]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs4.patch
- up to 5.1.4
[packages/kernel.git] / kernel-aufs4.patch
CommitLineData
2121bcd9 1SPDX-License-Identifier: GPL-2.0
cd7a4cd9 2aufs4.x-rcN kbuild patch
7f207e10
AM
3
4diff --git a/fs/Kconfig b/fs/Kconfig
ba1aed25 5index ac474a61be37..284cee954591 100644
7f207e10
AM
6--- a/fs/Kconfig
7+++ b/fs/Kconfig
eca801bf 8@@ -255,5 +255,6 @@ source "fs/pstore/Kconfig"
5527c038 9 source "fs/sysv/Kconfig"
7e9cd9fe 10 source "fs/ufs/Kconfig"
7f207e10
AM
11+source "fs/aufs/Kconfig"
12
13 endif # MISC_FILESYSTEMS
14
15diff --git a/fs/Makefile b/fs/Makefile
ba1aed25 16index 293733f61594..12d19d0de07a 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
be118d29 19@@ -128,3 +128,4 @@ obj-y += exofs/ # Multiple modules
7f207e10 20 obj-$(CONFIG_CEPH_FS) += ceph/
bf0370f2 21 obj-$(CONFIG_PSTORE) += pstore/
c06a8ce3 22 obj-$(CONFIG_EFIVAR_FS) += efivarfs/
86dc4139 23+obj-$(CONFIG_AUFS_FS) += aufs/
2121bcd9 24SPDX-License-Identifier: GPL-2.0
cd7a4cd9 25aufs4.x-rcN base patch
7f207e10 26
c1595e42 27diff --git a/MAINTAINERS b/MAINTAINERS
eca801bf 28index dce5c099f43c..d10f05c88860 100644
c1595e42
JR
29--- a/MAINTAINERS
30+++ b/MAINTAINERS
eca801bf 31@@ -2635,6 +2635,19 @@ F: include/linux/audit.h
c1595e42
JR
32 F: include/uapi/linux/audit.h
33 F: kernel/audit*
34
35+AUFS (advanced multi layered unification filesystem) FILESYSTEM
36+M: "J. R. Okajima" <hooanon05g@gmail.com>
c1595e42 37+L: aufs-users@lists.sourceforge.net (members only)
eca801bf 38+L: linux-unionfs@vger.kernel.org
c1595e42 39+W: http://aufs.sourceforge.net
5527c038 40+T: git://github.com/sfjro/aufs4-linux.git
c1595e42
JR
41+S: Supported
42+F: Documentation/filesystems/aufs/
43+F: Documentation/ABI/testing/debugfs-aufs
44+F: Documentation/ABI/testing/sysfs-aufs
45+F: fs/aufs/
46+F: include/uapi/linux/aufs_type.h
47+
48 AUXILIARY DISPLAY DRIVERS
49 M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
cd7a4cd9 50 S: Maintained
392086de 51diff --git a/drivers/block/loop.c b/drivers/block/loop.c
ba1aed25 52index cf5538942834..a271e17e4b10 100644
392086de
AM
53--- a/drivers/block/loop.c
54+++ b/drivers/block/loop.c
9f237c51 55@@ -738,6 +738,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
cd7a4cd9 56 return error;
392086de
AM
57 }
58
59+/*
60+ * for AUFS
61+ * no get/put for file.
62+ */
63+struct file *loop_backing_file(struct super_block *sb)
64+{
65+ struct file *ret;
66+ struct loop_device *l;
67+
68+ ret = NULL;
69+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
70+ l = sb->s_bdev->bd_disk->private_data;
71+ ret = l->lo_backing_file;
72+ }
73+ return ret;
74+}
febd17d6 75+EXPORT_SYMBOL_GPL(loop_backing_file);
392086de
AM
76+
77 /* loop sysfs attributes */
78
79 static ssize_t loop_attr_show(struct device *dev, char *page,
c1595e42 80diff --git a/fs/dcache.c b/fs/dcache.c
ba1aed25 81index aac41adf4743..fc18967c2522 100644
c1595e42
JR
82--- a/fs/dcache.c
83+++ b/fs/dcache.c
ba1aed25 84@@ -1247,7 +1247,7 @@ enum d_walk_ret {
c1595e42 85 *
cd7a4cd9 86 * The @enter() callbacks are called with d_lock held.
c1595e42
JR
87 */
88-static void d_walk(struct dentry *parent, void *data,
89+void d_walk(struct dentry *parent, void *data,
cd7a4cd9 90 enum d_walk_ret (*enter)(void *, struct dentry *))
c1595e42 91 {
cd7a4cd9 92 struct dentry *this_parent;
febd17d6 93diff --git a/fs/fcntl.c b/fs/fcntl.c
ba1aed25 94index 083185174c6d..78234ee16784 100644
febd17d6
JR
95--- a/fs/fcntl.c
96+++ b/fs/fcntl.c
2121bcd9 97@@ -32,7 +32,7 @@
febd17d6
JR
98
99 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
100
101-static int setfl(int fd, struct file * filp, unsigned long arg)
102+int setfl(int fd, struct file * filp, unsigned long arg)
103 {
104 struct inode * inode = file_inode(filp);
105 int error = 0;
2121bcd9 106@@ -63,6 +63,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
febd17d6
JR
107
108 if (filp->f_op->check_flags)
109 error = filp->f_op->check_flags(arg);
110+ if (!error && filp->f_op->setfl)
111+ error = filp->f_op->setfl(filp, arg);
112 if (error)
113 return error;
114
5afbbe0d 115diff --git a/fs/inode.c b/fs/inode.c
eca801bf 116index 73432e64f874..4a1756b8b4bd 100644
5afbbe0d
AM
117--- a/fs/inode.c
118+++ b/fs/inode.c
eca801bf 119@@ -1657,7 +1657,7 @@ EXPORT_SYMBOL(generic_update_time);
5afbbe0d
AM
120 * This does the actual work of updating an inodes time or version. Must have
121 * had called mnt_want_write() before calling this.
122 */
cd7a4cd9
AM
123-static int update_time(struct inode *inode, struct timespec64 *time, int flags)
124+int update_time(struct inode *inode, struct timespec64 *time, int flags)
5afbbe0d 125 {
cd7a4cd9 126 int (*update_time)(struct inode *, struct timespec64 *, int);
5afbbe0d 127
8b6a4947 128diff --git a/fs/namespace.c b/fs/namespace.c
eca801bf 129index 678ef175d63a..9b6a3d0f87a1 100644
8b6a4947
AM
130--- a/fs/namespace.c
131+++ b/fs/namespace.c
ba1aed25 132@@ -768,6 +768,12 @@ static inline int check_mnt(struct mount *mnt)
8b6a4947
AM
133 return mnt->mnt_ns == current->nsproxy->mnt_ns;
134 }
135
136+/* for aufs, CONFIG_AUFS_BR_FUSE */
137+int is_current_mnt_ns(struct vfsmount *mnt)
138+{
139+ return check_mnt(real_mount(mnt));
140+}
141+
142 /*
143 * vfsmount lock must be held for write
144 */
5527c038 145diff --git a/fs/read_write.c b/fs/read_write.c
ba1aed25 146index ff3c5e6f87cf..5c18a9e51f37 100644
5527c038
JR
147--- a/fs/read_write.c
148+++ b/fs/read_write.c
b00004a5 149@@ -489,6 +489,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
8b6a4947 150 return -EINVAL;
5527c038 151 }
5527c038
JR
152
153+vfs_readf_t vfs_readf(struct file *file)
154+{
155+ const struct file_operations *fop = file->f_op;
156+
157+ if (fop->read)
158+ return fop->read;
159+ if (fop->read_iter)
160+ return new_sync_read;
161+ return ERR_PTR(-ENOSYS);
162+}
163+
164+vfs_writef_t vfs_writef(struct file *file)
165+{
166+ const struct file_operations *fop = file->f_op;
167+
168+ if (fop->write)
169+ return fop->write;
170+ if (fop->write_iter)
171+ return new_sync_write;
172+ return ERR_PTR(-ENOSYS);
173+}
174+
8b6a4947 175 ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
5527c038
JR
176 {
177 mm_segment_t old_fs;
7f207e10 178diff --git a/fs/splice.c b/fs/splice.c
ba1aed25 179index de2ede048473..5dcf77b8e1b2 100644
7f207e10
AM
180--- a/fs/splice.c
181+++ b/fs/splice.c
9f237c51 182@@ -837,8 +837,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
183 /*
184 * Attempt to initiate a splice from pipe to file.
185 */
186-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
187- loff_t *ppos, size_t len, unsigned int flags)
188+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
189+ loff_t *ppos, size_t len, unsigned int flags)
190 {
191 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
192 loff_t *, size_t, unsigned int);
9f237c51 193@@ -854,9 +854,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
194 /*
195 * Attempt to initiate a splice from a file to a pipe.
196 */
197-static long do_splice_to(struct file *in, loff_t *ppos,
198- struct pipe_inode_info *pipe, size_t len,
199- unsigned int flags)
200+long do_splice_to(struct file *in, loff_t *ppos,
201+ struct pipe_inode_info *pipe, size_t len,
202+ unsigned int flags)
203 {
204 ssize_t (*splice_read)(struct file *, loff_t *,
205 struct pipe_inode_info *, size_t, unsigned int);
a2654f78 206diff --git a/fs/sync.c b/fs/sync.c
ba1aed25 207index b54e0541ad89..28607828e96f 100644
a2654f78
AM
208--- a/fs/sync.c
209+++ b/fs/sync.c
2121bcd9 210@@ -28,7 +28,7 @@
a2654f78
AM
211 * wait == 1 case since in that case write_inode() functions do
212 * sync_dirty_buffer() and thus effectively write one block at a time.
213 */
214-static int __sync_filesystem(struct super_block *sb, int wait)
215+int __sync_filesystem(struct super_block *sb, int wait)
216 {
217 if (wait)
218 sync_inodes_sb(sb);
5527c038 219diff --git a/include/linux/fs.h b/include/linux/fs.h
ba1aed25 220index 29d8e2cfed0e..5db265e7d35a 100644
5527c038
JR
221--- a/include/linux/fs.h
222+++ b/include/linux/fs.h
ba1aed25 223@@ -1310,6 +1310,7 @@ extern void fasync_free(struct fasync_struct *);
febd17d6
JR
224 /* can be called from interrupts */
225 extern void kill_fasync(struct fasync_struct **, int, int);
226
227+extern int setfl(int fd, struct file * filp, unsigned long arg);
228 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
3c1bdaff 229 extern int f_setown(struct file *filp, unsigned long arg, int force);
febd17d6 230 extern void f_delown(struct file *filp);
ba1aed25 231@@ -1803,6 +1804,7 @@ struct file_operations {
febd17d6
JR
232 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
233 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
234 int (*check_flags)(int);
235+ int (*setfl)(struct file *, unsigned long);
236 int (*flock) (struct file *, int, struct file_lock *);
237 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
238 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
ba1aed25 239@@ -1873,6 +1875,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
5527c038
JR
240 struct iovec *fast_pointer,
241 struct iovec **ret_pointer);
242
243+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *);
244+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t,
245+ loff_t *);
246+vfs_readf_t vfs_readf(struct file *file);
247+vfs_writef_t vfs_writef(struct file *file);
248+
249 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
5527c038 250 extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
8b6a4947 251 extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
ba1aed25 252@@ -2298,6 +2306,7 @@ extern int current_umask(void);
5afbbe0d
AM
253 extern void ihold(struct inode * inode);
254 extern void iput(struct inode *);
cd7a4cd9
AM
255 extern int generic_update_time(struct inode *, struct timespec64 *, int);
256+extern int update_time(struct inode *, struct timespec64 *, int);
5afbbe0d
AM
257
258 /* /sys/fs */
259 extern struct kobject *fs_kobj;
ba1aed25 260@@ -2585,6 +2594,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb)
a2654f78
AM
261 return false;
262 }
263 #endif
264+extern int __sync_filesystem(struct super_block *, int);
265 extern int sync_filesystem(struct super_block *);
266 extern const struct file_operations def_blk_fops;
267 extern const struct file_operations def_chr_fops;
8b6a4947 268diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
ba1aed25 269index c5335df2372f..4e48a5059536 100644
8b6a4947
AM
270--- a/include/linux/lockdep.h
271+++ b/include/linux/lockdep.h
ba1aed25 272@@ -306,6 +306,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock,
8b6a4947
AM
273 return lock->key == key;
274 }
275
276+struct lock_class *lockdep_hlock_class(struct held_lock *hlock);
277+
278 /*
279 * Acquire a lock.
280 *
ba1aed25 281@@ -432,6 +434,7 @@ struct lockdep_map { };
8b6a4947
AM
282
283 #define lockdep_depth(tsk) (0)
284
285+#define lockdep_is_held(lock) (1)
286 #define lockdep_is_held_type(l, r) (1)
287
288 #define lockdep_assert_held(l) do { (void)(l); } while (0)
289diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
ba1aed25 290index 35942084cd40..24f5fd1a789d 100644
8b6a4947
AM
291--- a/include/linux/mnt_namespace.h
292+++ b/include/linux/mnt_namespace.h
2121bcd9 293@@ -6,11 +6,14 @@
8b6a4947
AM
294 struct mnt_namespace;
295 struct fs_struct;
296 struct user_namespace;
297+struct vfsmount;
298
299 extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *,
300 struct user_namespace *, struct fs_struct *);
301 extern void put_mnt_ns(struct mnt_namespace *ns);
302
303+extern int is_current_mnt_ns(struct vfsmount *mnt);
304+
305 extern const struct file_operations proc_mounts_operations;
306 extern const struct file_operations proc_mountinfo_operations;
307 extern const struct file_operations proc_mountstats_operations;
1e00d052 308diff --git a/include/linux/splice.h b/include/linux/splice.h
ba1aed25 309index 74b4911ac16d..19789fbea567 100644
1e00d052
AM
310--- a/include/linux/splice.h
311+++ b/include/linux/splice.h
2121bcd9 312@@ -87,4 +87,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
313
314 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
106341ce 315 extern const struct pipe_buf_operations default_pipe_buf_ops;
1e00d052
AM
316+
317+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
318+ loff_t *ppos, size_t len, unsigned int flags);
319+extern long do_splice_to(struct file *in, loff_t *ppos,
320+ struct pipe_inode_info *pipe, size_t len,
321+ unsigned int flags);
322 #endif
8b6a4947 323diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
ba1aed25 324index 95932333a48b..516ab7da26fb 100644
8b6a4947
AM
325--- a/kernel/locking/lockdep.c
326+++ b/kernel/locking/lockdep.c
ba1aed25
AM
327@@ -143,7 +143,7 @@ static
328 #endif
9f237c51 329 struct lock_class lock_classes[MAX_LOCKDEP_KEYS];
8b6a4947
AM
330
331-static inline struct lock_class *hlock_class(struct held_lock *hlock)
332+inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
333 {
334 if (!hlock->class_idx) {
335 /*
ba1aed25 336@@ -154,6 +154,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
8b6a4947
AM
337 }
338 return lock_classes + hlock->class_idx - 1;
339 }
340+#define hlock_class(hlock) lockdep_hlock_class(hlock)
341
342 #ifdef CONFIG_LOCK_STAT
343 static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats);
2121bcd9 344SPDX-License-Identifier: GPL-2.0
cd7a4cd9 345aufs4.x-rcN mmap patch
fb47a38f 346
c1595e42 347diff --git a/fs/proc/base.c b/fs/proc/base.c
eca801bf 348index f5ed9512d193..e8f8e59d93bb 100644
c1595e42
JR
349--- a/fs/proc/base.c
350+++ b/fs/proc/base.c
eca801bf 351@@ -2014,7 +2014,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
c1595e42
JR
352 down_read(&mm->mmap_sem);
353 vma = find_exact_vma(mm, vm_start, vm_end);
354 if (vma && vma->vm_file) {
355- *path = vma->vm_file->f_path;
356+ *path = vma_pr_or_file(vma)->f_path;
357 path_get(path);
358 rc = 0;
359 }
fb47a38f 360diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
ba1aed25 361index 3b63be64e436..fb9913bf3d10 100644
fb47a38f
JR
362--- a/fs/proc/nommu.c
363+++ b/fs/proc/nommu.c
076b876e 364@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
fb47a38f
JR
365 file = region->vm_file;
366
367 if (file) {
368- struct inode *inode = file_inode(region->vm_file);
369+ struct inode *inode;
076b876e 370+
fb47a38f
JR
371+ file = vmr_pr_or_file(region);
372+ inode = file_inode(file);
373 dev = inode->i_sb->s_dev;
374 ino = inode->i_ino;
375 }
376diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
eca801bf 377index 85b0ef890b28..0f7fb8138160 100644
fb47a38f
JR
378--- a/fs/proc/task_mmu.c
379+++ b/fs/proc/task_mmu.c
acd2b654 380@@ -305,7 +305,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
fb47a38f
JR
381 const char *name = NULL;
382
383 if (file) {
384- struct inode *inode = file_inode(vma->vm_file);
385+ struct inode *inode;
076b876e 386+
fb47a38f
JR
387+ file = vma_pr_or_file(vma);
388+ inode = file_inode(file);
389 dev = inode->i_sb->s_dev;
390 ino = inode->i_ino;
391 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
eca801bf 392@@ -1740,7 +1743,7 @@ static int show_numa_map(struct seq_file *m, void *v)
076b876e
AM
393 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
394 struct vm_area_struct *vma = v;
395 struct numa_maps *md = &numa_priv->md;
396- struct file *file = vma->vm_file;
397+ struct file *file = vma_pr_or_file(vma);
076b876e 398 struct mm_struct *mm = vma->vm_mm;
7e9cd9fe
AM
399 struct mm_walk walk = {
400 .hugetlb_entry = gather_hugetlb_stats,
fb47a38f 401diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
ba1aed25 402index 0b63d68dedb2..400d1c594ceb 100644
fb47a38f
JR
403--- a/fs/proc/task_nommu.c
404+++ b/fs/proc/task_nommu.c
acd2b654 405@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
fb47a38f
JR
406 file = vma->vm_file;
407
408 if (file) {
409- struct inode *inode = file_inode(vma->vm_file);
410+ struct inode *inode;
076b876e 411+
b912730e 412+ file = vma_pr_or_file(vma);
fb47a38f
JR
413+ inode = file_inode(file);
414 dev = inode->i_sb->s_dev;
415 ino = inode->i_ino;
416 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
417diff --git a/include/linux/mm.h b/include/linux/mm.h
ba1aed25 418index 80bb6408fe73..59a1ea611ba7 100644
fb47a38f
JR
419--- a/include/linux/mm.h
420+++ b/include/linux/mm.h
ba1aed25 421@@ -1518,6 +1518,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
a3232e84 422 unmap_mapping_range(mapping, holebegin, holelen, 0);
fb47a38f 423 }
fb47a38f 424
076b876e
AM
425+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
426+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
f2c43d5f 427+ int);
076b876e
AM
428+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
429+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
fb47a38f 430+
f2c43d5f
AM
431+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
432+ __LINE__)
433+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
434+ __LINE__)
435+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
436+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
b912730e
AM
437+
438+#ifndef CONFIG_MMU
076b876e
AM
439+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
440+extern void vmr_do_fput(struct vm_region *, const char[], int);
441+
f2c43d5f
AM
442+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
443+ __LINE__)
444+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
b912730e 445+#endif /* !CONFIG_MMU */
fb47a38f 446+
a3232e84
JR
447 extern int access_process_vm(struct task_struct *tsk, unsigned long addr,
448 void *buf, int len, unsigned int gup_flags);
fb47a38f 449 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
fb47a38f 450diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
ba1aed25 451index 2c471a2c43fa..c6e7aa6996ff 100644
fb47a38f
JR
452--- a/include/linux/mm_types.h
453+++ b/include/linux/mm_types.h
ba1aed25 454@@ -244,6 +244,7 @@ struct vm_region {
fb47a38f
JR
455 unsigned long vm_top; /* region allocated to here */
456 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
457 struct file *vm_file; /* the backing file or NULL */
458+ struct file *vm_prfile; /* the virtual backing file or NULL */
459
460 int vm_usage; /* region usage count (access under nommu_region_sem) */
461 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
ba1aed25 462@@ -318,6 +319,7 @@ struct vm_area_struct {
fb47a38f 463 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
5afbbe0d 464 units */
fb47a38f
JR
465 struct file * vm_file; /* File we map to (can be NULL). */
466+ struct file *vm_prfile; /* shadow of vm_file */
467 void * vm_private_data; /* was vm_pte (shared mem) */
468
8b6a4947 469 atomic_long_t swap_readahead_info;
fb47a38f 470diff --git a/kernel/fork.c b/kernel/fork.c
ba1aed25 471index b69248e6f0e0..099b89978dd3 100644
fb47a38f
JR
472--- a/kernel/fork.c
473+++ b/kernel/fork.c
ba1aed25 474@@ -547,7 +547,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
fb47a38f
JR
475 struct inode *inode = file_inode(file);
476 struct address_space *mapping = file->f_mapping;
477
478- get_file(file);
479+ vma_get_file(tmp);
480 if (tmp->vm_flags & VM_DENYWRITE)
481 atomic_dec(&inode->i_writecount);
2000de60 482 i_mmap_lock_write(mapping);
076b876e 483diff --git a/mm/Makefile b/mm/Makefile
ba1aed25 484index d210cc9d6f80..e77e80ce7298 100644
076b876e
AM
485--- a/mm/Makefile
486+++ b/mm/Makefile
acd2b654 487@@ -39,7 +39,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \
076b876e 488 mm_init.o mmu_context.o percpu.o slab_common.o \
b00004a5 489 compaction.o vmacache.o \
076b876e 490 interval_tree.o list_lru.o workingset.o \
7e9cd9fe
AM
491- debug.o $(mmu-y)
492+ prfile.o debug.o $(mmu-y)
076b876e
AM
493
494 obj-y += init-mm.o
9f237c51 495 obj-y += memblock.o
fb47a38f 496diff --git a/mm/filemap.c b/mm/filemap.c
ba1aed25 497index 9f5e323e883e..90db684a7cf4 100644
fb47a38f
JR
498--- a/mm/filemap.c
499+++ b/mm/filemap.c
ba1aed25 500@@ -2677,7 +2677,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf)
cd7a4cd9 501 vm_fault_t ret = VM_FAULT_LOCKED;
fb47a38f
JR
502
503 sb_start_pagefault(inode->i_sb);
521ced18
JR
504- file_update_time(vmf->vma->vm_file);
505+ vma_file_update_time(vmf->vma);
fb47a38f
JR
506 lock_page(page);
507 if (page->mapping != inode->i_mapping) {
508 unlock_page(page);
fb47a38f 509diff --git a/mm/mmap.c b/mm/mmap.c
eca801bf 510index fc1809b1bed6..8f62e47a60ea 100644
fb47a38f
JR
511--- a/mm/mmap.c
512+++ b/mm/mmap.c
c4adf169 513@@ -180,7 +180,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
fb47a38f
JR
514 if (vma->vm_ops && vma->vm_ops->close)
515 vma->vm_ops->close(vma);
516 if (vma->vm_file)
517- fput(vma->vm_file);
518+ vma_fput(vma);
519 mpol_put(vma_policy(vma));
cd7a4cd9 520 vm_area_free(vma);
fb47a38f 521 return next;
9f237c51 522@@ -929,7 +929,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
fb47a38f
JR
523 if (remove_next) {
524 if (file) {
525 uprobe_munmap(next, next->vm_start, next->vm_end);
526- fput(file);
527+ vma_fput(vma);
528 }
529 if (next->anon_vma)
530 anon_vma_merge(vma, next);
9f237c51 531@@ -1845,8 +1845,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
35939ee7
JR
532 return addr;
533
fb47a38f 534 unmap_and_free_vma:
fb47a38f
JR
535+ vma_fput(vma);
536 vma->vm_file = NULL;
537- fput(file);
538
539 /* Undo any partial mapping done by a device driver. */
540 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
eca801bf 541@@ -2675,7 +2675,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
542 goto out_free_mpol;
543
544 if (new->vm_file)
545- get_file(new->vm_file);
546+ vma_get_file(new);
547
548 if (new->vm_ops && new->vm_ops->open)
549 new->vm_ops->open(new);
eca801bf 550@@ -2694,7 +2694,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
551 if (new->vm_ops && new->vm_ops->close)
552 new->vm_ops->close(new);
553 if (new->vm_file)
554- fput(new->vm_file);
555+ vma_fput(new);
556 unlink_anon_vmas(new);
557 out_free_mpol:
558 mpol_put(vma_policy(new));
eca801bf 559@@ -2884,7 +2884,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
7e9cd9fe
AM
560 struct vm_area_struct *vma;
561 unsigned long populate = 0;
562 unsigned long ret = -EINVAL;
563- struct file *file;
5afbbe0d 564+ struct file *file, *prfile;
7e9cd9fe 565
cd7a4cd9 566 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n",
5afbbe0d 567 current->comm, current->pid);
eca801bf 568@@ -2959,10 +2959,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
febd17d6 569 }
7e9cd9fe
AM
570 }
571
572- file = get_file(vma->vm_file);
573+ vma_get_file(vma);
5afbbe0d
AM
574+ file = vma->vm_file;
575+ prfile = vma->vm_prfile;
7e9cd9fe 576 ret = do_mmap_pgoff(vma->vm_file, start, size,
521ced18 577 prot, flags, pgoff, &populate, NULL);
5afbbe0d
AM
578+ if (!IS_ERR_VALUE(ret) && file && prfile) {
579+ struct vm_area_struct *new_vma;
580+
581+ new_vma = find_vma(mm, ret);
582+ if (!new_vma->vm_prfile)
583+ new_vma->vm_prfile = prfile;
584+ if (new_vma != vma)
585+ get_file(prfile);
586+ }
587+ /*
588+ * two fput()s instead of vma_fput(vma),
589+ * coz vma may not be available anymore.
590+ */
591 fput(file);
592+ if (prfile)
593+ fput(prfile);
7e9cd9fe
AM
594 out:
595 up_write(&mm->mmap_sem);
596 if (populate)
eca801bf 597@@ -3252,7 +3269,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
79b8bda9
AM
598 if (anon_vma_clone(new_vma, vma))
599 goto out_free_mempol;
600 if (new_vma->vm_file)
601- get_file(new_vma->vm_file);
602+ vma_get_file(new_vma);
603 if (new_vma->vm_ops && new_vma->vm_ops->open)
604 new_vma->vm_ops->open(new_vma);
605 vma_link(mm, new_vma, prev, rb_link, rb_parent);
fb47a38f 606diff --git a/mm/nommu.c b/mm/nommu.c
eca801bf 607index 749276beb109..c7957f06fbc4 100644
fb47a38f
JR
608--- a/mm/nommu.c
609+++ b/mm/nommu.c
acd2b654 610@@ -625,7 +625,7 @@ static void __put_nommu_region(struct vm_region *region)
fb47a38f
JR
611 up_write(&nommu_region_sem);
612
613 if (region->vm_file)
614- fput(region->vm_file);
615+ vmr_fput(region);
616
617 /* IO memory and memory shared directly out of the pagecache
618 * from ramfs/tmpfs mustn't be released here */
acd2b654 619@@ -763,7 +763,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
fb47a38f
JR
620 if (vma->vm_ops && vma->vm_ops->close)
621 vma->vm_ops->close(vma);
622 if (vma->vm_file)
623- fput(vma->vm_file);
624+ vma_fput(vma);
625 put_nommu_region(vma->vm_region);
cd7a4cd9 626 vm_area_free(vma);
fb47a38f 627 }
acd2b654 628@@ -1286,7 +1286,7 @@ unsigned long do_mmap(struct file *file,
fb47a38f
JR
629 goto error_just_free;
630 }
631 }
632- fput(region->vm_file);
633+ vmr_fput(region);
634 kmem_cache_free(vm_region_jar, region);
635 region = pregion;
636 result = start;
eca801bf 637@@ -1361,10 +1361,10 @@ unsigned long do_mmap(struct file *file,
fb47a38f
JR
638 up_write(&nommu_region_sem);
639 error:
640 if (region->vm_file)
641- fput(region->vm_file);
642+ vmr_fput(region);
643 kmem_cache_free(vm_region_jar, region);
644 if (vma->vm_file)
eca801bf
AM
645- fput(vma->vm_file);
646+ vma_fput(vma);
647 vm_area_free(vma);
648 return ret;
649
076b876e
AM
650diff --git a/mm/prfile.c b/mm/prfile.c
651new file mode 100644
ba1aed25 652index 000000000000..024cdcfae1b1
076b876e
AM
653--- /dev/null
654+++ b/mm/prfile.c
2121bcd9 655@@ -0,0 +1,86 @@
cd7a4cd9 656+// SPDX-License-Identifier: GPL-2.0
076b876e 657+/*
1c60b727
AM
658+ * Mainly for aufs which mmap(2) different file and wants to print different
659+ * path in /proc/PID/maps.
076b876e
AM
660+ * Call these functions via macros defined in linux/mm.h.
661+ *
662+ * See Documentation/filesystems/aufs/design/06mmap.txt
663+ *
ba1aed25 664+ * Copyright (c) 2014-2019 Junjro R. Okajima
076b876e
AM
665+ * Copyright (c) 2014 Ian Campbell
666+ */
667+
668+#include <linux/mm.h>
669+#include <linux/file.h>
670+#include <linux/fs.h>
671+
672+/* #define PRFILE_TRACE */
673+static inline void prfile_trace(struct file *f, struct file *pr,
674+ const char func[], int line, const char func2[])
675+{
676+#ifdef PRFILE_TRACE
677+ if (pr)
1c60b727 678+ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f);
076b876e
AM
679+#endif
680+}
681+
076b876e
AM
682+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
683+ int line)
684+{
685+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
686+
687+ prfile_trace(f, pr, func, line, __func__);
688+ file_update_time(f);
689+ if (f && pr)
690+ file_update_time(pr);
691+}
692+
693+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
694+ int line)
695+{
696+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
697+
698+ prfile_trace(f, pr, func, line, __func__);
699+ return (f && pr) ? pr : f;
700+}
701+
702+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
703+{
704+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
705+
706+ prfile_trace(f, pr, func, line, __func__);
707+ get_file(f);
708+ if (f && pr)
709+ get_file(pr);
710+}
711+
712+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
713+{
714+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
715+
716+ prfile_trace(f, pr, func, line, __func__);
717+ fput(f);
718+ if (f && pr)
719+ fput(pr);
720+}
b912730e
AM
721+
722+#ifndef CONFIG_MMU
076b876e
AM
723+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
724+ int line)
725+{
726+ struct file *f = region->vm_file, *pr = region->vm_prfile;
727+
728+ prfile_trace(f, pr, func, line, __func__);
729+ return (f && pr) ? pr : f;
730+}
731+
732+void vmr_do_fput(struct vm_region *region, const char func[], int line)
733+{
734+ struct file *f = region->vm_file, *pr = region->vm_prfile;
735+
736+ prfile_trace(f, pr, func, line, __func__);
737+ fput(f);
738+ if (f && pr)
739+ fput(pr);
740+}
b912730e 741+#endif /* !CONFIG_MMU */
2121bcd9 742SPDX-License-Identifier: GPL-2.0
cd7a4cd9 743aufs4.x-rcN standalone patch
7f207e10 744
c1595e42 745diff --git a/fs/dcache.c b/fs/dcache.c
ba1aed25 746index fc18967c2522..50eb587c1253 100644
c1595e42
JR
747--- a/fs/dcache.c
748+++ b/fs/dcache.c
ba1aed25 749@@ -1352,6 +1352,7 @@ void d_walk(struct dentry *parent, void *data,
c1595e42
JR
750 seq = 1;
751 goto again;
752 }
febd17d6 753+EXPORT_SYMBOL_GPL(d_walk);
c1595e42 754
a2654f78
AM
755 struct check_mount {
756 struct vfsmount *mnt;
ba1aed25 757@@ -2845,6 +2846,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2)
f2c43d5f
AM
758
759 write_sequnlock(&rename_lock);
760 }
761+EXPORT_SYMBOL_GPL(d_exchange);
762
763 /**
764 * d_ancestor - search for an ancestor
79b8bda9 765diff --git a/fs/exec.c b/fs/exec.c
ba1aed25 766index fb72d36f7823..7ce68004cbf8 100644
79b8bda9
AM
767--- a/fs/exec.c
768+++ b/fs/exec.c
521ced18 769@@ -109,6 +109,7 @@ bool path_noexec(const struct path *path)
79b8bda9
AM
770 return (path->mnt->mnt_flags & MNT_NOEXEC) ||
771 (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
772 }
febd17d6 773+EXPORT_SYMBOL_GPL(path_noexec);
79b8bda9
AM
774
775 #ifdef CONFIG_USELIB
776 /*
febd17d6 777diff --git a/fs/fcntl.c b/fs/fcntl.c
ba1aed25 778index 78234ee16784..2072f690b121 100644
febd17d6
JR
779--- a/fs/fcntl.c
780+++ b/fs/fcntl.c
2121bcd9 781@@ -85,6 +85,7 @@ int setfl(int fd, struct file * filp, unsigned long arg)
febd17d6
JR
782 out:
783 return error;
784 }
785+EXPORT_SYMBOL_GPL(setfl);
786
787 static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
788 int force)
b912730e 789diff --git a/fs/file_table.c b/fs/file_table.c
ba1aed25 790index 5679e7fcb6b0..961eec3df1eb 100644
b912730e
AM
791--- a/fs/file_table.c
792+++ b/fs/file_table.c
acd2b654 793@@ -161,6 +161,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred)
b912730e
AM
794 }
795 return ERR_PTR(-ENFILE);
796 }
acd2b654 797+EXPORT_SYMBOL_GPL(alloc_empty_file);
b912730e 798
acd2b654
AM
799 /*
800 * Variant of alloc_empty_file() that doesn't check and modify nr_files.
801@@ -323,6 +324,7 @@ void flush_delayed_fput(void)
8cdd5066
JR
802 {
803 delayed_fput(NULL);
804 }
febd17d6 805+EXPORT_SYMBOL_GPL(flush_delayed_fput);
8cdd5066
JR
806
807 static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
808
acd2b654 809@@ -365,6 +367,7 @@ void __fput_sync(struct file *file)
8cdd5066
JR
810 }
811
812 EXPORT_SYMBOL(fput);
febd17d6 813+EXPORT_SYMBOL_GPL(__fput_sync);
8cdd5066 814
79b8bda9 815 void __init files_init(void)
8b6a4947 816 {
5afbbe0d 817diff --git a/fs/inode.c b/fs/inode.c
eca801bf 818index 4a1756b8b4bd..6e51d5f9b9f3 100644
5afbbe0d
AM
819--- a/fs/inode.c
820+++ b/fs/inode.c
eca801bf 821@@ -1666,6 +1666,7 @@ int update_time(struct inode *inode, struct timespec64 *time, int flags)
5afbbe0d
AM
822
823 return update_time(inode, time, flags);
824 }
825+EXPORT_SYMBOL_GPL(update_time);
826
827 /**
828 * touch_atime - update the access time
7f207e10 829diff --git a/fs/namespace.c b/fs/namespace.c
eca801bf 830index 9b6a3d0f87a1..8c4d3d56f2df 100644
7f207e10
AM
831--- a/fs/namespace.c
832+++ b/fs/namespace.c
ba1aed25 833@@ -434,6 +434,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
834 mnt_dec_writers(real_mount(mnt));
835 preempt_enable();
836 }
837+EXPORT_SYMBOL_GPL(__mnt_drop_write);
838
839 /**
840 * mnt_drop_write - give up write access to a mount
ba1aed25 841@@ -773,6 +774,7 @@ int is_current_mnt_ns(struct vfsmount *mnt)
8b6a4947
AM
842 {
843 return check_mnt(real_mount(mnt));
844 }
845+EXPORT_SYMBOL_GPL(is_current_mnt_ns);
846
847 /*
848 * vfsmount lock must be held for write
ba1aed25 849@@ -1842,6 +1844,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
850 }
851 return 0;
852 }
febd17d6 853+EXPORT_SYMBOL_GPL(iterate_mounts);
7f207e10 854
7eafdf33 855 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
856 {
857diff --git a/fs/notify/group.c b/fs/notify/group.c
ba1aed25 858index c03b83662876..817f22c6e191 100644
7f207e10
AM
859--- a/fs/notify/group.c
860+++ b/fs/notify/group.c
acd2b654 861@@ -23,6 +23,7 @@
7f207e10
AM
862 #include <linux/rculist.h>
863 #include <linux/wait.h>
acd2b654 864 #include <linux/memcontrol.h>
7f207e10
AM
865+#include <linux/module.h>
866
867 #include <linux/fsnotify_backend.h>
868 #include "fsnotify.h"
acd2b654 869@@ -112,6 +113,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
1716fcea 870 {
2121bcd9 871 refcount_inc(&group->refcnt);
1716fcea 872 }
febd17d6 873+EXPORT_SYMBOL_GPL(fsnotify_get_group);
1716fcea
AM
874
875 /*
876 * Drop a reference to a group. Free it if it's through.
acd2b654 877@@ -121,6 +123,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
2121bcd9 878 if (refcount_dec_and_test(&group->refcnt))
1716fcea 879 fsnotify_final_destroy_group(group);
7f207e10 880 }
febd17d6 881+EXPORT_SYMBOL_GPL(fsnotify_put_group);
7f207e10
AM
882
883 /*
884 * Create a new fsnotify_group and hold a reference for the group returned.
acd2b654 885@@ -150,6 +153,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
886
887 return group;
888 }
febd17d6 889+EXPORT_SYMBOL_GPL(fsnotify_alloc_group);
1716fcea
AM
890
891 int fsnotify_fasync(int fd, struct file *file, int on)
892 {
7f207e10 893diff --git a/fs/notify/mark.c b/fs/notify/mark.c
ba1aed25 894index d2dd16cb5989..cf709b7d611a 100644
7f207e10
AM
895--- a/fs/notify/mark.c
896+++ b/fs/notify/mark.c
9f237c51 897@@ -289,6 +289,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
cd7a4cd9
AM
898 queue_delayed_work(system_unbound_wq, &reaper_work,
899 FSNOTIFY_REAPER_DELAY);
7f207e10 900 }
febd17d6 901+EXPORT_SYMBOL_GPL(fsnotify_put_mark);
7f207e10 902
cd7a4cd9
AM
903 /*
904 * Get mark reference when we found the mark via lockless traversal of object
9f237c51 905@@ -443,6 +444,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea 906 mutex_unlock(&group->mark_mutex);
79b8bda9 907 fsnotify_free_mark(mark);
7f207e10 908 }
febd17d6 909+EXPORT_SYMBOL_GPL(fsnotify_destroy_mark);
7f207e10 910
ffa93bbd
AM
911 /*
912 * Sorting function for lists of fsnotify marks.
9f237c51 913@@ -658,6 +660,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp,
cd7a4cd9 914 mutex_unlock(&group->mark_mutex);
7f207e10
AM
915 return ret;
916 }
febd17d6 917+EXPORT_SYMBOL_GPL(fsnotify_add_mark);
7f207e10 918
cd7a4cd9
AM
919 /*
920 * Given a list of marks, find the mark associated with given group. If found
9f237c51 921@@ -781,6 +784,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
ffa93bbd
AM
922 fsnotify_get_group(group);
923 mark->group = group;
7f207e10 924 }
febd17d6 925+EXPORT_SYMBOL_GPL(fsnotify_init_mark);
7f207e10 926
5afbbe0d
AM
927 /*
928 * Destroy all marks in destroy_list, waits for SRCU period to finish before
7f207e10 929diff --git a/fs/open.c b/fs/open.c
ba1aed25 930index 0285ce7dbd51..cb81623a8b09 100644
7f207e10
AM
931--- a/fs/open.c
932+++ b/fs/open.c
c2c0f25c 933@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
febd17d6 934 inode_unlock(dentry->d_inode);
7f207e10
AM
935 return ret;
936 }
febd17d6 937+EXPORT_SYMBOL_GPL(do_truncate);
7f207e10 938
5afbbe0d 939 long vfs_truncate(const struct path *path, loff_t length)
7f207e10 940 {
5527c038 941diff --git a/fs/read_write.c b/fs/read_write.c
ba1aed25 942index 5c18a9e51f37..542e59cd8d27 100644
5527c038
JR
943--- a/fs/read_write.c
944+++ b/fs/read_write.c
b00004a5 945@@ -459,6 +459,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
8b6a4947
AM
946
947 return ret;
948 }
949+EXPORT_SYMBOL_GPL(vfs_read);
950
951 static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
952 {
b00004a5 953@@ -499,6 +500,7 @@ vfs_readf_t vfs_readf(struct file *file)
5527c038
JR
954 return new_sync_read;
955 return ERR_PTR(-ENOSYS);
956 }
febd17d6 957+EXPORT_SYMBOL_GPL(vfs_readf);
5527c038
JR
958
959 vfs_writef_t vfs_writef(struct file *file)
960 {
b00004a5 961@@ -510,6 +512,7 @@ vfs_writef_t vfs_writef(struct file *file)
5527c038
JR
962 return new_sync_write;
963 return ERR_PTR(-ENOSYS);
964 }
febd17d6 965+EXPORT_SYMBOL_GPL(vfs_writef);
5527c038 966
8b6a4947
AM
967 ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
968 {
b00004a5 969@@ -579,6 +582,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
8b6a4947
AM
970
971 return ret;
972 }
973+EXPORT_SYMBOL_GPL(vfs_write);
974
975 static inline loff_t file_pos_read(struct file *file)
5527c038 976 {
7f207e10 977diff --git a/fs/splice.c b/fs/splice.c
ba1aed25 978index 5dcf77b8e1b2..63fe2652c67d 100644
7f207e10
AM
979--- a/fs/splice.c
980+++ b/fs/splice.c
9f237c51 981@@ -850,6 +850,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
392086de
AM
982
983 return splice_write(pipe, out, ppos, len, flags);
7f207e10 984 }
febd17d6 985+EXPORT_SYMBOL_GPL(do_splice_from);
7f207e10
AM
986
987 /*
988 * Attempt to initiate a splice from a file to a pipe.
9f237c51 989@@ -879,6 +880,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
990
991 return splice_read(in, ppos, pipe, len, flags);
992 }
febd17d6 993+EXPORT_SYMBOL_GPL(do_splice_to);
7f207e10
AM
994
995 /**
996 * splice_direct_to_actor - splices data directly between two non-pipes
a2654f78 997diff --git a/fs/sync.c b/fs/sync.c
ba1aed25 998index 28607828e96f..ffd7ea43831e 100644
a2654f78
AM
999--- a/fs/sync.c
1000+++ b/fs/sync.c
2121bcd9 1001@@ -39,6 +39,7 @@ int __sync_filesystem(struct super_block *sb, int wait)
a2654f78
AM
1002 sb->s_op->sync_fs(sb, wait);
1003 return __sync_blockdev(sb->s_bdev, wait);
1004 }
1005+EXPORT_SYMBOL_GPL(__sync_filesystem);
1006
1007 /*
1008 * Write out and wait upon all dirty data associated with this
c1595e42 1009diff --git a/fs/xattr.c b/fs/xattr.c
ba1aed25 1010index 0d6a6a4af861..7ce4701b7289 100644
c1595e42
JR
1011--- a/fs/xattr.c
1012+++ b/fs/xattr.c
acd2b654 1013@@ -295,6 +295,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
c1595e42
JR
1014 *xattr_value = value;
1015 return error;
1016 }
febd17d6 1017+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);
c1595e42 1018
febd17d6 1019 ssize_t
f2c43d5f 1020 __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
8b6a4947 1021diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
ba1aed25 1022index 516ab7da26fb..c4f72e461d28 100644
8b6a4947
AM
1023--- a/kernel/locking/lockdep.c
1024+++ b/kernel/locking/lockdep.c
ba1aed25 1025@@ -154,6 +154,7 @@ inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
8b6a4947
AM
1026 }
1027 return lock_classes + hlock->class_idx - 1;
1028 }
1029+EXPORT_SYMBOL_GPL(lockdep_hlock_class);
1030 #define hlock_class(hlock) lockdep_hlock_class(hlock)
1031
1032 #ifdef CONFIG_LOCK_STAT
8cdd5066 1033diff --git a/kernel/task_work.c b/kernel/task_work.c
ba1aed25 1034index 0fef395662a6..83fb1ecfc33d 100644
8cdd5066
JR
1035--- a/kernel/task_work.c
1036+++ b/kernel/task_work.c
2121bcd9 1037@@ -116,3 +116,4 @@ void task_work_run(void)
8cdd5066
JR
1038 } while (work);
1039 }
1040 }
febd17d6 1041+EXPORT_SYMBOL_GPL(task_work_run);
7f207e10 1042diff --git a/security/commoncap.c b/security/commoncap.c
ba1aed25 1043index 232db019f051..a402a5b72bf4 100644
7f207e10
AM
1044--- a/security/commoncap.c
1045+++ b/security/commoncap.c
ba1aed25 1046@@ -1332,12 +1332,14 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 1047 }
7f207e10
AM
1048 return ret;
1049 }
febd17d6 1050+EXPORT_SYMBOL_GPL(cap_mmap_addr);
0c3ec466
AM
1051
1052 int cap_mmap_file(struct file *file, unsigned long reqprot,
1053 unsigned long prot, unsigned long flags)
1054 {
1055 return 0;
1056 }
febd17d6 1057+EXPORT_SYMBOL_GPL(cap_mmap_file);
c2c0f25c
AM
1058
1059 #ifdef CONFIG_SECURITY
1060
7f207e10 1061diff --git a/security/device_cgroup.c b/security/device_cgroup.c
ba1aed25 1062index cd97929fac66..424fd230866d 100644
7f207e10
AM
1063--- a/security/device_cgroup.c
1064+++ b/security/device_cgroup.c
2121bcd9 1065@@ -8,6 +8,7 @@
f6c5ef8b
AM
1066 #include <linux/device_cgroup.h>
1067 #include <linux/cgroup.h>
1068 #include <linux/ctype.h>
1069+#include <linux/export.h>
1070 #include <linux/list.h>
1071 #include <linux/uaccess.h>
1072 #include <linux/seq_file.h>
2121bcd9 1073@@ -824,3 +825,4 @@ int __devcgroup_check_permission(short type, u32 major, u32 minor,
7f207e10 1074
2121bcd9
AM
1075 return 0;
1076 }
1077+EXPORT_SYMBOL_GPL(__devcgroup_check_permission);
7f207e10 1078diff --git a/security/security.c b/security/security.c
ba1aed25 1079index 55bc49027ba9..870eaa8ebedc 100644
7f207e10
AM
1080--- a/security/security.c
1081+++ b/security/security.c
ba1aed25 1082@@ -566,6 +566,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry)
7f207e10 1083 return 0;
c2c0f25c 1084 return call_int_hook(path_rmdir, 0, dir, dentry);
7f207e10 1085 }
febd17d6 1086+EXPORT_SYMBOL_GPL(security_path_rmdir);
7f207e10 1087
5afbbe0d 1088 int security_path_unlink(const struct path *dir, struct dentry *dentry)
7f207e10 1089 {
ba1aed25 1090@@ -582,6 +583,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry,
7f207e10 1091 return 0;
c2c0f25c 1092 return call_int_hook(path_symlink, 0, dir, dentry, old_name);
7f207e10 1093 }
febd17d6 1094+EXPORT_SYMBOL_GPL(security_path_symlink);
7f207e10 1095
5afbbe0d 1096 int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
7f207e10 1097 struct dentry *new_dentry)
ba1aed25 1098@@ -590,6 +592,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
7f207e10 1099 return 0;
c2c0f25c 1100 return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
7f207e10 1101 }
febd17d6 1102+EXPORT_SYMBOL_GPL(security_path_link);
7f207e10 1103
5afbbe0d
AM
1104 int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
1105 const struct path *new_dir, struct dentry *new_dentry,
ba1aed25 1106@@ -617,6 +620,7 @@ int security_path_truncate(const struct path *path)
7f207e10 1107 return 0;
c2c0f25c 1108 return call_int_hook(path_truncate, 0, path);
7f207e10 1109 }
febd17d6 1110+EXPORT_SYMBOL_GPL(security_path_truncate);
7f207e10 1111
5afbbe0d 1112 int security_path_chmod(const struct path *path, umode_t mode)
7eafdf33 1113 {
ba1aed25 1114@@ -624,6 +628,7 @@ int security_path_chmod(const struct path *path, umode_t mode)
7f207e10 1115 return 0;
c2c0f25c 1116 return call_int_hook(path_chmod, 0, path, mode);
7f207e10 1117 }
febd17d6 1118+EXPORT_SYMBOL_GPL(security_path_chmod);
7f207e10 1119
5afbbe0d 1120 int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
7f207e10 1121 {
ba1aed25 1122@@ -631,6 +636,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
7f207e10 1123 return 0;
c2c0f25c 1124 return call_int_hook(path_chown, 0, path, uid, gid);
7f207e10 1125 }
febd17d6 1126+EXPORT_SYMBOL_GPL(security_path_chown);
7f207e10 1127
5afbbe0d 1128 int security_path_chroot(const struct path *path)
7f207e10 1129 {
ba1aed25 1130@@ -716,6 +722,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10 1131 return 0;
c2c0f25c 1132 return call_int_hook(inode_readlink, 0, dentry);
7f207e10 1133 }
febd17d6 1134+EXPORT_SYMBOL_GPL(security_inode_readlink);
7f207e10 1135
c2c0f25c
AM
1136 int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
1137 bool rcu)
ba1aed25 1138@@ -731,6 +738,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 1139 return 0;
c2c0f25c 1140 return call_int_hook(inode_permission, 0, inode, mask);
7f207e10 1141 }
febd17d6 1142+EXPORT_SYMBOL_GPL(security_inode_permission);
7f207e10 1143
1e00d052 1144 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 1145 {
ba1aed25 1146@@ -902,6 +910,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
1147
1148 return fsnotify_perm(file, mask);
1149 }
febd17d6 1150+EXPORT_SYMBOL_GPL(security_file_permission);
7f207e10
AM
1151
1152 int security_file_alloc(struct file *file)
1153 {
ba1aed25 1154@@ -961,6 +970,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
1155 return ret;
1156 return ima_file_mmap(file, prot);
1157 }
febd17d6 1158+EXPORT_SYMBOL_GPL(security_mmap_file);
7f207e10 1159
0c3ec466
AM
1160 int security_mmap_addr(unsigned long addr)
1161 {
7f207e10
AM
1162diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
1163--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 1164+++ linux/Documentation/ABI/testing/debugfs-aufs 2018-08-12 23:43:05.450124426 +0200
062440b3 1165@@ -0,0 +1,55 @@
7f207e10
AM
1166+What: /debug/aufs/si_<id>/
1167+Date: March 2009
f6b6e03d 1168+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1169+Description:
1170+ Under /debug/aufs, a directory named si_<id> is created
1171+ per aufs mount, where <id> is a unique id generated
1172+ internally.
1facf9fc 1173+
86dc4139
AM
1174+What: /debug/aufs/si_<id>/plink
1175+Date: Apr 2013
f6b6e03d 1176+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
1177+Description:
1178+ It has three lines and shows the information about the
1179+ pseudo-link. The first line is a single number
1180+ representing a number of buckets. The second line is a
1181+ number of pseudo-links per buckets (separated by a
1182+ blank). The last line is a single number representing a
1183+ total number of psedo-links.
1184+ When the aufs mount option 'noplink' is specified, it
1185+ will show "1\n0\n0\n".
1186+
7f207e10
AM
1187+What: /debug/aufs/si_<id>/xib
1188+Date: March 2009
f6b6e03d 1189+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1190+Description:
1191+ It shows the consumed blocks by xib (External Inode Number
1192+ Bitmap), its block size and file size.
1193+ When the aufs mount option 'noxino' is specified, it
1194+ will be empty. About XINO files, see the aufs manual.
1195+
062440b3 1196+What: /debug/aufs/si_<id>/xi0, xi1 ... xiN and xiN-N
7f207e10 1197+Date: March 2009
f6b6e03d 1198+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1199+Description:
1200+ It shows the consumed blocks by xino (External Inode Number
1201+ Translation Table), its link count, block size and file
1202+ size.
062440b3
AM
1203+ Due to the file size limit, there may exist multiple
1204+ xino files per branch. In this case, "-N" is added to
1205+ the filename and it corresponds to the index of the
1206+ internal xino array. "-0" is omitted.
1207+ When the aufs mount option 'noxino' is specified, Those
1208+ entries won't exist. About XINO files, see the aufs
1209+ manual.
7f207e10
AM
1210+
1211+What: /debug/aufs/si_<id>/xigen
1212+Date: March 2009
f6b6e03d 1213+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1214+Description:
1215+ It shows the consumed blocks by xigen (External Inode
1216+ Generation Table), its block size and file size.
1217+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
1218+ be created.
1219+ When the aufs mount option 'noxino' is specified, it
1220+ will be empty. About XINO files, see the aufs manual.
1221diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
1222--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
b00004a5 1223+++ linux/Documentation/ABI/testing/sysfs-aufs 2017-07-29 12:14:25.893041746 +0200
392086de 1224@@ -0,0 +1,31 @@
7f207e10
AM
1225+What: /sys/fs/aufs/si_<id>/
1226+Date: March 2009
f6b6e03d 1227+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1228+Description:
1229+ Under /sys/fs/aufs, a directory named si_<id> is created
1230+ per aufs mount, where <id> is a unique id generated
1231+ internally.
1232+
1233+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
1234+Date: March 2009
f6b6e03d 1235+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1236+Description:
1237+ It shows the abolute path of a member directory (which
1238+ is called branch) in aufs, and its permission.
1239+
392086de
AM
1240+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
1241+Date: July 2013
f6b6e03d 1242+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
1243+Description:
1244+ It shows the id of a member directory (which is called
1245+ branch) in aufs.
1246+
7f207e10
AM
1247+What: /sys/fs/aufs/si_<id>/xi_path
1248+Date: March 2009
f6b6e03d 1249+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1250+Description:
1251+ It shows the abolute path of XINO (External Inode Number
1252+ Bitmap, Translation Table and Generation Table) file
1253+ even if it is the default path.
1254+ When the aufs mount option 'noxino' is specified, it
1255+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
1256diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
1257--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 1258+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2019-03-05 12:13:00.132557473 +0100
1c60b727 1259@@ -0,0 +1,171 @@
53392da6 1260+
ba1aed25 1261+# Copyright (C) 2005-2019 Junjiro R. Okajima
53392da6
AM
1262+#
1263+# This program is free software; you can redistribute it and/or modify
1264+# it under the terms of the GNU General Public License as published by
1265+# the Free Software Foundation; either version 2 of the License, or
1266+# (at your option) any later version.
1267+#
1268+# This program is distributed in the hope that it will be useful,
1269+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1270+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1271+# GNU General Public License for more details.
1272+#
1273+# You should have received a copy of the GNU General Public License
523b37e3 1274+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1275+
1276+Introduction
1277+----------------------------------------
1278+
3c1bdaff 1279+aufs [ei ju: ef es] | /ey-yoo-ef-es/ | [a u f s]
53392da6
AM
1280+1. abbrev. for "advanced multi-layered unification filesystem".
1281+2. abbrev. for "another unionfs".
1282+3. abbrev. for "auf das" in German which means "on the" in English.
1283+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
1284+ But "Filesystem aufs Filesystem" is hard to understand.
1c60b727 1285+4. abbrev. for "African Urban Fashion Show".
53392da6
AM
1286+
1287+AUFS is a filesystem with features:
1288+- multi layered stackable unification filesystem, the member directory
1289+ is called as a branch.
1290+- branch permission and attribute, 'readonly', 'real-readonly',
7e9cd9fe 1291+ 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their
53392da6
AM
1292+ combination.
1293+- internal "file copy-on-write".
1294+- logical deletion, whiteout.
1295+- dynamic branch manipulation, adding, deleting and changing permission.
1296+- allow bypassing aufs, user's direct branch access.
1297+- external inode number translation table and bitmap which maintains the
1298+ persistent aufs inode number.
1299+- seekable directory, including NFS readdir.
1300+- file mapping, mmap and sharing pages.
1301+- pseudo-link, hardlink over branches.
1302+- loopback mounted filesystem as a branch.
1303+- several policies to select one among multiple writable branches.
1304+- revert a single systemcall when an error occurs in aufs.
1305+- and more...
1306+
1307+
1308+Multi Layered Stackable Unification Filesystem
1309+----------------------------------------------------------------------
1310+Most people already knows what it is.
1311+It is a filesystem which unifies several directories and provides a
1312+merged single directory. When users access a file, the access will be
1313+passed/re-directed/converted (sorry, I am not sure which English word is
1314+correct) to the real file on the member filesystem. The member
1315+filesystem is called 'lower filesystem' or 'branch' and has a mode
1316+'readonly' and 'readwrite.' And the deletion for a file on the lower
1317+readonly branch is handled by creating 'whiteout' on the upper writable
1318+branch.
1319+
1320+On LKML, there have been discussions about UnionMount (Jan Blunck,
1321+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
1322+different approaches to implement the merged-view.
1323+The former tries putting it into VFS, and the latter implements as a
1324+separate filesystem.
1325+(If I misunderstand about these implementations, please let me know and
1326+I shall correct it. Because it is a long time ago when I read their
1327+source files last time).
1328+
1329+UnionMount's approach will be able to small, but may be hard to share
1330+branches between several UnionMount since the whiteout in it is
1331+implemented in the inode on branch filesystem and always
1332+shared. According to Bharata's post, readdir does not seems to be
1333+finished yet.
1334+There are several missing features known in this implementations such as
1335+- for users, the inode number may change silently. eg. copy-up.
1336+- link(2) may break by copy-up.
1337+- read(2) may get an obsoleted filedata (fstat(2) too).
1338+- fcntl(F_SETLK) may be broken by copy-up.
1339+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
1340+ open(O_RDWR).
1341+
7e9cd9fe
AM
1342+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was
1343+merged into mainline. This is another implementation of UnionMount as a
1344+separated filesystem. All the limitations and known problems which
1345+UnionMount are equally inherited to "overlay" filesystem.
1346+
1347+Unionfs has a longer history. When I started implementing a stackable
1348+filesystem (Aug 2005), it already existed. It has virtual super_block,
1349+inode, dentry and file objects and they have an array pointing lower
1350+same kind objects. After contributing many patches for Unionfs, I
1351+re-started my project AUFS (Jun 2006).
53392da6
AM
1352+
1353+In AUFS, the structure of filesystem resembles to Unionfs, but I
1354+implemented my own ideas, approaches and enhancements and it became
1355+totally different one.
1356+
1357+Comparing DM snapshot and fs based implementation
1358+- the number of bytes to be copied between devices is much smaller.
1359+- the type of filesystem must be one and only.
1360+- the fs must be writable, no readonly fs, even for the lower original
1361+ device. so the compression fs will not be usable. but if we use
1362+ loopback mount, we may address this issue.
1363+ for instance,
1364+ mount /cdrom/squashfs.img /sq
1365+ losetup /sq/ext2.img
1366+ losetup /somewhere/cow
1367+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
1368+- it will be difficult (or needs more operations) to extract the
1369+ difference between the original device and COW.
1370+- DM snapshot-merge may help a lot when users try merging. in the
1371+ fs-layer union, users will use rsync(1).
1372+
7e9cd9fe
AM
1373+You may want to read my old paper "Filesystems in LiveCD"
1374+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf).
53392da6 1375+
7e9cd9fe
AM
1376+
1377+Several characters/aspects/persona of aufs
53392da6
AM
1378+----------------------------------------------------------------------
1379+
7e9cd9fe 1380+Aufs has several characters, aspects or persona.
53392da6
AM
1381+1. a filesystem, callee of VFS helper
1382+2. sub-VFS, caller of VFS helper for branches
1383+3. a virtual filesystem which maintains persistent inode number
1384+4. reader/writer of files on branches such like an application
1385+
1386+1. Callee of VFS Helper
1387+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1388+unlink(2) from an application reaches sys_unlink() kernel function and
1389+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1390+calls filesystem specific unlink operation. Actually aufs implements the
1391+unlink operation but it behaves like a redirector.
1392+
1393+2. Caller of VFS Helper for Branches
1394+aufs_unlink() passes the unlink request to the branch filesystem as if
1395+it were called from VFS. So the called unlink operation of the branch
1396+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1397+every necessary pre/post operation for the branch filesystem.
1398+- acquire the lock for the parent dir on a branch
1399+- lookup in a branch
1400+- revalidate dentry on a branch
1401+- mnt_want_write() for a branch
1402+- vfs_unlink() for a branch
1403+- mnt_drop_write() for a branch
1404+- release the lock on a branch
1405+
1406+3. Persistent Inode Number
1407+One of the most important issue for a filesystem is to maintain inode
1408+numbers. This is particularly important to support exporting a
1409+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1410+backend block device for its own. But some storage is necessary to
7e9cd9fe
AM
1411+keep and maintain the inode numbers. It may be a large space and may not
1412+suit to keep in memory. Aufs rents some space from its first writable
1413+branch filesystem (by default) and creates file(s) on it. These files
1414+are created by aufs internally and removed soon (currently) keeping
1415+opened.
53392da6
AM
1416+Note: Because these files are removed, they are totally gone after
1417+ unmounting aufs. It means the inode numbers are not persistent
1418+ across unmount or reboot. I have a plan to make them really
1419+ persistent which will be important for aufs on NFS server.
1420+
1421+4. Read/Write Files Internally (copy-on-write)
1422+Because a branch can be readonly, when you write a file on it, aufs will
1423+"copy-up" it to the upper writable branch internally. And then write the
1424+originally requested thing to the file. Generally kernel doesn't
1425+open/read/write file actively. In aufs, even a single write may cause a
1426+internal "file copy". This behaviour is very similar to cp(1) command.
1427+
1428+Some people may think it is better to pass such work to user space
1429+helper, instead of doing in kernel space. Actually I am still thinking
1430+about it. But currently I have implemented it in kernel space.
1431diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1432--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 1433+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2019-03-05 12:13:00.132557473 +0100
7e9cd9fe 1434@@ -0,0 +1,258 @@
53392da6 1435+
ba1aed25 1436+# Copyright (C) 2005-2019 Junjiro R. Okajima
53392da6
AM
1437+#
1438+# This program is free software; you can redistribute it and/or modify
1439+# it under the terms of the GNU General Public License as published by
1440+# the Free Software Foundation; either version 2 of the License, or
1441+# (at your option) any later version.
1442+#
1443+# This program is distributed in the hope that it will be useful,
1444+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1445+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1446+# GNU General Public License for more details.
1447+#
1448+# You should have received a copy of the GNU General Public License
523b37e3 1449+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1450+
1451+Basic Aufs Internal Structure
1452+
1453+Superblock/Inode/Dentry/File Objects
1454+----------------------------------------------------------------------
1455+As like an ordinary filesystem, aufs has its own
1456+superblock/inode/dentry/file objects. All these objects have a
1457+dynamically allocated array and store the same kind of pointers to the
1458+lower filesystem, branch.
1459+For example, when you build a union with one readwrite branch and one
1460+readonly, mounted /au, /rw and /ro respectively.
1461+- /au = /rw + /ro
1462+- /ro/fileA exists but /rw/fileA
1463+
1464+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1465+pointers are stored in a aufs dentry. The array in aufs dentry will be,
7e9cd9fe 1466+- [0] = NULL (because /rw/fileA doesn't exist)
53392da6
AM
1467+- [1] = /ro/fileA
1468+
1469+This style of an array is essentially same to the aufs
1470+superblock/inode/dentry/file objects.
1471+
1472+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1473+branches dynamically, these objects has its own generation. When
1474+branches are changed, the generation in aufs superblock is
1475+incremented. And a generation in other object are compared when it is
1476+accessed. When a generation in other objects are obsoleted, aufs
1477+refreshes the internal array.
53392da6
AM
1478+
1479+
1480+Superblock
1481+----------------------------------------------------------------------
1482+Additionally aufs superblock has some data for policies to select one
1483+among multiple writable branches, XIB files, pseudo-links and kobject.
1484+See below in detail.
7e9cd9fe
AM
1485+About the policies which supports copy-down a directory, see
1486+wbr_policy.txt too.
53392da6
AM
1487+
1488+
1489+Branch and XINO(External Inode Number Translation Table)
1490+----------------------------------------------------------------------
1491+Every branch has its own xino (external inode number translation table)
1492+file. The xino file is created and unlinked by aufs internally. When two
1493+members of a union exist on the same filesystem, they share the single
1494+xino file.
1495+The struct of a xino file is simple, just a sequence of aufs inode
1496+numbers which is indexed by the lower inode number.
1497+In the above sample, assume the inode number of /ro/fileA is i111 and
1498+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1499+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1500+
1501+When the inode numbers are not contiguous, the xino file will be sparse
1502+which has a hole in it and doesn't consume as much disk space as it
1503+might appear. If your branch filesystem consumes disk space for such
1504+holes, then you should specify 'xino=' option at mounting aufs.
1505+
7e9cd9fe
AM
1506+Aufs has a mount option to free the disk blocks for such holes in XINO
1507+files on tmpfs or ramdisk. But it is not so effective actually. If you
1508+meet a problem of disk shortage due to XINO files, then you should try
1509+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git.
1510+The patch localizes the assignment inumbers per tmpfs-mount and avoid
1511+the holes in XINO files.
1512+
53392da6 1513+Also a writable branch has three kinds of "whiteout bases". All these
7e9cd9fe 1514+are existed when the branch is joined to aufs, and their names are
53392da6
AM
1515+whiteout-ed doubly, so that users will never see their names in aufs
1516+hierarchy.
7e9cd9fe 1517+1. a regular file which will be hardlinked to all whiteouts.
53392da6 1518+2. a directory to store a pseudo-link.
7e9cd9fe 1519+3. a directory to store an "orphan"-ed file temporary.
53392da6
AM
1520+
1521+1. Whiteout Base
1522+ When you remove a file on a readonly branch, aufs handles it as a
1523+ logical deletion and creates a whiteout on the upper writable branch
1524+ as a hardlink of this file in order not to consume inode on the
1525+ writable branch.
1526+2. Pseudo-link Dir
1527+ See below, Pseudo-link.
1528+3. Step-Parent Dir
1529+ When "fileC" exists on the lower readonly branch only and it is
1530+ opened and removed with its parent dir, and then user writes
1531+ something into it, then aufs copies-up fileC to this
1532+ directory. Because there is no other dir to store fileC. After
1533+ creating a file under this dir, the file is unlinked.
1534+
1535+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1536+dynamically, a branch has its own id. When the branch order changes,
1537+aufs finds the new index by searching the branch id.
53392da6
AM
1538+
1539+
1540+Pseudo-link
1541+----------------------------------------------------------------------
1542+Assume "fileA" exists on the lower readonly branch only and it is
1543+hardlinked to "fileB" on the branch. When you write something to fileA,
1544+aufs copies-up it to the upper writable branch. Additionally aufs
1545+creates a hardlink under the Pseudo-link Directory of the writable
1546+branch. The inode of a pseudo-link is kept in aufs super_block as a
1547+simple list. If fileB is read after unlinking fileA, aufs returns
1548+filedata from the pseudo-link instead of the lower readonly
1549+branch. Because the pseudo-link is based upon the inode, to keep the
7e9cd9fe 1550+inode number by xino (see above) is essentially necessary.
53392da6
AM
1551+
1552+All the hardlinks under the Pseudo-link Directory of the writable branch
1553+should be restored in a proper location later. Aufs provides a utility
1554+to do this. The userspace helpers executed at remounting and unmounting
1555+aufs by default.
1556+During this utility is running, it puts aufs into the pseudo-link
1557+maintenance mode. In this mode, only the process which began the
1558+maintenance mode (and its child processes) is allowed to operate in
1559+aufs. Some other processes which are not related to the pseudo-link will
1560+be allowed to run too, but the rest have to return an error or wait
1561+until the maintenance mode ends. If a process already acquires an inode
1562+mutex (in VFS), it has to return an error.
1563+
1564+
1565+XIB(external inode number bitmap)
1566+----------------------------------------------------------------------
1567+Addition to the xino file per a branch, aufs has an external inode number
7e9cd9fe
AM
1568+bitmap in a superblock object. It is also an internal file such like a
1569+xino file.
53392da6
AM
1570+It is a simple bitmap to mark whether the aufs inode number is in-use or
1571+not.
1572+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1573+
7e9cd9fe 1574+As well as XINO files, aufs has a feature to truncate/refresh XIB to
53392da6
AM
1575+reduce the number of consumed disk blocks for these files.
1576+
1577+
1578+Virtual or Vertical Dir, and Readdir in Userspace
1579+----------------------------------------------------------------------
1580+In order to support multiple layers (branches), aufs readdir operation
1581+constructs a virtual dir block on memory. For readdir, aufs calls
1582+vfs_readdir() internally for each dir on branches, merges their entries
1583+with eliminating the whiteout-ed ones, and sets it to file (dir)
1584+object. So the file object has its entry list until it is closed. The
1585+entry list will be updated when the file position is zero and becomes
7e9cd9fe 1586+obsoleted. This decision is made in aufs automatically.
53392da6
AM
1587+
1588+The dynamically allocated memory block for the name of entries has a
1589+unit of 512 bytes (by default) and stores the names contiguously (no
1590+padding). Another block for each entry is handled by kmem_cache too.
1591+During building dir blocks, aufs creates hash list and judging whether
1592+the entry is whiteouted by its upper branch or already listed.
1593+The merged result is cached in the corresponding inode object and
1594+maintained by a customizable life-time option.
1595+
1596+Some people may call it can be a security hole or invite DoS attack
1597+since the opened and once readdir-ed dir (file object) holds its entry
1598+list and becomes a pressure for system memory. But I'd say it is similar
1599+to files under /proc or /sys. The virtual files in them also holds a
1600+memory page (generally) while they are opened. When an idea to reduce
1601+memory for them is introduced, it will be applied to aufs too.
1602+For those who really hate this situation, I've developed readdir(3)
1603+library which operates this merging in userspace. You just need to set
1604+LD_PRELOAD environment variable, and aufs will not consume no memory in
1605+kernel space for readdir(3).
1606+
1607+
1608+Workqueue
1609+----------------------------------------------------------------------
1610+Aufs sometimes requires privilege access to a branch. For instance,
1611+in copy-up/down operation. When a user process is going to make changes
1612+to a file which exists in the lower readonly branch only, and the mode
1613+of one of ancestor directories may not be writable by a user
1614+process. Here aufs copy-up the file with its ancestors and they may
1615+require privilege to set its owner/group/mode/etc.
1616+This is a typical case of a application character of aufs (see
1617+Introduction).
1618+
1619+Aufs uses workqueue synchronously for this case. It creates its own
1620+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1621+passes the request to call mkdir or write (for example), and wait for
1622+its completion. This approach solves a problem of a signal handler
1623+simply.
1624+If aufs didn't adopt the workqueue and changed the privilege of the
7e9cd9fe
AM
1625+process, then the process may receive the unexpected SIGXFSZ or other
1626+signals.
53392da6
AM
1627+
1628+Also aufs uses the system global workqueue ("events" kernel thread) too
1629+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1630+whiteout base and etc. This is unrelated to a privilege.
1631+Most of aufs operation tries acquiring a rw_semaphore for aufs
1632+superblock at the beginning, at the same time waits for the completion
1633+of all queued asynchronous tasks.
1634+
1635+
1636+Whiteout
1637+----------------------------------------------------------------------
1638+The whiteout in aufs is very similar to Unionfs's. That is represented
1639+by its filename. UnionMount takes an approach of a file mode, but I am
1640+afraid several utilities (find(1) or something) will have to support it.
1641+
1642+Basically the whiteout represents "logical deletion" which stops aufs to
1643+lookup further, but also it represents "dir is opaque" which also stop
7e9cd9fe 1644+further lookup.
53392da6
AM
1645+
1646+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1647+In order to make several functions in a single systemcall to be
1648+revertible, aufs adopts an approach to rename a directory to a temporary
1649+unique whiteouted name.
1650+For example, in rename(2) dir where the target dir already existed, aufs
1651+renames the target dir to a temporary unique whiteouted name before the
7e9cd9fe 1652+actual rename on a branch, and then handles other actions (make it opaque,
53392da6
AM
1653+update the attributes, etc). If an error happens in these actions, aufs
1654+simply renames the whiteouted name back and returns an error. If all are
1655+succeeded, aufs registers a function to remove the whiteouted unique
1656+temporary name completely and asynchronously to the system global
1657+workqueue.
1658+
1659+
1660+Copy-up
1661+----------------------------------------------------------------------
1662+It is a well-known feature or concept.
1663+When user modifies a file on a readonly branch, aufs operate "copy-up"
1664+internally and makes change to the new file on the upper writable branch.
1665+When the trigger systemcall does not update the timestamps of the parent
1666+dir, aufs reverts it after copy-up.
c2b27bf2
AM
1667+
1668+
1669+Move-down (aufs3.9 and later)
1670+----------------------------------------------------------------------
1671+"Copy-up" is one of the essential feature in aufs. It copies a file from
1672+the lower readonly branch to the upper writable branch when a user
1673+changes something about the file.
1674+"Move-down" is an opposite action of copy-up. Basically this action is
1675+ran manually instead of automatically and internally.
076b876e
AM
1676+For desgin and implementation, aufs has to consider these issues.
1677+- whiteout for the file may exist on the lower branch.
1678+- ancestor directories may not exist on the lower branch.
1679+- diropq for the ancestor directories may exist on the upper branch.
1680+- free space on the lower branch will reduce.
1681+- another access to the file may happen during moving-down, including
7e9cd9fe 1682+ UDBA (see "Revalidate Dentry and UDBA").
076b876e
AM
1683+- the file should not be hard-linked nor pseudo-linked. they should be
1684+ handled by auplink utility later.
c2b27bf2
AM
1685+
1686+Sometimes users want to move-down a file from the upper writable branch
1687+to the lower readonly or writable branch. For instance,
1688+- the free space of the upper writable branch is going to run out.
1689+- create a new intermediate branch between the upper and lower branch.
1690+- etc.
1691+
1692+For this purpose, use "aumvdown" command in aufs-util.git.
b912730e
AM
1693diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt linux/Documentation/filesystems/aufs/design/03atomic_open.txt
1694--- /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 1695+++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2019-03-05 12:13:00.132557473 +0100
b912730e
AM
1696@@ -0,0 +1,85 @@
1697+
ba1aed25 1698+# Copyright (C) 2015-2019 Junjiro R. Okajima
b912730e
AM
1699+#
1700+# This program is free software; you can redistribute it and/or modify
1701+# it under the terms of the GNU General Public License as published by
1702+# the Free Software Foundation; either version 2 of the License, or
1703+# (at your option) any later version.
1704+#
1705+# This program is distributed in the hope that it will be useful,
1706+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1707+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1708+# GNU General Public License for more details.
1709+#
1710+# You should have received a copy of the GNU General Public License
1711+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1712+
1713+Support for a branch who has its ->atomic_open()
1714+----------------------------------------------------------------------
1715+The filesystems who implement its ->atomic_open() are not majority. For
1716+example NFSv4 does, and aufs should call NFSv4 ->atomic_open,
1717+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than
1718+->atomic_open(), NFSv4 returns an error for this open(2). While I am not
1719+sure whether all filesystems who have ->atomic_open() behave like this,
1720+but NFSv4 surely returns the error.
1721+
1722+In order to support ->atomic_open() for aufs, there are a few
1723+approaches.
1724+
1725+A. Introduce aufs_atomic_open()
1726+ - calls one of VFS:do_last(), lookup_open() or atomic_open() for
1727+ branch fs.
1728+B. Introduce aufs_atomic_open() calling create, open and chmod. this is
1729+ an aufs user Pip Cet's approach
1730+ - calls aufs_create(), VFS finish_open() and notify_change().
1731+ - pass fake-mode to finish_open(), and then correct the mode by
1732+ notify_change().
1733+C. Extend aufs_open() to call branch fs's ->atomic_open()
1734+ - no aufs_atomic_open().
1735+ - aufs_lookup() registers the TID to an aufs internal object.
1736+ - aufs_create() does nothing when the matching TID is registered, but
1737+ registers the mode.
1738+ - aufs_open() calls branch fs's ->atomic_open() when the matching
1739+ TID is registered.
1740+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's
1741+ credential
1742+ - no aufs_atomic_open().
1743+ - aufs_create() registers the TID to an internal object. this info
1744+ represents "this process created this file just now."
1745+ - when aufs gets EACCES from branch fs's ->open(), then confirm the
1746+ registered TID and re-try open() with superuser's credential.
1747+
1748+Pros and cons for each approach.
1749+
1750+A.
1751+ - straightforward but highly depends upon VFS internal.
1752+ - the atomic behavaiour is kept.
1753+ - some of parameters such as nameidata are hard to reproduce for
1754+ branch fs.
1755+ - large overhead.
1756+B.
1757+ - easy to implement.
1758+ - the atomic behavaiour is lost.
1759+C.
1760+ - the atomic behavaiour is kept.
1761+ - dirty and tricky.
1762+ - VFS checks whether the file is created correctly after calling
1763+ ->create(), which means this approach doesn't work.
1764+D.
1765+ - easy to implement.
1766+ - the atomic behavaiour is lost.
1767+ - to open a file with superuser's credential and give it to a user
1768+ process is a bad idea, since the file object keeps the credential
1769+ in it. It may affect LSM or something. This approach doesn't work
1770+ either.
1771+
1772+The approach A is ideal, but it hard to implement. So here is a
1773+variation of A, which is to be implemented.
1774+
1775+A-1. Introduce aufs_atomic_open()
1776+ - calls branch fs ->atomic_open() if exists. otherwise calls
1777+ vfs_create() and finish_open().
1778+ - the demerit is that the several checks after branch fs
1779+ ->atomic_open() are lost. in the ordinary case, the checks are
1780+ done by VFS:do_last(), lookup_open() and atomic_open(). some can
1781+ be implemented in aufs, but not all I am afraid.
53392da6
AM
1782diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1783--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 1784+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2019-03-05 12:13:00.132557473 +0100
7e9cd9fe 1785@@ -0,0 +1,113 @@
53392da6 1786+
ba1aed25 1787+# Copyright (C) 2005-2019 Junjiro R. Okajima
53392da6
AM
1788+#
1789+# This program is free software; you can redistribute it and/or modify
1790+# it under the terms of the GNU General Public License as published by
1791+# the Free Software Foundation; either version 2 of the License, or
1792+# (at your option) any later version.
1793+#
1794+# This program is distributed in the hope that it will be useful,
1795+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1796+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1797+# GNU General Public License for more details.
1798+#
1799+# You should have received a copy of the GNU General Public License
523b37e3 1800+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1801+
1802+Lookup in a Branch
1803+----------------------------------------------------------------------
1804+Since aufs has a character of sub-VFS (see Introduction), it operates
7e9cd9fe
AM
1805+lookup for branches as VFS does. It may be a heavy work. But almost all
1806+lookup operation in aufs is the simplest case, ie. lookup only an entry
1807+directly connected to its parent. Digging down the directory hierarchy
1808+is unnecessary. VFS has a function lookup_one_len() for that use, and
1809+aufs calls it.
1810+
1811+When a branch is a remote filesystem, aufs basically relies upon its
53392da6
AM
1812+->d_revalidate(), also aufs forces the hardest revalidate tests for
1813+them.
1814+For d_revalidate, aufs implements three levels of revalidate tests. See
1815+"Revalidate Dentry and UDBA" in detail.
1816+
1817+
076b876e
AM
1818+Test Only the Highest One for the Directory Permission (dirperm1 option)
1819+----------------------------------------------------------------------
1820+Let's try case study.
1821+- aufs has two branches, upper readwrite and lower readonly.
1822+ /au = /rw + /ro
1823+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1824+- user invoked "chmod a+rx /au/dirA"
1825+- the internal copy-up is activated and "/rw/dirA" is created and its
7e9cd9fe 1826+ permission bits are set to world readable.
076b876e
AM
1827+- then "/au/dirA" becomes world readable?
1828+
1829+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1830+or it may be a natively readonly filesystem. If aufs respects the lower
1831+branch, it should not respond readdir request from other users. But user
1832+allowed it by chmod. Should really aufs rejects showing the entries
1833+under /ro/dirA?
1834+
7e9cd9fe
AM
1835+To be honest, I don't have a good solution for this case. So aufs
1836+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to
1837+users.
076b876e
AM
1838+When dirperm1 is specified, aufs checks only the highest one for the
1839+directory permission, and shows the entries. Otherwise, as usual, checks
1840+every dir existing on all branches and rejects the request.
1841+
1842+As a side effect, dirperm1 option improves the performance of aufs
1843+because the number of permission check is reduced when the number of
1844+branch is many.
1845+
1846+
53392da6
AM
1847+Revalidate Dentry and UDBA (User's Direct Branch Access)
1848+----------------------------------------------------------------------
1849+Generally VFS helpers re-validate a dentry as a part of lookup.
1850+0. digging down the directory hierarchy.
1851+1. lock the parent dir by its i_mutex.
1852+2. lookup the final (child) entry.
1853+3. revalidate it.
1854+4. call the actual operation (create, unlink, etc.)
1855+5. unlock the parent dir
1856+
1857+If the filesystem implements its ->d_revalidate() (step 3), then it is
1858+called. Actually aufs implements it and checks the dentry on a branch is
1859+still valid.
1860+But it is not enough. Because aufs has to release the lock for the
1861+parent dir on a branch at the end of ->lookup() (step 2) and
1862+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1863+held by VFS.
1864+If the file on a branch is changed directly, eg. bypassing aufs, after
1865+aufs released the lock, then the subsequent operation may cause
1866+something unpleasant result.
1867+
1868+This situation is a result of VFS architecture, ->lookup() and
1869+->d_revalidate() is separated. But I never say it is wrong. It is a good
1870+design from VFS's point of view. It is just not suitable for sub-VFS
1871+character in aufs.
1872+
1873+Aufs supports such case by three level of revalidation which is
1874+selectable by user.
1875+1. Simple Revalidate
1876+ Addition to the native flow in VFS's, confirm the child-parent
1877+ relationship on the branch just after locking the parent dir on the
1878+ branch in the "actual operation" (step 4). When this validation
1879+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1880+ checks the validation of the dentry on branches.
1881+2. Monitor Changes Internally by Inotify/Fsnotify
1882+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1883+ the dentry on the branch, and returns EBUSY if it finds different
1884+ dentry.
1885+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1886+ during it is in cache. When the event is notified, aufs registers a
1887+ function to kernel 'events' thread by schedule_work(). And the
1888+ function sets some special status to the cached aufs dentry and inode
1889+ private data. If they are not cached, then aufs has nothing to
1890+ do. When the same file is accessed through aufs (step 0-3) later,
1891+ aufs will detect the status and refresh all necessary data.
1892+ In this mode, aufs has to ignore the event which is fired by aufs
1893+ itself.
1894+3. No Extra Validation
1895+ This is the simplest test and doesn't add any additional revalidation
7e9cd9fe 1896+ test, and skip the revalidation in step 4. It is useful and improves
53392da6
AM
1897+ aufs performance when system surely hide the aufs branches from user,
1898+ by over-mounting something (or another method).
1899diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1900--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 1901+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2019-03-05 12:13:00.132557473 +0100
7e9cd9fe 1902@@ -0,0 +1,74 @@
53392da6 1903+
ba1aed25 1904+# Copyright (C) 2005-2019 Junjiro R. Okajima
53392da6
AM
1905+#
1906+# This program is free software; you can redistribute it and/or modify
1907+# it under the terms of the GNU General Public License as published by
1908+# the Free Software Foundation; either version 2 of the License, or
1909+# (at your option) any later version.
1910+#
1911+# This program is distributed in the hope that it will be useful,
1912+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1913+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1914+# GNU General Public License for more details.
1915+#
1916+# You should have received a copy of the GNU General Public License
523b37e3 1917+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1918+
1919+Branch Manipulation
1920+
1921+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1922+and changing its permission/attribute, there are a lot of works to do.
1923+
1924+
1925+Add a Branch
1926+----------------------------------------------------------------------
1927+o Confirm the adding dir exists outside of aufs, including loopback
7e9cd9fe 1928+ mount, and its various attributes.
53392da6
AM
1929+o Initialize the xino file and whiteout bases if necessary.
1930+ See struct.txt.
1931+
1932+o Check the owner/group/mode of the directory
1933+ When the owner/group/mode of the adding directory differs from the
1934+ existing branch, aufs issues a warning because it may impose a
1935+ security risk.
1936+ For example, when a upper writable branch has a world writable empty
1937+ top directory, a malicious user can create any files on the writable
1938+ branch directly, like copy-up and modify manually. If something like
1939+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1940+ writable branch, and the writable branch is world-writable, then a
1941+ malicious guy may create /etc/passwd on the writable branch directly
1942+ and the infected file will be valid in aufs.
7e9cd9fe 1943+ I am afraid it can be a security issue, but aufs can do nothing except
53392da6
AM
1944+ producing a warning.
1945+
1946+
1947+Delete a Branch
1948+----------------------------------------------------------------------
1949+o Confirm the deleting branch is not busy
1950+ To be general, there is one merit to adopt "remount" interface to
1951+ manipulate branches. It is to discard caches. At deleting a branch,
1952+ aufs checks the still cached (and connected) dentries and inodes. If
1953+ there are any, then they are all in-use. An inode without its
1954+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1955+
1956+ For the cached one, aufs checks whether the same named entry exists on
1957+ other branches.
1958+ If the cached one is a directory, because aufs provides a merged view
1959+ to users, as long as one dir is left on any branch aufs can show the
1960+ dir to users. In this case, the branch can be removed from aufs.
1961+ Otherwise aufs rejects deleting the branch.
1962+
1963+ If any file on the deleting branch is opened by aufs, then aufs
1964+ rejects deleting.
1965+
1966+
1967+Modify the Permission of a Branch
1968+----------------------------------------------------------------------
1969+o Re-initialize or remove the xino file and whiteout bases if necessary.
1970+ See struct.txt.
1971+
1972+o rw --> ro: Confirm the modifying branch is not busy
1973+ Aufs rejects the request if any of these conditions are true.
1974+ - a file on the branch is mmap-ed.
1975+ - a regular file on the branch is opened for write and there is no
1976+ same named entry on the upper branch.
1977diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1978--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 1979+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2019-03-05 12:13:00.132557473 +0100
523b37e3 1980@@ -0,0 +1,64 @@
53392da6 1981+
ba1aed25 1982+# Copyright (C) 2005-2019 Junjiro R. Okajima
53392da6
AM
1983+#
1984+# This program is free software; you can redistribute it and/or modify
1985+# it under the terms of the GNU General Public License as published by
1986+# the Free Software Foundation; either version 2 of the License, or
1987+# (at your option) any later version.
1988+#
1989+# This program is distributed in the hope that it will be useful,
1990+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1991+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1992+# GNU General Public License for more details.
1993+#
1994+# You should have received a copy of the GNU General Public License
523b37e3 1995+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1996+
1997+Policies to Select One among Multiple Writable Branches
1998+----------------------------------------------------------------------
1999+When the number of writable branch is more than one, aufs has to decide
2000+the target branch for file creation or copy-up. By default, the highest
2001+writable branch which has the parent (or ancestor) dir of the target
2002+file is chosen (top-down-parent policy).
2003+By user's request, aufs implements some other policies to select the
7e9cd9fe
AM
2004+writable branch, for file creation several policies, round-robin,
2005+most-free-space, and other policies. For copy-up, top-down-parent,
2006+bottom-up-parent, bottom-up and others.
53392da6
AM
2007+
2008+As expected, the round-robin policy selects the branch in circular. When
2009+you have two writable branches and creates 10 new files, 5 files will be
2010+created for each branch. mkdir(2) systemcall is an exception. When you
2011+create 10 new directories, all will be created on the same branch.
2012+And the most-free-space policy selects the one which has most free
2013+space among the writable branches. The amount of free space will be
2014+checked by aufs internally, and users can specify its time interval.
2015+
2016+The policies for copy-up is more simple,
2017+top-down-parent is equivalent to the same named on in create policy,
2018+bottom-up-parent selects the writable branch where the parent dir
2019+exists and the nearest upper one from the copyup-source,
2020+bottom-up selects the nearest upper writable branch from the
2021+copyup-source, regardless the existence of the parent dir.
2022+
2023+There are some rules or exceptions to apply these policies.
2024+- If there is a readonly branch above the policy-selected branch and
2025+ the parent dir is marked as opaque (a variation of whiteout), or the
2026+ target (creating) file is whiteout-ed on the upper readonly branch,
2027+ then the result of the policy is ignored and the target file will be
2028+ created on the nearest upper writable branch than the readonly branch.
2029+- If there is a writable branch above the policy-selected branch and
2030+ the parent dir is marked as opaque or the target file is whiteouted
2031+ on the branch, then the result of the policy is ignored and the target
2032+ file will be created on the highest one among the upper writable
2033+ branches who has diropq or whiteout. In case of whiteout, aufs removes
2034+ it as usual.
2035+- link(2) and rename(2) systemcalls are exceptions in every policy.
2036+ They try selecting the branch where the source exists as possible
2037+ since copyup a large file will take long time. If it can't be,
2038+ ie. the branch where the source exists is readonly, then they will
2039+ follow the copyup policy.
2040+- There is an exception for rename(2) when the target exists.
2041+ If the rename target exists, aufs compares the index of the branches
2042+ where the source and the target exists and selects the higher
2043+ one. If the selected branch is readonly, then aufs follows the
2044+ copyup policy.
8b6a4947
AM
2045diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot linux/Documentation/filesystems/aufs/design/06dirren.dot
2046--- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot 1970-01-01 01:00:00.000000000 +0100
b00004a5 2047+++ linux/Documentation/filesystems/aufs/design/06dirren.dot 2018-04-15 08:49:13.394483860 +0200
8b6a4947
AM
2048@@ -0,0 +1,31 @@
2049+
2050+// to view this graph, run dot(1) command in GRAPHVIZ.
2051+
2052+digraph G {
2053+node [shape=box];
2054+whinfo [label="detailed info file\n(lower_brid_root-hinum, h_inum, namelen, old name)"];
2055+
2056+node [shape=oval];
2057+
2058+aufs_rename -> whinfo [label="store/remove"];
2059+
2060+node [shape=oval];
2061+inode_list [label="h_inum list in branch\ncache"];
2062+
2063+node [shape=box];
2064+whinode [label="h_inum list file"];
2065+
2066+node [shape=oval];
2067+brmgmt [label="br_add/del/mod/umount"];
2068+
2069+brmgmt -> inode_list [label="create/remove"];
2070+brmgmt -> whinode [label="load/store"];
2071+
2072+inode_list -> whinode [style=dashed,dir=both];
2073+
2074+aufs_rename -> inode_list [label="add/del"];
2075+
2076+aufs_lookup -> inode_list [label="search"];
2077+
2078+aufs_lookup -> whinfo [label="load/remove"];
2079+}
2080diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt linux/Documentation/filesystems/aufs/design/06dirren.txt
2081--- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 2082+++ linux/Documentation/filesystems/aufs/design/06dirren.txt 2019-03-05 12:13:00.132557473 +0100
8b6a4947
AM
2083@@ -0,0 +1,102 @@
2084+
ba1aed25 2085+# Copyright (C) 2017-2019 Junjiro R. Okajima
8b6a4947
AM
2086+#
2087+# This program is free software; you can redistribute it and/or modify
2088+# it under the terms of the GNU General Public License as published by
2089+# the Free Software Foundation; either version 2 of the License, or
2090+# (at your option) any later version.
2091+#
2092+# This program is distributed in the hope that it will be useful,
2093+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2094+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2095+# GNU General Public License for more details.
2096+#
2097+# You should have received a copy of the GNU General Public License
2098+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2099+
2100+Special handling for renaming a directory (DIRREN)
2101+----------------------------------------------------------------------
2102+First, let's assume we have a simple usecase.
2103+
2104+- /u = /rw + /ro
2105+- /rw/dirA exists
2106+- /ro/dirA and /ro/dirA/file exist too
2107+- there is no dirB on both branches
2108+- a user issues rename("dirA", "dirB")
2109+
2110+Now, what should aufs behave against this rename(2)?
2111+There are a few possible cases.
2112+
2113+A. returns EROFS.
2114+ since dirA exists on a readonly branch which cannot be renamed.
2115+B. returns EXDEV.
2116+ it is possible to copy-up dirA (only the dir itself), but the child
2117+ entries ("file" in this case) should not be. it must be a bad
2118+ approach to copy-up recursively.
2119+C. returns a success.
2120+ even the branch /ro is readonly, aufs tries renaming it. Obviously it
2121+ is a violation of aufs' policy.
2122+D. construct an extra information which indicates that /ro/dirA should
2123+ be handled as the name of dirB.
2124+ overlayfs has a similar feature called REDIRECT.
2125+
2126+Until now, aufs implements the case B only which returns EXDEV, and
2127+expects the userspace application behaves like mv(1) which tries
2128+issueing rename(2) recursively.
2129+
2130+A new aufs feature called DIRREN is introduced which implements the case
2131+D. There are several "extra information" added.
2132+
2133+1. detailed info per renamed directory
2134+ path: /rw/dirB/$AUFS_WH_DR_INFO_PFX.<lower branch-id>
2135+2. the inode-number list of directories on a branch
2136+ path: /rw/dirB/$AUFS_WH_DR_BRHINO
2137+
2138+The filename of "detailed info per directory" represents the lower
2139+branch, and its format is
2140+- a type of the branch id
2141+ one of these.
2142+ + uuid (not implemented yet)
2143+ + fsid
2144+ + dev
2145+- the inode-number of the branch root dir
2146+
2147+And it contains these info in a single regular file.
2148+- magic number
2149+- branch's inode-number of the logically renamed dir
2150+- the name of the before-renamed dir
2151+
2152+The "detailed info per directory" file is created in aufs rename(2), and
2153+loaded in any lookup.
2154+The info is considered in lookup for the matching case only. Here
2155+"matching" means that the root of branch (in the info filename) is same
2156+to the current looking-up branch. After looking-up the before-renamed
2157+name, the inode-number is compared. And the matched dentry is used.
2158+
2159+The "inode-number list of directories" is a regular file which contains
2160+simply the inode-numbers on the branch. The file is created or updated
2161+in removing the branch, and loaded in adding the branch. Its lifetime is
2162+equal to the branch.
2163+The list is refered in lookup, and when the current target inode is
2164+found in the list, the aufs tries loading the "detailed info per
2165+directory" and get the changed and valid name of the dir.
2166+
2167+Theoretically these "extra informaiton" may be able to be put into XATTR
2168+in the dir inode. But aufs doesn't choose this way because
2169+1. XATTR may not be supported by the branch (or its configuration)
2170+2. XATTR may have its size limit.
2171+3. XATTR may be less easy to convert than a regular file, when the
2172+ format of the info is changed in the future.
2173+At the same time, I agree that the regular file approach is much slower
2174+than XATTR approach. So, in the future, aufs may take the XATTR or other
2175+better approach.
2176+
2177+This DIRREN feature is enabled by aufs configuration, and is activated
2178+by a new mount option.
2179+
2180+For the more complicated case, there is a work with UDBA option, which
2181+is to dected the direct access to the branches (by-passing aufs) and to
2182+maintain the cashes in aufs. Since a single cached aufs dentry may
2183+contains two names, before- and after-rename, the name comparision in
2184+UDBA handler may not work correctly. In this case, the behaviour will be
2185+equivalen to udba=reval case.
076b876e
AM
2186diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
2187--- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 2188+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2019-03-05 12:13:00.132557473 +0100
076b876e
AM
2189@@ -0,0 +1,120 @@
2190+
ba1aed25 2191+# Copyright (C) 2011-2019 Junjiro R. Okajima
076b876e
AM
2192+#
2193+# This program is free software; you can redistribute it and/or modify
2194+# it under the terms of the GNU General Public License as published by
2195+# the Free Software Foundation; either version 2 of the License, or
2196+# (at your option) any later version.
2197+#
2198+# This program is distributed in the hope that it will be useful,
2199+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2200+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2201+# GNU General Public License for more details.
2202+#
2203+# You should have received a copy of the GNU General Public License
2204+# along with this program; if not, write to the Free Software
2205+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2206+
2207+
2208+File-based Hierarchical Storage Management (FHSM)
2209+----------------------------------------------------------------------
2210+Hierarchical Storage Management (or HSM) is a well-known feature in the
2211+storage world. Aufs provides this feature as file-based with multiple
7e9cd9fe 2212+writable branches, based upon the principle of "Colder, the Lower".
076b876e 2213+Here the word "colder" means that the less used files, and "lower" means
7e9cd9fe 2214+that the position in the order of the stacked branches vertically.
076b876e
AM
2215+These multiple writable branches are prioritized, ie. the topmost one
2216+should be the fastest drive and be used heavily.
2217+
2218+o Characters in aufs FHSM story
2219+- aufs itself and a new branch attribute.
2220+- a new ioctl interface to move-down and to establish a connection with
2221+ the daemon ("move-down" is a converse of "copy-up").
2222+- userspace tool and daemon.
2223+
2224+The userspace daemon establishes a connection with aufs and waits for
2225+the notification. The notified information is very similar to struct
2226+statfs containing the number of consumed blocks and inodes.
2227+When the consumed blocks/inodes of a branch exceeds the user-specified
2228+upper watermark, the daemon activates its move-down process until the
2229+consumed blocks/inodes reaches the user-specified lower watermark.
2230+
2231+The actual move-down is done by aufs based upon the request from
2232+user-space since we need to maintain the inode number and the internal
2233+pointer arrays in aufs.
2234+
2235+Currently aufs FHSM handles the regular files only. Additionally they
2236+must not be hard-linked nor pseudo-linked.
2237+
2238+
2239+o Cowork of aufs and the user-space daemon
2240+ During the userspace daemon established the connection, aufs sends a
2241+ small notification to it whenever aufs writes something into the
2242+ writable branch. But it may cost high since aufs issues statfs(2)
2243+ internally. So user can specify a new option to cache the
2244+ info. Actually the notification is controlled by these factors.
2245+ + the specified cache time.
2246+ + classified as "force" by aufs internally.
2247+ Until the specified time expires, aufs doesn't send the info
2248+ except the forced cases. When aufs decide forcing, the info is always
2249+ notified to userspace.
2250+ For example, the number of free inodes is generally large enough and
2251+ the shortage of it happens rarely. So aufs doesn't force the
2252+ notification when creating a new file, directory and others. This is
2253+ the typical case which aufs doesn't force.
2254+ When aufs writes the actual filedata and the files consumes any of new
2255+ blocks, the aufs forces notifying.
2256+
2257+
2258+o Interfaces in aufs
2259+- New branch attribute.
2260+ + fhsm
2261+ Specifies that the branch is managed by FHSM feature. In other word,
2262+ participant in the FHSM.
2263+ When nofhsm is set to the branch, it will not be the source/target
2264+ branch of the move-down operation. This attribute is set
2265+ independently from coo and moo attributes, and if you want full
2266+ FHSM, you should specify them as well.
2267+- New mount option.
2268+ + fhsm_sec
2269+ Specifies a second to suppress many less important info to be
2270+ notified.
2271+- New ioctl.
2272+ + AUFS_CTL_FHSM_FD
2273+ create a new file descriptor which userspace can read the notification
2274+ (a subset of struct statfs) from aufs.
2275+- Module parameter 'brs'
2276+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not
2277+ be set.
2278+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
2279+ When there are two or more branches with fhsm attributes,
2280+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
2281+ terminates it. As a result of remounting and branch-manipulation, the
2282+ number of branches with fhsm attribute can be one. In this case,
2283+ /sbin/mount.aufs will terminate the user-space daemon.
2284+
2285+
2286+Finally the operation is done as these steps in kernel-space.
2287+- make sure that,
2288+ + no one else is using the file.
2289+ + the file is not hard-linked.
2290+ + the file is not pseudo-linked.
2291+ + the file is a regular file.
2292+ + the parent dir is not opaqued.
2293+- find the target writable branch.
2294+- make sure the file is not whiteout-ed by the upper (than the target)
2295+ branch.
2296+- make the parent dir on the target branch.
2297+- mutex lock the inode on the branch.
2298+- unlink the whiteout on the target branch (if exists).
2299+- lookup and create the whiteout-ed temporary name on the target branch.
2300+- copy the file as the whiteout-ed temporary name on the target branch.
2301+- rename the whiteout-ed temporary name to the original name.
2302+- unlink the file on the source branch.
2303+- maintain the internal pointer array and the external inode number
2304+ table (XINO).
2305+- maintain the timestamps and other attributes of the parent dir and the
2306+ file.
2307+
2308+And of course, in every step, an error may happen. So the operation
2309+should restore the original file state after an error happens.
53392da6
AM
2310diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
2311--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 2312+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2019-03-05 12:13:00.132557473 +0100
b912730e 2313@@ -0,0 +1,72 @@
53392da6 2314+
ba1aed25 2315+# Copyright (C) 2005-2019 Junjiro R. Okajima
53392da6
AM
2316+#
2317+# This program is free software; you can redistribute it and/or modify
2318+# it under the terms of the GNU General Public License as published by
2319+# the Free Software Foundation; either version 2 of the License, or
2320+# (at your option) any later version.
2321+#
2322+# This program is distributed in the hope that it will be useful,
2323+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2324+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2325+# GNU General Public License for more details.
2326+#
2327+# You should have received a copy of the GNU General Public License
523b37e3 2328+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2329+
2330+mmap(2) -- File Memory Mapping
2331+----------------------------------------------------------------------
2332+In aufs, the file-mapped pages are handled by a branch fs directly, no
2333+interaction with aufs. It means aufs_mmap() calls the branch fs's
2334+->mmap().
2335+This approach is simple and good, but there is one problem.
7e9cd9fe 2336+Under /proc, several entries show the mmapped files by its path (with
53392da6
AM
2337+device and inode number), and the printed path will be the path on the
2338+branch fs's instead of virtual aufs's.
2339+This is not a problem in most cases, but some utilities lsof(1) (and its
2340+user) may expect the path on aufs.
2341+
2342+To address this issue, aufs adds a new member called vm_prfile in struct
2343+vm_area_struct (and struct vm_region). The original vm_file points to
2344+the file on the branch fs in order to handle everything correctly as
2345+usual. The new vm_prfile points to a virtual file in aufs, and the
2346+show-functions in procfs refers to vm_prfile if it is set.
2347+Also we need to maintain several other places where touching vm_file
2348+such like
2349+- fork()/clone() copies vma and the reference count of vm_file is
2350+ incremented.
2351+- merging vma maintains the ref count too.
2352+
7e9cd9fe 2353+This is not a good approach. It just fakes the printed path. But it
53392da6
AM
2354+leaves all behaviour around f_mapping unchanged. This is surely an
2355+advantage.
2356+Actually aufs had adopted another complicated approach which calls
2357+generic_file_mmap() and handles struct vm_operations_struct. In this
2358+approach, aufs met a hard problem and I could not solve it without
2359+switching the approach.
b912730e
AM
2360+
2361+There may be one more another approach which is
2362+- bind-mount the branch-root onto the aufs-root internally
2363+- grab the new vfsmount (ie. struct mount)
2364+- lazy-umount the branch-root internally
2365+- in open(2) the aufs-file, open the branch-file with the hidden
2366+ vfsmount (instead of the original branch's vfsmount)
2367+- ideally this "bind-mount and lazy-umount" should be done atomically,
2368+ but it may be possible from userspace by the mount helper.
2369+
2370+Adding the internal hidden vfsmount and using it in opening a file, the
2371+file path under /proc will be printed correctly. This approach looks
2372+smarter, but is not possible I am afraid.
2373+- aufs-root may be bind-mount later. when it happens, another hidden
2374+ vfsmount will be required.
2375+- it is hard to get the chance to bind-mount and lazy-umount
2376+ + in kernel-space, FS can have vfsmount in open(2) via
2377+ file->f_path, and aufs can know its vfsmount. But several locks are
2378+ already acquired, and if aufs tries to bind-mount and lazy-umount
2379+ here, then it may cause a deadlock.
2380+ + in user-space, bind-mount doesn't invoke the mount helper.
2381+- since /proc shows dev and ino, aufs has to give vma these info. it
2382+ means a new member vm_prinode will be necessary. this is essentially
2383+ equivalent to vm_prfile described above.
2384+
2385+I have to give up this "looks-smater" approach.
c1595e42
JR
2386diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
2387--- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 2388+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2019-03-05 12:13:00.132557473 +0100
c1595e42
JR
2389@@ -0,0 +1,96 @@
2390+
ba1aed25 2391+# Copyright (C) 2014-2019 Junjiro R. Okajima
c1595e42
JR
2392+#
2393+# This program is free software; you can redistribute it and/or modify
2394+# it under the terms of the GNU General Public License as published by
2395+# the Free Software Foundation; either version 2 of the License, or
2396+# (at your option) any later version.
2397+#
2398+# This program is distributed in the hope that it will be useful,
2399+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2400+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2401+# GNU General Public License for more details.
2402+#
2403+# You should have received a copy of the GNU General Public License
2404+# along with this program; if not, write to the Free Software
2405+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2406+
2407+
2408+Listing XATTR/EA and getting the value
2409+----------------------------------------------------------------------
2410+For the inode standard attributes (owner, group, timestamps, etc.), aufs
2411+shows the values from the topmost existing file. This behaviour is good
7e9cd9fe 2412+for the non-dir entries since the bahaviour exactly matches the shown
c1595e42
JR
2413+information. But for the directories, aufs considers all the same named
2414+entries on the lower branches. Which means, if one of the lower entry
2415+rejects readdir call, then aufs returns an error even if the topmost
2416+entry allows it. This behaviour is necessary to respect the branch fs's
2417+security, but can make users confused since the user-visible standard
2418+attributes don't match the behaviour.
2419+To address this issue, aufs has a mount option called dirperm1 which
2420+checks the permission for the topmost entry only, and ignores the lower
2421+entry's permission.
2422+
2423+A similar issue can happen around XATTR.
2424+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
7e9cd9fe
AM
2425+always set. Otherwise these very unpleasant situation would happen.
2426+- listxattr(2) may return the duplicated entries.
c1595e42
JR
2427+- users may not be able to remove or reset the XATTR forever,
2428+
2429+
2430+XATTR/EA support in the internal (copy,move)-(up,down)
2431+----------------------------------------------------------------------
7e9cd9fe 2432+Generally the extended attributes of inode are categorized as these.
c1595e42
JR
2433+- "security" for LSM and capability.
2434+- "system" for posix ACL, 'acl' mount option is required for the branch
2435+ fs generally.
2436+- "trusted" for userspace, CAP_SYS_ADMIN is required.
2437+- "user" for userspace, 'user_xattr' mount option is required for the
2438+ branch fs generally.
2439+
2440+Moreover there are some other categories. Aufs handles these rather
2441+unpopular categories as the ordinary ones, ie. there is no special
2442+condition nor exception.
2443+
2444+In copy-up, the support for XATTR on the dst branch may differ from the
2445+src branch. In this case, the copy-up operation will get an error and
7e9cd9fe
AM
2446+the original user operation which triggered the copy-up will fail. It
2447+can happen that even all copy-up will fail.
c1595e42
JR
2448+When both of src and dst branches support XATTR and if an error occurs
2449+during copying XATTR, then the copy-up should fail obviously. That is a
2450+good reason and aufs should return an error to userspace. But when only
7e9cd9fe 2451+the src branch support that XATTR, aufs should not return an error.
c1595e42
JR
2452+For example, the src branch supports ACL but the dst branch doesn't
2453+because the dst branch may natively un-support it or temporary
2454+un-support it due to "noacl" mount option. Of course, the dst branch fs
2455+may NOT return an error even if the XATTR is not supported. It is
2456+totally up to the branch fs.
2457+
2458+Anyway when the aufs internal copy-up gets an error from the dst branch
2459+fs, then aufs tries removing the just copied entry and returns the error
2460+to the userspace. The worst case of this situation will be all copy-up
2461+will fail.
2462+
2463+For the copy-up operation, there two basic approaches.
2464+- copy the specified XATTR only (by category above), and return the
7e9cd9fe 2465+ error unconditionally if it happens.
c1595e42
JR
2466+- copy all XATTR, and ignore the error on the specified category only.
2467+
2468+In order to support XATTR and to implement the correct behaviour, aufs
7e9cd9fe
AM
2469+chooses the latter approach and introduces some new branch attributes,
2470+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
c1595e42 2471+They correspond to the XATTR namespaces (see above). Additionally, to be
7e9cd9fe
AM
2472+convenient, "icex" is also provided which means all "icex*" attributes
2473+are set (here the word "icex" stands for "ignore copy-error on XATTR").
c1595e42
JR
2474+
2475+The meaning of these attributes is to ignore the error from setting
2476+XATTR on that branch.
2477+Note that aufs tries copying all XATTR unconditionally, and ignores the
2478+error from the dst branch according to the specified attributes.
2479+
2480+Some XATTR may have its default value. The default value may come from
2481+the parent dir or the environment. If the default value is set at the
2482+file creating-time, it will be overwritten by copy-up.
2483+Some contradiction may happen I am afraid.
2484+Do we need another attribute to stop copying XATTR? I am unsure. For
2485+now, aufs implements the branch attributes to ignore the error.
53392da6
AM
2486diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
2487--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 2488+++ linux/Documentation/filesystems/aufs/design/07export.txt 2019-03-05 12:13:00.132557473 +0100
523b37e3 2489@@ -0,0 +1,58 @@
53392da6 2490+
ba1aed25 2491+# Copyright (C) 2005-2019 Junjiro R. Okajima
53392da6
AM
2492+#
2493+# This program is free software; you can redistribute it and/or modify
2494+# it under the terms of the GNU General Public License as published by
2495+# the Free Software Foundation; either version 2 of the License, or
2496+# (at your option) any later version.
2497+#
2498+# This program is distributed in the hope that it will be useful,
2499+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2500+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2501+# GNU General Public License for more details.
2502+#
2503+# You should have received a copy of the GNU General Public License
523b37e3 2504+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2505+
2506+Export Aufs via NFS
2507+----------------------------------------------------------------------
2508+Here is an approach.
2509+- like xino/xib, add a new file 'xigen' which stores aufs inode
2510+ generation.
2511+- iget_locked(): initialize aufs inode generation for a new inode, and
2512+ store it in xigen file.
2513+- destroy_inode(): increment aufs inode generation and store it in xigen
2514+ file. it is necessary even if it is not unlinked, because any data of
2515+ inode may be changed by UDBA.
2516+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
2517+ build file handle by
2518+ + branch id (4 bytes)
2519+ + superblock generation (4 bytes)
2520+ + inode number (4 or 8 bytes)
2521+ + parent dir inode number (4 or 8 bytes)
2522+ + inode generation (4 bytes))
2523+ + return value of exportfs_encode_fh() for the parent on a branch (4
2524+ bytes)
2525+ + file handle for a branch (by exportfs_encode_fh())
2526+- fh_to_dentry():
2527+ + find the index of a branch from its id in handle, and check it is
2528+ still exist in aufs.
2529+ + 1st level: get the inode number from handle and search it in cache.
7e9cd9fe
AM
2530+ + 2nd level: if not found in cache, get the parent inode number from
2531+ the handle and search it in cache. and then open the found parent
2532+ dir, find the matching inode number by vfs_readdir() and get its
2533+ name, and call lookup_one_len() for the target dentry.
53392da6
AM
2534+ + 3rd level: if the parent dir is not cached, call
2535+ exportfs_decode_fh() for a branch and get the parent on a branch,
2536+ build a pathname of it, convert it a pathname in aufs, call
2537+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
2538+ the 2nd level.
2539+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
2540+ for every branch, but not itself. to get this, (currently) aufs
2541+ searches in current->nsproxy->mnt_ns list. it may not be a good
2542+ idea, but I didn't get other approach.
2543+ + test the generation of the gotten inode.
2544+- every inode operation: they may get EBUSY due to UDBA. in this case,
2545+ convert it into ESTALE for NFSD.
2546+- readdir(): call lockdep_on/off() because filldir in NFSD calls
2547+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
2548diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
2549--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 2550+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2019-03-05 12:13:00.135890907 +0100
523b37e3 2551@@ -0,0 +1,52 @@
53392da6 2552+
ba1aed25 2553+# Copyright (C) 2005-2019 Junjiro R. Okajima
53392da6
AM
2554+#
2555+# This program is free software; you can redistribute it and/or modify
2556+# it under the terms of the GNU General Public License as published by
2557+# the Free Software Foundation; either version 2 of the License, or
2558+# (at your option) any later version.
2559+#
2560+# This program is distributed in the hope that it will be useful,
2561+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2562+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2563+# GNU General Public License for more details.
2564+#
2565+# You should have received a copy of the GNU General Public License
523b37e3 2566+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2567+
2568+Show Whiteout Mode (shwh)
2569+----------------------------------------------------------------------
2570+Generally aufs hides the name of whiteouts. But in some cases, to show
2571+them is very useful for users. For instance, creating a new middle layer
2572+(branch) by merging existing layers.
2573+
2574+(borrowing aufs1 HOW-TO from a user, Michael Towers)
2575+When you have three branches,
2576+- Bottom: 'system', squashfs (underlying base system), read-only
2577+- Middle: 'mods', squashfs, read-only
2578+- Top: 'overlay', ram (tmpfs), read-write
2579+
2580+The top layer is loaded at boot time and saved at shutdown, to preserve
2581+the changes made to the system during the session.
2582+When larger changes have been made, or smaller changes have accumulated,
2583+the size of the saved top layer data grows. At this point, it would be
2584+nice to be able to merge the two overlay branches ('mods' and 'overlay')
2585+and rewrite the 'mods' squashfs, clearing the top layer and thus
2586+restoring save and load speed.
2587+
2588+This merging is simplified by the use of another aufs mount, of just the
2589+two overlay branches using the 'shwh' option.
2590+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
2591+ aufs /livesys/merge_union
2592+
2593+A merged view of these two branches is then available at
2594+/livesys/merge_union, and the new feature is that the whiteouts are
2595+visible!
2596+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
2597+writing to all branches. Also the default mode for all branches is 'ro'.
2598+It is now possible to save the combined contents of the two overlay
2599+branches to a new squashfs, e.g.:
2600+# mksquashfs /livesys/merge_union /path/to/newmods.squash
2601+
2602+This new squashfs archive can be stored on the boot device and the
2603+initramfs will use it to replace the old one at the next boot.
2604diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
2605--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
ba1aed25 2606+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2019-03-05 12:13:00.135890907 +0100
7e9cd9fe 2607@@ -0,0 +1,47 @@
53392da6 2608+
ba1aed25 2609+# Copyright (C) 2010-2019 Junjiro R. Okajima
53392da6
AM
2610+#
2611+# This program is free software; you can redistribute it and/or modify
2612+# it under the terms of the GNU General Public License as published by
2613+# the Free Software Foundation; either version 2 of the License, or
2614+# (at your option) any later version.
2615+#
2616+# This program is distributed in the hope that it will be useful,
2617+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2618+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2619+# GNU General Public License for more details.
2620+#
2621+# You should have received a copy of the GNU General Public License
523b37e3 2622+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2623+
2624+Dynamically customizable FS operations
2625+----------------------------------------------------------------------
2626+Generally FS operations (struct inode_operations, struct
2627+address_space_operations, struct file_operations, etc.) are defined as
2628+"static const", but it never means that FS have only one set of
2629+operation. Some FS have multiple sets of them. For instance, ext2 has
2630+three sets, one for XIP, for NOBH, and for normal.
2631+Since aufs overrides and redirects these operations, sometimes aufs has
7e9cd9fe 2632+to change its behaviour according to the branch FS type. More importantly
53392da6
AM
2633+VFS acts differently if a function (member in the struct) is set or
2634+not. It means aufs should have several sets of operations and select one
2635+among them according to the branch FS definition.
2636+
7e9cd9fe 2637+In order to solve this problem and not to affect the behaviour of VFS,
53392da6 2638+aufs defines these operations dynamically. For instance, aufs defines
7e9cd9fe
AM
2639+dummy direct_IO function for struct address_space_operations, but it may
2640+not be set to the address_space_operations actually. When the branch FS
2641+doesn't have it, aufs doesn't set it to its address_space_operations
2642+while the function definition itself is still alive. So the behaviour
2643+itself will not change, and it will return an error when direct_IO is
2644+not set.
53392da6
AM
2645+
2646+The lifetime of these dynamically generated operation object is
2647+maintained by aufs branch object. When the branch is removed from aufs,
2648+the reference counter of the object is decremented. When it reaches
2649+zero, the dynamically generated operation object will be freed.
2650+
7e9cd9fe
AM
2651+This approach is designed to support AIO (io_submit), Direct I/O and
2652+XIP (DAX) mainly.
2653+Currently this approach is applied to address_space_operations for
2654+regular files only.
53392da6
AM
2655diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
2656--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
9f237c51
AM
2657+++ linux/Documentation/filesystems/aufs/README 2018-12-27 13:19:17.705082621 +0100
2658@@ -0,0 +1,395 @@
53392da6 2659+
5527c038 2660+Aufs4 -- advanced multi layered unification filesystem version 4.x
53392da6
AM
2661+http://aufs.sf.net
2662+Junjiro R. Okajima
2663+
2664+
2665+0. Introduction
2666+----------------------------------------
2667+In the early days, aufs was entirely re-designed and re-implemented
7e9cd9fe 2668+Unionfs Version 1.x series. Adding many original ideas, approaches,
53392da6
AM
2669+improvements and implementations, it becomes totally different from
2670+Unionfs while keeping the basic features.
2671+Recently, Unionfs Version 2.x series begin taking some of the same
2672+approaches to aufs1's.
2673+Unionfs is being developed by Professor Erez Zadok at Stony Brook
2674+University and his team.
2675+
5527c038 2676+Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3.
53392da6
AM
2677+If you want older kernel version support, try aufs2-2.6.git or
2678+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
2679+
2680+Note: it becomes clear that "Aufs was rejected. Let's give it up."
38d290e6
JR
2681+ According to Christoph Hellwig, linux rejects all union-type
2682+ filesystems but UnionMount.
53392da6
AM
2683+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
2684+
38d290e6
JR
2685+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
2686+ UnionMount, and he pointed out an issue around a directory mutex
2687+ lock and aufs addressed it. But it is still unsure whether aufs will
2688+ be merged (or any other union solution).
076b876e 2689+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
38d290e6 2690+
53392da6
AM
2691+
2692+1. Features
2693+----------------------------------------
2694+- unite several directories into a single virtual filesystem. The member
2695+ directory is called as a branch.
2696+- you can specify the permission flags to the branch, which are 'readonly',
2697+ 'readwrite' and 'whiteout-able.'
2698+- by upper writable branch, internal copyup and whiteout, files/dirs on
2699+ readonly branch are modifiable logically.
2700+- dynamic branch manipulation, add, del.
2701+- etc...
2702+
7e9cd9fe
AM
2703+Also there are many enhancements in aufs, such as:
2704+- test only the highest one for the directory permission (dirperm1)
2705+- copyup on open (coo=)
2706+- 'move' policy for copy-up between two writable branches, after
2707+ checking free space.
2708+- xattr, acl
53392da6
AM
2709+- readdir(3) in userspace.
2710+- keep inode number by external inode number table
2711+- keep the timestamps of file/dir in internal copyup operation
2712+- seekable directory, supporting NFS readdir.
2713+- whiteout is hardlinked in order to reduce the consumption of inodes
2714+ on branch
2715+- do not copyup, nor create a whiteout when it is unnecessary
2716+- revert a single systemcall when an error occurs in aufs
2717+- remount interface instead of ioctl
2718+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
2719+- loopback mounted filesystem as a branch
2720+- kernel thread for removing the dir who has a plenty of whiteouts
2721+- support copyup sparse file (a file which has a 'hole' in it)
2722+- default permission flags for branches
2723+- selectable permission flags for ro branch, whether whiteout can
2724+ exist or not
2725+- export via NFS.
2726+- support <sysfs>/fs/aufs and <debugfs>/aufs.
2727+- support multiple writable branches, some policies to select one
2728+ among multiple writable branches.
2729+- a new semantics for link(2) and rename(2) to support multiple
2730+ writable branches.
2731+- no glibc changes are required.
2732+- pseudo hardlink (hardlink over branches)
2733+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
2734+ including NFS or remote filesystem branch.
2735+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
2736+- and more...
2737+
5527c038 2738+Currently these features are dropped temporary from aufs4.
53392da6 2739+See design/08plan.txt in detail.
53392da6
AM
2740+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
2741+ (robr)
2742+- statistics of aufs thread (/sys/fs/aufs/stat)
53392da6
AM
2743+
2744+Features or just an idea in the future (see also design/*.txt),
2745+- reorder the branch index without del/re-add.
2746+- permanent xino files for NFSD
2747+- an option for refreshing the opened files after add/del branches
53392da6
AM
2748+- light version, without branch manipulation. (unnecessary?)
2749+- copyup in userspace
2750+- inotify in userspace
2751+- readv/writev
53392da6
AM
2752+
2753+
2754+2. Download
2755+----------------------------------------
5527c038
JR
2756+There are three GIT trees for aufs4, aufs4-linux.git,
2757+aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in
1e00d052 2758+"aufs-util.git."
5527c038
JR
2759+While the aufs-util is always necessary, you need either of aufs4-linux
2760+or aufs4-standalone.
1e00d052 2761+
5527c038 2762+The aufs4-linux tree includes the whole linux mainline GIT tree,
1e00d052
AM
2763+git://git.kernel.org/.../torvalds/linux.git.
2764+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
5527c038 2765+build aufs4 as an external kernel module.
2000de60 2766+Several extra patches are not included in this tree. Only
be52b249 2767+aufs4-standalone tree contains them. They are described in the later
2000de60 2768+section "Configuration and Compilation."
1e00d052 2769+
5527c038 2770+On the other hand, the aufs4-standalone tree has only aufs source files
53392da6 2771+and necessary patches, and you can select CONFIG_AUFS_FS=m.
2000de60 2772+But you need to apply all aufs patches manually.
53392da6 2773+
5527c038
JR
2774+You will find GIT branches whose name is in form of "aufs4.x" where "x"
2775+represents the linux kernel version, "linux-4.x". For instance,
2776+"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use
2777+"aufs4.x-rcN" branch.
1e00d052 2778+
5527c038 2779+o aufs4-linux tree
1e00d052 2780+$ git clone --reference /your/linux/git/tree \
5527c038 2781+ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git
1e00d052 2782+- if you don't have linux GIT tree, then remove "--reference ..."
5527c038
JR
2783+$ cd aufs4-linux.git
2784+$ git checkout origin/aufs4.0
53392da6 2785+
2000de60
JR
2786+Or You may want to directly git-pull aufs into your linux GIT tree, and
2787+leave the patch-work to GIT.
2788+$ cd /your/linux/git/tree
5527c038
JR
2789+$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git
2790+$ git fetch aufs4
2791+$ git checkout -b my4.0 v4.0
2792+$ (add your local change...)
2793+$ git pull aufs4 aufs4.0
2794+- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch.
2000de60 2795+- you may need to solve some conflicts between your_changes and
5527c038
JR
2796+ aufs4.0. in this case, git-rerere is recommended so that you can
2797+ solve the similar conflicts automatically when you upgrade to 4.1 or
2000de60
JR
2798+ later in the future.
2799+
5527c038
JR
2800+o aufs4-standalone tree
2801+$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git
2802+$ cd aufs4-standalone.git
2803+$ git checkout origin/aufs4.0
53392da6
AM
2804+
2805+o aufs-util tree
5527c038
JR
2806+$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git
2807+- note that the public aufs-util.git is on SourceForge instead of
2808+ GitHUB.
53392da6 2809+$ cd aufs-util.git
5527c038 2810+$ git checkout origin/aufs4.0
53392da6 2811+
5527c038
JR
2812+Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY.
2813+The minor version number, 'x' in '4.x', of aufs may not always
9dbd164d
AM
2814+follow the minor version number of the kernel.
2815+Because changes in the kernel that cause the use of a new
2816+minor version number do not always require changes to aufs-util.
2817+
2818+Since aufs-util has its own minor version number, you may not be
2819+able to find a GIT branch in aufs-util for your kernel's
2820+exact minor version number.
2821+In this case, you should git-checkout the branch for the
53392da6 2822+nearest lower number.
9dbd164d
AM
2823+
2824+For (an unreleased) example:
5527c038
JR
2825+If you are using "linux-4.10" and the "aufs4.10" branch
2826+does not exist in aufs-util repository, then "aufs4.9", "aufs4.8"
9dbd164d
AM
2827+or something numerically smaller is the branch for your kernel.
2828+
53392da6
AM
2829+Also you can view all branches by
2830+ $ git branch -a
2831+
2832+
2833+3. Configuration and Compilation
2834+----------------------------------------
2835+Make sure you have git-checkout'ed the correct branch.
2836+
5527c038 2837+For aufs4-linux tree,
c06a8ce3 2838+- enable CONFIG_AUFS_FS.
1e00d052
AM
2839+- set other aufs configurations if necessary.
2840+
5527c038 2841+For aufs4-standalone tree,
53392da6
AM
2842+There are several ways to build.
2843+
2844+1.
5527c038
JR
2845+- apply ./aufs4-kbuild.patch to your kernel source files.
2846+- apply ./aufs4-base.patch too.
2847+- apply ./aufs4-mmap.patch too.
2848+- apply ./aufs4-standalone.patch too, if you have a plan to set
2849+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch.
537831f9
AM
2850+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2851+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 2852+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
2853+ =m or =y.
2854+- and build your kernel as usual.
2855+- install the built kernel.
c06a8ce3
AM
2856+ Note: Since linux-3.9, every filesystem module requires an alias
2857+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2858+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
2859+- install the header files too by "make headers_install" to the
2860+ directory where you specify. By default, it is $PWD/usr.
b4510431 2861+ "make help" shows a brief note for headers_install.
53392da6
AM
2862+- and reboot your system.
2863+
2864+2.
2865+- module only (CONFIG_AUFS_FS=m).
5527c038
JR
2866+- apply ./aufs4-base.patch to your kernel source files.
2867+- apply ./aufs4-mmap.patch too.
2868+- apply ./aufs4-standalone.patch too.
53392da6
AM
2869+- build your kernel, don't forget "make headers_install", and reboot.
2870+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 2871+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
2872+ every aufs configurations.
2873+- build the module by simple "make".
c06a8ce3
AM
2874+ Note: Since linux-3.9, every filesystem module requires an alias
2875+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2876+ modules.aliases file.
53392da6
AM
2877+- you can specify ${KDIR} make variable which points to your kernel
2878+ source tree.
2879+- install the files
2880+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
2881+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2882+ + run "make install_headers" (instead of headers_install) to install
2883+ the modified aufs header file (you can specify DESTDIR which is
2884+ available in aufs standalone version's Makefile only), or copy
2885+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2886+ you like manually. By default, the target directory is $PWD/usr.
5527c038 2887+- no need to apply aufs4-kbuild.patch, nor copying source files to your
53392da6
AM
2888+ kernel source tree.
2889+
b4510431 2890+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
2891+ as well as "make headers_install" in the kernel source tree.
2892+ headers_install is subject to be forgotten, but it is essentially
2893+ necessary, not only for building aufs-util.
2894+ You may not meet problems without headers_install in some older
2895+ version though.
2896+
2897+And then,
2898+- read README in aufs-util, build and install it
9dbd164d
AM
2899+- note that your distribution may contain an obsoleted version of
2900+ aufs_type.h in /usr/include/linux or something. When you build aufs
2901+ utilities, make sure that your compiler refers the correct aufs header
2902+ file which is built by "make headers_install."
53392da6
AM
2903+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2904+ then run "make install_ulib" too. And refer to the aufs manual in
2905+ detail.
2906+
5527c038 2907+There several other patches in aufs4-standalone.git. They are all
38d290e6 2908+optional. When you meet some problems, they will help you.
5527c038 2909+- aufs4-loopback.patch
38d290e6
JR
2910+ Supports a nested loopback mount in a branch-fs. This patch is
2911+ unnecessary until aufs produces a message like "you may want to try
2912+ another patch for loopback file".
2913+- vfs-ino.patch
2914+ Modifies a system global kernel internal function get_next_ino() in
2915+ order to stop assigning 0 for an inode-number. Not directly related to
2916+ aufs, but recommended generally.
2917+- tmpfs-idr.patch
2918+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
2919+ the size of aufs XINO files for tmpfs branch. Also it prevents the
2920+ duplication of inode number, which is important for backup tools and
2921+ other utilities. When you find aufs XINO files for tmpfs branch
2922+ growing too much, try this patch.
be52b249
AM
2923+- lockdep-debug.patch
2924+ Because aufs is not only an ordinary filesystem (callee of VFS), but
2925+ also a caller of VFS functions for branch filesystems, subclassing of
2926+ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging
2927+ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will
2928+ need to apply this debug patch to expand several constant values.
2929+ If don't know what LOCKDEP, then you don't have apply this patch.
38d290e6 2930+
53392da6
AM
2931+
2932+4. Usage
2933+----------------------------------------
2934+At first, make sure aufs-util are installed, and please read the aufs
2935+manual, aufs.5 in aufs-util.git tree.
2936+$ man -l aufs.5
2937+
2938+And then,
2939+$ mkdir /tmp/rw /tmp/aufs
2940+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2941+
2942+Here is another example. The result is equivalent.
2943+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2944+ Or
2945+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2946+# mount -o remount,append:${HOME} /tmp/aufs
2947+
2948+Then, you can see whole tree of your home dir through /tmp/aufs. If
2949+you modify a file under /tmp/aufs, the one on your home directory is
2950+not affected, instead the same named file will be newly created under
2951+/tmp/rw. And all of your modification to a file will be applied to
2952+the one under /tmp/rw. This is called the file based Copy on Write
2953+(COW) method.
2954+Aufs mount options are described in aufs.5.
2955+If you run chroot or something and make your aufs as a root directory,
2956+then you need to customize the shutdown script. See the aufs manual in
2957+detail.
2958+
2959+Additionally, there are some sample usages of aufs which are a
2960+diskless system with network booting, and LiveCD over NFS.
2961+See sample dir in CVS tree on SourceForge.
2962+
2963+
2964+5. Contact
2965+----------------------------------------
2966+When you have any problems or strange behaviour in aufs, please let me
2967+know with:
2968+- /proc/mounts (instead of the output of mount(8))
2969+- /sys/module/aufs/*
2970+- /sys/fs/aufs/* (if you have them)
2971+- /debug/aufs/* (if you have them)
2972+- linux kernel version
2973+ if your kernel is not plain, for example modified by distributor,
2974+ the url where i can download its source is necessary too.
2975+- aufs version which was printed at loading the module or booting the
2976+ system, instead of the date you downloaded.
2977+- configuration (define/undefine CONFIG_AUFS_xxx)
2978+- kernel configuration or /proc/config.gz (if you have it)
2979+- behaviour which you think to be incorrect
2980+- actual operation, reproducible one is better
2981+- mailto: aufs-users at lists.sourceforge.net
2982+
2983+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2984+and Feature Requests) on SourceForge. Please join and write to
2985+aufs-users ML.
2986+
2987+
2988+6. Acknowledgements
2989+----------------------------------------
2990+Thanks to everyone who have tried and are using aufs, whoever
2991+have reported a bug or any feedback.
2992+
2993+Especially donators:
2994+Tomas Matejicek(slax.org) made a donation (much more than once).
2995+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2996+ scripts) is making "doubling" donations.
2997+ Unfortunately I cannot list all of the donators, but I really
b4510431 2998+ appreciate.
53392da6
AM
2999+ It ends Aug 2010, but the ordinary donation URL is still available.
3000+ <http://sourceforge.net/donate/index.php?group_id=167503>
3001+Dai Itasaka made a donation (2007/8).
3002+Chuck Smith made a donation (2008/4, 10 and 12).
3003+Henk Schoneveld made a donation (2008/9).
3004+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
3005+Francois Dupoux made a donation (2008/11).
3006+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
3007+ aufs2 GIT tree (2009/2).
3008+William Grant made a donation (2009/3).
3009+Patrick Lane made a donation (2009/4).
3010+The Mail Archive (mail-archive.com) made donations (2009/5).
3011+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
3012+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
3013+Pavel Pronskiy made a donation (2011/2).
3014+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
3015+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
3016+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
3017+11).
1e00d052 3018+Sam Liddicott made a donation (2011/9).
86dc4139
AM
3019+Era Scarecrow made a donation (2013/4).
3020+Bor Ratajc made a donation (2013/4).
3021+Alessandro Gorreta made a donation (2013/4).
3022+POIRETTE Marc made a donation (2013/4).
3023+Alessandro Gorreta made a donation (2013/4).
3024+lauri kasvandik made a donation (2013/5).
392086de 3025+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
3026+The Parted Magic Project made a donation (2013/9 and 11).
3027+Pavel Barta made a donation (2013/10).
38d290e6 3028+Nikolay Pertsev made a donation (2014/5).
c2c0f25c 3029+James B made a donation (2014/7 and 2015/7).
076b876e 3030+Stefano Di Biase made a donation (2014/8).
2000de60 3031+Daniel Epellei made a donation (2015/1).
c4adf169 3032+OmegaPhil made a donation (2016/1, 2018/4).
5afbbe0d 3033+Tomasz Szewczyk made a donation (2016/4).
f2c43d5f 3034+James Burry made a donation (2016/12).
acd2b654 3035+Carsten Rose made a donation (2018/9).
9f237c51 3036+Porteus Kiosk made a donation (2018/10).
53392da6
AM
3037+
3038+Thank you very much.
3039+Donations are always, including future donations, very important and
3040+helpful for me to keep on developing aufs.
3041+
3042+
3043+7.
3044+----------------------------------------
3045+If you are an experienced user, no explanation is needed. Aufs is
3046+just a linux filesystem.
3047+
3048+
3049+Enjoy!
3050+
3051+# Local variables: ;
3052+# mode: text;
3053+# End: ;
7f207e10
AM
3054diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
3055--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 3056+++ linux/fs/aufs/aufs.h 2019-03-05 12:13:00.135890907 +0100
acd2b654 3057@@ -0,0 +1,62 @@
062440b3 3058+/* SPDX-License-Identifier: GPL-2.0 */
7f207e10 3059+/*
ba1aed25 3060+ * Copyright (C) 2005-2019 Junjiro R. Okajima
7f207e10
AM
3061+ *
3062+ * This program, aufs is free software; you can redistribute it and/or modify
3063+ * it under the terms of the GNU General Public License as published by
3064+ * the Free Software Foundation; either version 2 of the License, or
3065+ * (at your option) any later version.
3066+ *
3067+ * This program is distributed in the hope that it will be useful,
3068+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3069+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3070+ * GNU General Public License for more details.
3071+ *
3072+ * You should have received a copy of the GNU General Public License
523b37e3 3073+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
3074+ */
3075+
3076+/*
3077+ * all header files
3078+ */
3079+
3080+#ifndef __AUFS_H__
3081+#define __AUFS_H__
3082+
3083+#ifdef __KERNEL__
3084+
3085+#define AuStub(type, name, body, ...) \
3086+ static inline type name(__VA_ARGS__) { body; }
3087+
3088+#define AuStubVoid(name, ...) \
3089+ AuStub(void, name, , __VA_ARGS__)
3090+#define AuStubInt0(name, ...) \
3091+ AuStub(int, name, return 0, __VA_ARGS__)
3092+
3093+#include "debug.h"
3094+
3095+#include "branch.h"
3096+#include "cpup.h"
3097+#include "dcsub.h"
3098+#include "dbgaufs.h"
3099+#include "dentry.h"
3100+#include "dir.h"
8b6a4947 3101+#include "dirren.h"
7f207e10
AM
3102+#include "dynop.h"
3103+#include "file.h"
3104+#include "fstype.h"
8b6a4947 3105+#include "hbl.h"
7f207e10 3106+#include "inode.h"
acd2b654 3107+#include "lcnt.h"
7f207e10
AM
3108+#include "loop.h"
3109+#include "module.h"
7f207e10
AM
3110+#include "opts.h"
3111+#include "rwsem.h"
7f207e10
AM
3112+#include "super.h"
3113+#include "sysaufs.h"
3114+#include "vfsub.h"
3115+#include "whout.h"
3116+#include "wkq.h"
3117+
3118+#endif /* __KERNEL__ */
3119+#endif /* __AUFS_H__ */
3120diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
3121--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25
AM
3122+++ linux/fs/aufs/branch.c 2019-03-05 12:13:00.135890907 +0100
3123@@ -0,0 +1,1423 @@
cd7a4cd9 3124+// SPDX-License-Identifier: GPL-2.0
7f207e10 3125+/*
ba1aed25 3126+ * Copyright (C) 2005-2019 Junjiro R. Okajima
7f207e10
AM
3127+ *
3128+ * This program, aufs is free software; you can redistribute it and/or modify
3129+ * it under the terms of the GNU General Public License as published by
3130+ * the Free Software Foundation; either version 2 of the License, or
3131+ * (at your option) any later version.
3132+ *
3133+ * This program is distributed in the hope that it will be useful,
3134+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3135+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3136+ * GNU General Public License for more details.
3137+ *
3138+ * You should have received a copy of the GNU General Public License
523b37e3 3139+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
3140+ */
3141+
3142+/*
3143+ * branch management
3144+ */
3145+
027c5e7a 3146+#include <linux/compat.h>
7f207e10
AM
3147+#include <linux/statfs.h>
3148+#include "aufs.h"
3149+
3150+/*
3151+ * free a single branch
1facf9fc 3152+ */
3153+static void au_br_do_free(struct au_branch *br)
3154+{
3155+ int i;
3156+ struct au_wbr *wbr;
4a4d8108 3157+ struct au_dykey **key;
1facf9fc 3158+
027c5e7a 3159+ au_hnotify_fin_br(br);
8b6a4947
AM
3160+ /* always, regardless the mount option */
3161+ au_dr_hino_free(&br->br_dirren);
062440b3 3162+ au_xino_put(br);
1facf9fc 3163+
acd2b654
AM
3164+ AuLCntZero(au_lcnt_read(&br->br_nfiles, /*do_rev*/0));
3165+ au_lcnt_fin(&br->br_nfiles, /*do_sync*/0);
3166+ AuLCntZero(au_lcnt_read(&br->br_count, /*do_rev*/0));
3167+ au_lcnt_fin(&br->br_count, /*do_sync*/0);
1facf9fc 3168+
3169+ wbr = br->br_wbr;
3170+ if (wbr) {
3171+ for (i = 0; i < AuBrWh_Last; i++)
3172+ dput(wbr->wbr_wh[i]);
3173+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 3174+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 3175+ }
3176+
076b876e
AM
3177+ if (br->br_fhsm) {
3178+ au_br_fhsm_fin(br->br_fhsm);
9f237c51 3179+ au_kfree_try_rcu(br->br_fhsm);
076b876e
AM
3180+ }
3181+
4a4d8108
AM
3182+ key = br->br_dykey;
3183+ for (i = 0; i < AuBrDynOp; i++, key++)
3184+ if (*key)
3185+ au_dy_put(*key);
3186+ else
3187+ break;
3188+
537831f9 3189+ /* recursive lock, s_umount of branch's */
acd2b654 3190+ /* synchronize_rcu(); */ /* why? */
537831f9 3191+ lockdep_off();
86dc4139 3192+ path_put(&br->br_path);
537831f9 3193+ lockdep_on();
9f237c51 3194+ au_kfree_rcu(wbr);
acd2b654
AM
3195+ au_lcnt_wait_for_fin(&br->br_nfiles);
3196+ au_lcnt_wait_for_fin(&br->br_count);
3197+ /* I don't know why, but percpu_refcount requires this */
3198+ /* synchronize_rcu(); */
9f237c51 3199+ au_kfree_rcu(br);
1facf9fc 3200+}
3201+
3202+/*
3203+ * frees all branches
3204+ */
3205+void au_br_free(struct au_sbinfo *sbinfo)
3206+{
3207+ aufs_bindex_t bmax;
3208+ struct au_branch **br;
3209+
dece6358
AM
3210+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3211+
5afbbe0d 3212+ bmax = sbinfo->si_bbot + 1;
1facf9fc 3213+ br = sbinfo->si_branch;
3214+ while (bmax--)
3215+ au_br_do_free(*br++);
3216+}
3217+
3218+/*
3219+ * find the index of a branch which is specified by @br_id.
3220+ */
3221+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
3222+{
5afbbe0d 3223+ aufs_bindex_t bindex, bbot;
1facf9fc 3224+
5afbbe0d
AM
3225+ bbot = au_sbbot(sb);
3226+ for (bindex = 0; bindex <= bbot; bindex++)
1facf9fc 3227+ if (au_sbr_id(sb, bindex) == br_id)
3228+ return bindex;
3229+ return -1;
3230+}
3231+
3232+/* ---------------------------------------------------------------------- */
3233+
3234+/*
3235+ * add a branch
3236+ */
3237+
b752ccd1
AM
3238+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
3239+ struct dentry *h_root)
1facf9fc 3240+{
b752ccd1
AM
3241+ if (unlikely(h_adding == h_root
3242+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 3243+ return 1;
b752ccd1
AM
3244+ if (h_adding->d_sb != h_root->d_sb)
3245+ return 0;
3246+ return au_test_subdir(h_adding, h_root)
3247+ || au_test_subdir(h_root, h_adding);
1facf9fc 3248+}
3249+
3250+/*
3251+ * returns a newly allocated branch. @new_nbranch is a number of branches
3252+ * after adding a branch.
3253+ */
3254+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
3255+ int perm)
3256+{
3257+ struct au_branch *add_branch;
3258+ struct dentry *root;
5527c038 3259+ struct inode *inode;
4a4d8108 3260+ int err;
1facf9fc 3261+
4a4d8108 3262+ err = -ENOMEM;
be52b249 3263+ add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS);
1facf9fc 3264+ if (unlikely(!add_branch))
3265+ goto out;
acd2b654 3266+ add_branch->br_xino = au_xino_alloc(/*nfile*/1);
062440b3 3267+ if (unlikely(!add_branch->br_xino))
521ced18 3268+ goto out_br;
027c5e7a
AM
3269+ err = au_hnotify_init_br(add_branch, perm);
3270+ if (unlikely(err))
062440b3 3271+ goto out_xino;
027c5e7a 3272+
1facf9fc 3273+ if (au_br_writable(perm)) {
3274+ /* may be freed separately at changing the branch permission */
be52b249 3275+ add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr),
1facf9fc 3276+ GFP_NOFS);
3277+ if (unlikely(!add_branch->br_wbr))
027c5e7a 3278+ goto out_hnotify;
1facf9fc 3279+ }
3280+
076b876e
AM
3281+ if (au_br_fhsm(perm)) {
3282+ err = au_fhsm_br_alloc(add_branch);
3283+ if (unlikely(err))
3284+ goto out_wbr;
3285+ }
3286+
521ced18 3287+ root = sb->s_root;
e2f27e51 3288+ err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0);
4a4d8108 3289+ if (!err)
e2f27e51 3290+ err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0);
5527c038
JR
3291+ if (!err) {
3292+ inode = d_inode(root);
1c60b727
AM
3293+ err = au_hinode_realloc(au_ii(inode), new_nbranch,
3294+ /*may_shrink*/0);
5527c038 3295+ }
4a4d8108
AM
3296+ if (!err)
3297+ return add_branch; /* success */
1facf9fc 3298+
076b876e 3299+out_wbr:
9f237c51 3300+ au_kfree_rcu(add_branch->br_wbr);
027c5e7a
AM
3301+out_hnotify:
3302+ au_hnotify_fin_br(add_branch);
062440b3
AM
3303+out_xino:
3304+ au_xino_put(add_branch);
4f0767ce 3305+out_br:
9f237c51 3306+ au_kfree_rcu(add_branch);
4f0767ce 3307+out:
4a4d8108 3308+ return ERR_PTR(err);
1facf9fc 3309+}
3310+
3311+/*
3312+ * test if the branch permission is legal or not.
3313+ */
3314+static int test_br(struct inode *inode, int brperm, char *path)
3315+{
3316+ int err;
3317+
4a4d8108
AM
3318+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
3319+ if (!err)
3320+ goto out;
1facf9fc 3321+
4a4d8108
AM
3322+ err = -EINVAL;
3323+ pr_err("write permission for readonly mount or inode, %s\n", path);
3324+
4f0767ce 3325+out:
1facf9fc 3326+ return err;
3327+}
3328+
3329+/*
3330+ * returns:
3331+ * 0: success, the caller will add it
3332+ * plus: success, it is already unified, the caller should ignore it
3333+ * minus: error
3334+ */
3335+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
3336+{
3337+ int err;
5afbbe0d 3338+ aufs_bindex_t bbot, bindex;
5527c038 3339+ struct dentry *root, *h_dentry;
1facf9fc 3340+ struct inode *inode, *h_inode;
3341+
3342+ root = sb->s_root;
5afbbe0d
AM
3343+ bbot = au_sbbot(sb);
3344+ if (unlikely(bbot >= 0
1facf9fc 3345+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
3346+ err = 1;
3347+ if (!remount) {
3348+ err = -EINVAL;
4a4d8108 3349+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 3350+ }
3351+ goto out;
3352+ }
3353+
3354+ err = -ENOSPC; /* -E2BIG; */
3355+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
5afbbe0d 3356+ || AUFS_BRANCH_MAX - 1 <= bbot)) {
4a4d8108 3357+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 3358+ goto out;
3359+ }
3360+
3361+ err = -EDOM;
5afbbe0d 3362+ if (unlikely(add->bindex < 0 || bbot + 1 < add->bindex)) {
4a4d8108 3363+ pr_err("bad index %d\n", add->bindex);
1facf9fc 3364+ goto out;
3365+ }
3366+
5527c038 3367+ inode = d_inode(add->path.dentry);
1facf9fc 3368+ err = -ENOENT;
3369+ if (unlikely(!inode->i_nlink)) {
4a4d8108 3370+ pr_err("no existence %s\n", add->pathname);
1facf9fc 3371+ goto out;
3372+ }
3373+
3374+ err = -EINVAL;
3375+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 3376+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 3377+ goto out;
3378+ }
3379+
3380+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
3381+ pr_err("unsupported filesystem, %s (%s)\n",
3382+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 3383+ goto out;
3384+ }
3385+
c1595e42
JR
3386+ if (unlikely(inode->i_sb->s_stack_depth)) {
3387+ pr_err("already stacked, %s (%s)\n",
3388+ add->pathname, au_sbtype(inode->i_sb));
3389+ goto out;
3390+ }
3391+
5527c038 3392+ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname);
1facf9fc 3393+ if (unlikely(err))
3394+ goto out;
3395+
5afbbe0d 3396+ if (bbot < 0)
1facf9fc 3397+ return 0; /* success */
3398+
3399+ err = -EINVAL;
5afbbe0d 3400+ for (bindex = 0; bindex <= bbot; bindex++)
1facf9fc 3401+ if (unlikely(test_overlap(sb, add->path.dentry,
3402+ au_h_dptr(root, bindex)))) {
4a4d8108 3403+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 3404+ goto out;
3405+ }
3406+
3407+ err = 0;
3408+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
5527c038
JR
3409+ h_dentry = au_h_dptr(root, 0);
3410+ h_inode = d_inode(h_dentry);
1facf9fc 3411+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
3412+ || !uid_eq(h_inode->i_uid, inode->i_uid)
3413+ || !gid_eq(h_inode->i_gid, inode->i_gid))
3414+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
3415+ add->pathname,
3416+ i_uid_read(inode), i_gid_read(inode),
3417+ (inode->i_mode & S_IALLUGO),
3418+ i_uid_read(h_inode), i_gid_read(h_inode),
3419+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 3420+ }
3421+
4f0767ce 3422+out:
1facf9fc 3423+ return err;
3424+}
3425+
3426+/*
3427+ * initialize or clean the whiteouts for an adding branch
3428+ */
3429+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 3430+ int new_perm)
1facf9fc 3431+{
3432+ int err, old_perm;
3433+ aufs_bindex_t bindex;
febd17d6 3434+ struct inode *h_inode;
1facf9fc 3435+ struct au_wbr *wbr;
3436+ struct au_hinode *hdir;
5527c038 3437+ struct dentry *h_dentry;
1facf9fc 3438+
86dc4139
AM
3439+ err = vfsub_mnt_want_write(au_br_mnt(br));
3440+ if (unlikely(err))
3441+ goto out;
3442+
1facf9fc 3443+ wbr = br->br_wbr;
3444+ old_perm = br->br_perm;
3445+ br->br_perm = new_perm;
3446+ hdir = NULL;
febd17d6 3447+ h_inode = NULL;
1facf9fc 3448+ bindex = au_br_index(sb, br->br_id);
3449+ if (0 <= bindex) {
5527c038 3450+ hdir = au_hi(d_inode(sb->s_root), bindex);
5afbbe0d 3451+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 3452+ } else {
5527c038 3453+ h_dentry = au_br_dentry(br);
febd17d6
JR
3454+ h_inode = d_inode(h_dentry);
3455+ inode_lock_nested(h_inode, AuLsc_I_PARENT);
1facf9fc 3456+ }
3457+ if (!wbr)
86dc4139 3458+ err = au_wh_init(br, sb);
1facf9fc 3459+ else {
3460+ wbr_wh_write_lock(wbr);
86dc4139 3461+ err = au_wh_init(br, sb);
1facf9fc 3462+ wbr_wh_write_unlock(wbr);
3463+ }
3464+ if (hdir)
5afbbe0d 3465+ au_hn_inode_unlock(hdir);
1facf9fc 3466+ else
febd17d6 3467+ inode_unlock(h_inode);
86dc4139 3468+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 3469+ br->br_perm = old_perm;
3470+
3471+ if (!err && wbr && !au_br_writable(new_perm)) {
9f237c51 3472+ au_kfree_rcu(wbr);
1facf9fc 3473+ br->br_wbr = NULL;
3474+ }
3475+
86dc4139 3476+out:
1facf9fc 3477+ return err;
3478+}
3479+
3480+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 3481+ int perm)
1facf9fc 3482+{
3483+ int err;
4a4d8108 3484+ struct kstatfs kst;
1facf9fc 3485+ struct au_wbr *wbr;
3486+
3487+ wbr = br->br_wbr;
dece6358 3488+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 3489+ atomic_set(&wbr->wbr_wh_running, 0);
1facf9fc 3490+
4a4d8108
AM
3491+ /*
3492+ * a limit for rmdir/rename a dir
523b37e3 3493+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 3494+ */
86dc4139 3495+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
3496+ if (unlikely(err))
3497+ goto out;
3498+ err = -EINVAL;
3499+ if (kst.f_namelen >= NAME_MAX)
86dc4139 3500+ err = au_br_init_wh(sb, br, perm);
4a4d8108 3501+ else
523b37e3
AM
3502+ pr_err("%pd(%s), unsupported namelen %ld\n",
3503+ au_br_dentry(br),
86dc4139 3504+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 3505+
4f0767ce 3506+out:
1facf9fc 3507+ return err;
3508+}
3509+
c1595e42 3510+/* initialize a new branch */
1facf9fc 3511+static int au_br_init(struct au_branch *br, struct super_block *sb,
3512+ struct au_opt_add *add)
3513+{
3514+ int err;
062440b3
AM
3515+ struct au_branch *brbase;
3516+ struct file *xf;
5527c038 3517+ struct inode *h_inode;
1facf9fc 3518+
3519+ err = 0;
1facf9fc 3520+ br->br_perm = add->perm;
86dc4139 3521+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108 3522+ spin_lock_init(&br->br_dykey_lock);
acd2b654
AM
3523+ au_lcnt_init(&br->br_nfiles, /*release*/NULL);
3524+ au_lcnt_init(&br->br_count, /*release*/NULL);
1facf9fc 3525+ br->br_id = au_new_br_id(sb);
7f207e10 3526+ AuDebugOn(br->br_id < 0);
1facf9fc 3527+
8b6a4947
AM
3528+ /* always, regardless the given option */
3529+ err = au_dr_br_init(sb, br, &add->path);
3530+ if (unlikely(err))
3531+ goto out_err;
3532+
1facf9fc 3533+ if (au_br_writable(add->perm)) {
86dc4139 3534+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 3535+ if (unlikely(err))
b752ccd1 3536+ goto out_err;
1facf9fc 3537+ }
3538+
3539+ if (au_opt_test(au_mntflags(sb), XINO)) {
062440b3 3540+ brbase = au_sbr(sb, 0);
acd2b654 3541+ xf = au_xino_file(brbase->br_xino, /*idx*/-1);
062440b3 3542+ AuDebugOn(!xf);
5527c038 3543+ h_inode = d_inode(add->path.dentry);
062440b3 3544+ err = au_xino_init_br(sb, br, h_inode->i_ino, &xf->f_path);
1facf9fc 3545+ if (unlikely(err)) {
acd2b654 3546+ AuDebugOn(au_xino_file(br->br_xino, /*idx*/-1));
b752ccd1 3547+ goto out_err;
1facf9fc 3548+ }
3549+ }
3550+
3551+ sysaufs_br_init(br);
86dc4139 3552+ path_get(&br->br_path);
b752ccd1 3553+ goto out; /* success */
1facf9fc 3554+
4f0767ce 3555+out_err:
86dc4139 3556+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 3557+out:
1facf9fc 3558+ return err;
3559+}
3560+
3561+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
5afbbe0d 3562+ struct au_branch *br, aufs_bindex_t bbot,
1facf9fc 3563+ aufs_bindex_t amount)
3564+{
3565+ struct au_branch **brp;
3566+
dece6358
AM
3567+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3568+
1facf9fc 3569+ brp = sbinfo->si_branch + bindex;
3570+ memmove(brp + 1, brp, sizeof(*brp) * amount);
3571+ *brp = br;
5afbbe0d
AM
3572+ sbinfo->si_bbot++;
3573+ if (unlikely(bbot < 0))
3574+ sbinfo->si_bbot = 0;
1facf9fc 3575+}
3576+
3577+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
5afbbe0d 3578+ aufs_bindex_t bbot, aufs_bindex_t amount)
1facf9fc 3579+{
3580+ struct au_hdentry *hdp;
3581+
1308ab2a 3582+ AuRwMustWriteLock(&dinfo->di_rwsem);
3583+
5afbbe0d 3584+ hdp = au_hdentry(dinfo, bindex);
1facf9fc 3585+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
3586+ au_h_dentry_init(hdp);
5afbbe0d
AM
3587+ dinfo->di_bbot++;
3588+ if (unlikely(bbot < 0))
3589+ dinfo->di_btop = 0;
1facf9fc 3590+}
3591+
3592+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
5afbbe0d 3593+ aufs_bindex_t bbot, aufs_bindex_t amount)
1facf9fc 3594+{
3595+ struct au_hinode *hip;
3596+
1308ab2a 3597+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3598+
5afbbe0d 3599+ hip = au_hinode(iinfo, bindex);
1facf9fc 3600+ memmove(hip + 1, hip, sizeof(*hip) * amount);
5afbbe0d
AM
3601+ au_hinode_init(hip);
3602+ iinfo->ii_bbot++;
3603+ if (unlikely(bbot < 0))
3604+ iinfo->ii_btop = 0;
1facf9fc 3605+}
3606+
86dc4139
AM
3607+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
3608+ aufs_bindex_t bindex)
1facf9fc 3609+{
86dc4139 3610+ struct dentry *root, *h_dentry;
5527c038 3611+ struct inode *root_inode, *h_inode;
5afbbe0d 3612+ aufs_bindex_t bbot, amount;
1facf9fc 3613+
3614+ root = sb->s_root;
5527c038 3615+ root_inode = d_inode(root);
5afbbe0d
AM
3616+ bbot = au_sbbot(sb);
3617+ amount = bbot + 1 - bindex;
86dc4139 3618+ h_dentry = au_br_dentry(br);
53392da6 3619+ au_sbilist_lock();
5afbbe0d
AM
3620+ au_br_do_add_brp(au_sbi(sb), bindex, br, bbot, amount);
3621+ au_br_do_add_hdp(au_di(root), bindex, bbot, amount);
3622+ au_br_do_add_hip(au_ii(root_inode), bindex, bbot, amount);
1facf9fc 3623+ au_set_h_dptr(root, bindex, dget(h_dentry));
5527c038
JR
3624+ h_inode = d_inode(h_dentry);
3625+ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
53392da6 3626+ au_sbilist_unlock();
1facf9fc 3627+}
3628+
3629+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
3630+{
3631+ int err;
5afbbe0d 3632+ aufs_bindex_t bbot, add_bindex;
1facf9fc 3633+ struct dentry *root, *h_dentry;
3634+ struct inode *root_inode;
3635+ struct au_branch *add_branch;
3636+
3637+ root = sb->s_root;
5527c038 3638+ root_inode = d_inode(root);
1facf9fc 3639+ IMustLock(root_inode);
5afbbe0d 3640+ IiMustWriteLock(root_inode);
1facf9fc 3641+ err = test_add(sb, add, remount);
3642+ if (unlikely(err < 0))
3643+ goto out;
3644+ if (err) {
3645+ err = 0;
3646+ goto out; /* success */
3647+ }
3648+
5afbbe0d
AM
3649+ bbot = au_sbbot(sb);
3650+ add_branch = au_br_alloc(sb, bbot + 2, add->perm);
1facf9fc 3651+ err = PTR_ERR(add_branch);
3652+ if (IS_ERR(add_branch))
3653+ goto out;
3654+
3655+ err = au_br_init(add_branch, sb, add);
3656+ if (unlikely(err)) {
3657+ au_br_do_free(add_branch);
3658+ goto out;
3659+ }
3660+
3661+ add_bindex = add->bindex;
062440b3
AM
3662+ sysaufs_brs_del(sb, add_bindex); /* remove successors */
3663+ au_br_do_add(sb, add_branch, add_bindex);
3664+ sysaufs_brs_add(sb, add_bindex); /* append successors */
3665+ dbgaufs_brs_add(sb, add_bindex, /*topdown*/0); /* rename successors */
1facf9fc 3666+
86dc4139 3667+ h_dentry = add->path.dentry;
1308ab2a 3668+ if (!add_bindex) {
1facf9fc 3669+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 3670+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
3671+ } else
5527c038 3672+ au_add_nlink(root_inode, d_inode(h_dentry));
1facf9fc 3673+
4f0767ce 3674+out:
1facf9fc 3675+ return err;
3676+}
3677+
3678+/* ---------------------------------------------------------------------- */
3679+
79b8bda9 3680+static unsigned long long au_farray_cb(struct super_block *sb, void *a,
076b876e
AM
3681+ unsigned long long max __maybe_unused,
3682+ void *arg)
3683+{
3684+ unsigned long long n;
3685+ struct file **p, *f;
8b6a4947
AM
3686+ struct hlist_bl_head *files;
3687+ struct hlist_bl_node *pos;
076b876e 3688+ struct au_finfo *finfo;
076b876e
AM
3689+
3690+ n = 0;
3691+ p = a;
3692+ files = &au_sbi(sb)->si_files;
8b6a4947
AM
3693+ hlist_bl_lock(files);
3694+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) {
076b876e
AM
3695+ f = finfo->fi_file;
3696+ if (file_count(f)
3697+ && !special_file(file_inode(f)->i_mode)) {
3698+ get_file(f);
3699+ *p++ = f;
3700+ n++;
3701+ AuDebugOn(n > max);
3702+ }
3703+ }
8b6a4947 3704+ hlist_bl_unlock(files);
076b876e
AM
3705+
3706+ return n;
3707+}
3708+
3709+static struct file **au_farray_alloc(struct super_block *sb,
3710+ unsigned long long *max)
3711+{
acd2b654
AM
3712+ struct au_sbinfo *sbi;
3713+
3714+ sbi = au_sbi(sb);
3715+ *max = au_lcnt_read(&sbi->si_nfiles, /*do_rev*/1);
79b8bda9 3716+ return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL);
076b876e
AM
3717+}
3718+
3719+static void au_farray_free(struct file **a, unsigned long long max)
3720+{
3721+ unsigned long long ull;
3722+
3723+ for (ull = 0; ull < max; ull++)
3724+ if (a[ull])
3725+ fput(a[ull]);
be52b249 3726+ kvfree(a);
076b876e
AM
3727+}
3728+
3729+/* ---------------------------------------------------------------------- */
3730+
1facf9fc 3731+/*
3732+ * delete a branch
3733+ */
3734+
3735+/* to show the line number, do not make it inlined function */
4a4d8108 3736+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 3737+ if (do_info) \
4a4d8108 3738+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 3739+} while (0)
3740+
5afbbe0d
AM
3741+static int au_test_ibusy(struct inode *inode, aufs_bindex_t btop,
3742+ aufs_bindex_t bbot)
027c5e7a 3743+{
5afbbe0d 3744+ return (inode && !S_ISDIR(inode->i_mode)) || btop == bbot;
027c5e7a
AM
3745+}
3746+
5afbbe0d
AM
3747+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t btop,
3748+ aufs_bindex_t bbot)
027c5e7a 3749+{
5afbbe0d 3750+ return au_test_ibusy(d_inode(dentry), btop, bbot);
027c5e7a
AM
3751+}
3752+
1facf9fc 3753+/*
3754+ * test if the branch is deletable or not.
3755+ */
3756+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 3757+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3758+{
3759+ int err, i, j, ndentry;
5afbbe0d 3760+ aufs_bindex_t btop, bbot;
1facf9fc 3761+ struct au_dcsub_pages dpages;
3762+ struct au_dpage *dpage;
3763+ struct dentry *d;
1facf9fc 3764+
3765+ err = au_dpages_init(&dpages, GFP_NOFS);
3766+ if (unlikely(err))
3767+ goto out;
3768+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
3769+ if (unlikely(err))
3770+ goto out_dpages;
3771+
1facf9fc 3772+ for (i = 0; !err && i < dpages.ndpage; i++) {
3773+ dpage = dpages.dpages + i;
3774+ ndentry = dpage->ndentry;
3775+ for (j = 0; !err && j < ndentry; j++) {
3776+ d = dpage->dentries[j];
c1595e42 3777+ AuDebugOn(au_dcount(d) <= 0);
027c5e7a 3778+ if (!au_digen_test(d, sigen)) {
1facf9fc 3779+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
3780+ if (unlikely(au_dbrange_test(d))) {
3781+ di_read_unlock(d, AuLock_IR);
3782+ continue;
3783+ }
3784+ } else {
1facf9fc 3785+ di_write_lock_child(d);
027c5e7a
AM
3786+ if (unlikely(au_dbrange_test(d))) {
3787+ di_write_unlock(d);
3788+ continue;
3789+ }
1facf9fc 3790+ err = au_reval_dpath(d, sigen);
3791+ if (!err)
3792+ di_downgrade_lock(d, AuLock_IR);
3793+ else {
3794+ di_write_unlock(d);
3795+ break;
3796+ }
3797+ }
3798+
027c5e7a 3799+ /* AuDbgDentry(d); */
5afbbe0d
AM
3800+ btop = au_dbtop(d);
3801+ bbot = au_dbbot(d);
3802+ if (btop <= bindex
3803+ && bindex <= bbot
1facf9fc 3804+ && au_h_dptr(d, bindex)
5afbbe0d 3805+ && au_test_dbusy(d, btop, bbot)) {
1facf9fc 3806+ err = -EBUSY;
523b37e3 3807+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 3808+ AuDbgDentry(d);
1facf9fc 3809+ }
3810+ di_read_unlock(d, AuLock_IR);
3811+ }
3812+ }
3813+
4f0767ce 3814+out_dpages:
1facf9fc 3815+ au_dpages_free(&dpages);
4f0767ce 3816+out:
1facf9fc 3817+ return err;
3818+}
3819+
3820+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 3821+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3822+{
3823+ int err;
7f207e10
AM
3824+ unsigned long long max, ull;
3825+ struct inode *i, **array;
5afbbe0d 3826+ aufs_bindex_t btop, bbot;
1facf9fc 3827+
7f207e10
AM
3828+ array = au_iarray_alloc(sb, &max);
3829+ err = PTR_ERR(array);
3830+ if (IS_ERR(array))
3831+ goto out;
3832+
1facf9fc 3833+ err = 0;
7f207e10
AM
3834+ AuDbg("b%d\n", bindex);
3835+ for (ull = 0; !err && ull < max; ull++) {
3836+ i = array[ull];
076b876e
AM
3837+ if (unlikely(!i))
3838+ break;
7f207e10 3839+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 3840+ continue;
3841+
7f207e10 3842+ /* AuDbgInode(i); */
537831f9 3843+ if (au_iigen(i, NULL) == sigen)
1facf9fc 3844+ ii_read_lock_child(i);
3845+ else {
3846+ ii_write_lock_child(i);
027c5e7a
AM
3847+ err = au_refresh_hinode_self(i);
3848+ au_iigen_dec(i);
1facf9fc 3849+ if (!err)
3850+ ii_downgrade_lock(i);
3851+ else {
3852+ ii_write_unlock(i);
3853+ break;
3854+ }
3855+ }
3856+
5afbbe0d
AM
3857+ btop = au_ibtop(i);
3858+ bbot = au_ibbot(i);
3859+ if (btop <= bindex
3860+ && bindex <= bbot
1facf9fc 3861+ && au_h_iptr(i, bindex)
5afbbe0d 3862+ && au_test_ibusy(i, btop, bbot)) {
1facf9fc 3863+ err = -EBUSY;
3864+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 3865+ AuDbgInode(i);
1facf9fc 3866+ }
3867+ ii_read_unlock(i);
3868+ }
7f207e10 3869+ au_iarray_free(array, max);
1facf9fc 3870+
7f207e10 3871+out:
1facf9fc 3872+ return err;
3873+}
3874+
b752ccd1
AM
3875+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
3876+ const unsigned int verbose)
1facf9fc 3877+{
3878+ int err;
3879+ unsigned int sigen;
3880+
3881+ sigen = au_sigen(root->d_sb);
3882+ DiMustNoWaiters(root);
5527c038 3883+ IiMustNoWaiters(d_inode(root));
1facf9fc 3884+ di_write_unlock(root);
b752ccd1 3885+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 3886+ if (!err)
b752ccd1 3887+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 3888+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3889+
3890+ return err;
3891+}
3892+
076b876e
AM
3893+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
3894+ struct file **to_free, int *idx)
3895+{
3896+ int err;
c1595e42 3897+ unsigned char matched, root;
5afbbe0d 3898+ aufs_bindex_t bindex, bbot;
076b876e
AM
3899+ struct au_fidir *fidir;
3900+ struct au_hfile *hfile;
3901+
3902+ err = 0;
2000de60 3903+ root = IS_ROOT(file->f_path.dentry);
c1595e42
JR
3904+ if (root) {
3905+ get_file(file);
3906+ to_free[*idx] = file;
3907+ (*idx)++;
3908+ goto out;
3909+ }
3910+
076b876e 3911+ matched = 0;
076b876e
AM
3912+ fidir = au_fi(file)->fi_hdir;
3913+ AuDebugOn(!fidir);
5afbbe0d
AM
3914+ bbot = au_fbbot_dir(file);
3915+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) {
076b876e
AM
3916+ hfile = fidir->fd_hfile + bindex;
3917+ if (!hfile->hf_file)
3918+ continue;
3919+
c1595e42 3920+ if (hfile->hf_br->br_id == br_id) {
076b876e 3921+ matched = 1;
076b876e 3922+ break;
c1595e42 3923+ }
076b876e 3924+ }
c1595e42 3925+ if (matched)
076b876e
AM
3926+ err = -EBUSY;
3927+
3928+out:
3929+ return err;
3930+}
3931+
3932+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
3933+ struct file **to_free, int opened)
3934+{
3935+ int err, idx;
3936+ unsigned long long ull, max;
5afbbe0d 3937+ aufs_bindex_t btop;
076b876e 3938+ struct file *file, **array;
076b876e
AM
3939+ struct dentry *root;
3940+ struct au_hfile *hfile;
3941+
3942+ array = au_farray_alloc(sb, &max);
3943+ err = PTR_ERR(array);
3944+ if (IS_ERR(array))
3945+ goto out;
3946+
3947+ err = 0;
3948+ idx = 0;
3949+ root = sb->s_root;
3950+ di_write_unlock(root);
3951+ for (ull = 0; ull < max; ull++) {
3952+ file = array[ull];
3953+ if (unlikely(!file))
3954+ break;
3955+
3956+ /* AuDbg("%pD\n", file); */
3957+ fi_read_lock(file);
5afbbe0d 3958+ btop = au_fbtop(file);
2000de60 3959+ if (!d_is_dir(file->f_path.dentry)) {
076b876e
AM
3960+ hfile = &au_fi(file)->fi_htop;
3961+ if (hfile->hf_br->br_id == br_id)
3962+ err = -EBUSY;
3963+ } else
3964+ err = test_dir_busy(file, br_id, to_free, &idx);
3965+ fi_read_unlock(file);
3966+ if (unlikely(err))
3967+ break;
3968+ }
3969+ di_write_lock_child(root);
3970+ au_farray_free(array, max);
3971+ AuDebugOn(idx > opened);
3972+
3973+out:
3974+ return err;
3975+}
3976+
3977+static void br_del_file(struct file **to_free, unsigned long long opened,
062440b3 3978+ aufs_bindex_t br_id)
076b876e
AM
3979+{
3980+ unsigned long long ull;
5afbbe0d 3981+ aufs_bindex_t bindex, btop, bbot, bfound;
076b876e
AM
3982+ struct file *file;
3983+ struct au_fidir *fidir;
3984+ struct au_hfile *hfile;
3985+
3986+ for (ull = 0; ull < opened; ull++) {
3987+ file = to_free[ull];
3988+ if (unlikely(!file))
3989+ break;
3990+
3991+ /* AuDbg("%pD\n", file); */
2000de60 3992+ AuDebugOn(!d_is_dir(file->f_path.dentry));
076b876e
AM
3993+ bfound = -1;
3994+ fidir = au_fi(file)->fi_hdir;
3995+ AuDebugOn(!fidir);
3996+ fi_write_lock(file);
5afbbe0d
AM
3997+ btop = au_fbtop(file);
3998+ bbot = au_fbbot_dir(file);
3999+ for (bindex = btop; bindex <= bbot; bindex++) {
076b876e
AM
4000+ hfile = fidir->fd_hfile + bindex;
4001+ if (!hfile->hf_file)
4002+ continue;
4003+
4004+ if (hfile->hf_br->br_id == br_id) {
4005+ bfound = bindex;
4006+ break;
4007+ }
4008+ }
4009+ AuDebugOn(bfound < 0);
4010+ au_set_h_fptr(file, bfound, NULL);
5afbbe0d
AM
4011+ if (bfound == btop) {
4012+ for (btop++; btop <= bbot; btop++)
4013+ if (au_hf_dir(file, btop)) {
4014+ au_set_fbtop(file, btop);
076b876e
AM
4015+ break;
4016+ }
4017+ }
4018+ fi_write_unlock(file);
4019+ }
4020+}
4021+
1facf9fc 4022+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
4023+ const aufs_bindex_t bindex,
5afbbe0d 4024+ const aufs_bindex_t bbot)
1facf9fc 4025+{
4026+ struct au_branch **brp, **p;
4027+
dece6358
AM
4028+ AuRwMustWriteLock(&sbinfo->si_rwsem);
4029+
1facf9fc 4030+ brp = sbinfo->si_branch + bindex;
5afbbe0d
AM
4031+ if (bindex < bbot)
4032+ memmove(brp, brp + 1, sizeof(*brp) * (bbot - bindex));
4033+ sbinfo->si_branch[0 + bbot] = NULL;
4034+ sbinfo->si_bbot--;
1facf9fc 4035+
e2f27e51
AM
4036+ p = au_krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST,
4037+ /*may_shrink*/1);
1facf9fc 4038+ if (p)
4039+ sbinfo->si_branch = p;
4a4d8108 4040+ /* harmless error */
1facf9fc 4041+}
4042+
4043+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
5afbbe0d 4044+ const aufs_bindex_t bbot)
1facf9fc 4045+{
4046+ struct au_hdentry *hdp, *p;
4047+
1308ab2a 4048+ AuRwMustWriteLock(&dinfo->di_rwsem);
4049+
5afbbe0d
AM
4050+ hdp = au_hdentry(dinfo, bindex);
4051+ if (bindex < bbot)
4052+ memmove(hdp, hdp + 1, sizeof(*hdp) * (bbot - bindex));
4053+ /* au_h_dentry_init(au_hdentry(dinfo, bbot); */
4054+ dinfo->di_bbot--;
1facf9fc 4055+
e2f27e51
AM
4056+ p = au_krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST,
4057+ /*may_shrink*/1);
1facf9fc 4058+ if (p)
4059+ dinfo->di_hdentry = p;
4a4d8108 4060+ /* harmless error */
1facf9fc 4061+}
4062+
4063+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
5afbbe0d 4064+ const aufs_bindex_t bbot)
1facf9fc 4065+{
4066+ struct au_hinode *hip, *p;
4067+
1308ab2a 4068+ AuRwMustWriteLock(&iinfo->ii_rwsem);
4069+
5afbbe0d
AM
4070+ hip = au_hinode(iinfo, bindex);
4071+ if (bindex < bbot)
4072+ memmove(hip, hip + 1, sizeof(*hip) * (bbot - bindex));
4073+ /* au_hinode_init(au_hinode(iinfo, bbot)); */
4074+ iinfo->ii_bbot--;
1facf9fc 4075+
e2f27e51
AM
4076+ p = au_krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST,
4077+ /*may_shrink*/1);
1facf9fc 4078+ if (p)
4079+ iinfo->ii_hinode = p;
4a4d8108 4080+ /* harmless error */
1facf9fc 4081+}
4082+
4083+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
4084+ struct au_branch *br)
4085+{
5afbbe0d 4086+ aufs_bindex_t bbot;
1facf9fc 4087+ struct au_sbinfo *sbinfo;
53392da6
AM
4088+ struct dentry *root, *h_root;
4089+ struct inode *inode, *h_inode;
4090+ struct au_hinode *hinode;
1facf9fc 4091+
dece6358
AM
4092+ SiMustWriteLock(sb);
4093+
1facf9fc 4094+ root = sb->s_root;
5527c038 4095+ inode = d_inode(root);
1facf9fc 4096+ sbinfo = au_sbi(sb);
5afbbe0d 4097+ bbot = sbinfo->si_bbot;
1facf9fc 4098+
53392da6
AM
4099+ h_root = au_h_dptr(root, bindex);
4100+ hinode = au_hi(inode, bindex);
4101+ h_inode = au_igrab(hinode->hi_inode);
4102+ au_hiput(hinode);
1facf9fc 4103+
53392da6 4104+ au_sbilist_lock();
5afbbe0d
AM
4105+ au_br_do_del_brp(sbinfo, bindex, bbot);
4106+ au_br_do_del_hdp(au_di(root), bindex, bbot);
4107+ au_br_do_del_hip(au_ii(inode), bindex, bbot);
53392da6
AM
4108+ au_sbilist_unlock();
4109+
8b6a4947
AM
4110+ /* ignore an error */
4111+ au_dr_br_fin(sb, br); /* always, regardless the mount option */
4112+
53392da6
AM
4113+ dput(h_root);
4114+ iput(h_inode);
4115+ au_br_do_free(br);
1facf9fc 4116+}
4117+
79b8bda9
AM
4118+static unsigned long long empty_cb(struct super_block *sb, void *array,
4119+ unsigned long long max, void *arg)
076b876e
AM
4120+{
4121+ return max;
4122+}
4123+
1facf9fc 4124+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
4125+{
4126+ int err, rerr, i;
076b876e 4127+ unsigned long long opened;
1facf9fc 4128+ unsigned int mnt_flags;
5afbbe0d 4129+ aufs_bindex_t bindex, bbot, br_id;
1facf9fc 4130+ unsigned char do_wh, verbose;
4131+ struct au_branch *br;
4132+ struct au_wbr *wbr;
076b876e
AM
4133+ struct dentry *root;
4134+ struct file **to_free;
1facf9fc 4135+
4136+ err = 0;
076b876e
AM
4137+ opened = 0;
4138+ to_free = NULL;
4139+ root = sb->s_root;
4140+ bindex = au_find_dbindex(root, del->h_path.dentry);
1facf9fc 4141+ if (bindex < 0) {
4142+ if (remount)
4143+ goto out; /* success */
4144+ err = -ENOENT;
4a4d8108 4145+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 4146+ goto out;
4147+ }
4148+ AuDbg("bindex b%d\n", bindex);
4149+
4150+ err = -EBUSY;
4151+ mnt_flags = au_mntflags(sb);
4152+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
5afbbe0d
AM
4153+ bbot = au_sbbot(sb);
4154+ if (unlikely(!bbot)) {
1facf9fc 4155+ AuVerbose(verbose, "no more branches left\n");
4156+ goto out;
4157+ }
acd2b654 4158+
1facf9fc 4159+ br = au_sbr(sb, bindex);
86dc4139 4160+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
acd2b654
AM
4161+ if (unlikely(au_lcnt_read(&br->br_count, /*do_rev*/1))) {
4162+ AuVerbose(verbose, "br %pd2 is busy now\n", del->h_path.dentry);
4163+ goto out;
4164+ }
076b876e
AM
4165+
4166+ br_id = br->br_id;
acd2b654 4167+ opened = au_lcnt_read(&br->br_nfiles, /*do_rev*/1);
076b876e 4168+ if (unlikely(opened)) {
79b8bda9 4169+ to_free = au_array_alloc(&opened, empty_cb, sb, NULL);
076b876e
AM
4170+ err = PTR_ERR(to_free);
4171+ if (IS_ERR(to_free))
4172+ goto out;
4173+
4174+ err = test_file_busy(sb, br_id, to_free, opened);
4175+ if (unlikely(err)) {
4176+ AuVerbose(verbose, "%llu file(s) opened\n", opened);
4177+ goto out;
4178+ }
1facf9fc 4179+ }
4180+
4181+ wbr = br->br_wbr;
4182+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
4183+ if (do_wh) {
1308ab2a 4184+ /* instead of WbrWhMustWriteLock(wbr) */
4185+ SiMustWriteLock(sb);
1facf9fc 4186+ for (i = 0; i < AuBrWh_Last; i++) {
4187+ dput(wbr->wbr_wh[i]);
4188+ wbr->wbr_wh[i] = NULL;
4189+ }
4190+ }
4191+
076b876e 4192+ err = test_children_busy(root, bindex, verbose);
1facf9fc 4193+ if (unlikely(err)) {
4194+ if (do_wh)
4195+ goto out_wh;
4196+ goto out;
4197+ }
4198+
4199+ err = 0;
076b876e
AM
4200+ if (to_free) {
4201+ /*
4202+ * now we confirmed the branch is deletable.
4203+ * let's free the remaining opened dirs on the branch.
4204+ */
4205+ di_write_unlock(root);
4206+ br_del_file(to_free, opened, br_id);
4207+ di_write_lock_child(root);
4208+ }
4209+
062440b3
AM
4210+ sysaufs_brs_del(sb, bindex); /* remove successors */
4211+ dbgaufs_xino_del(br); /* remove one */
4212+ au_br_do_del(sb, bindex, br);
4213+ sysaufs_brs_add(sb, bindex); /* append successors */
4214+ dbgaufs_brs_add(sb, bindex, /*topdown*/1); /* rename successors */
1facf9fc 4215+
1308ab2a 4216+ if (!bindex) {
5527c038 4217+ au_cpup_attr_all(d_inode(root), /*force*/1);
1308ab2a 4218+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
4219+ } else
5527c038 4220+ au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry));
1facf9fc 4221+ if (au_opt_test(mnt_flags, PLINK))
4222+ au_plink_half_refresh(sb, br_id);
4223+
1facf9fc 4224+ goto out; /* success */
4225+
4f0767ce 4226+out_wh:
1facf9fc 4227+ /* revert */
86dc4139 4228+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 4229+ if (rerr)
0c3ec466
AM
4230+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
4231+ del->pathname, rerr);
4f0767ce 4232+out:
076b876e
AM
4233+ if (to_free)
4234+ au_farray_free(to_free, opened);
1facf9fc 4235+ return err;
4236+}
4237+
4238+/* ---------------------------------------------------------------------- */
4239+
027c5e7a
AM
4240+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
4241+{
4242+ int err;
5afbbe0d 4243+ aufs_bindex_t btop, bbot;
027c5e7a
AM
4244+ struct aufs_ibusy ibusy;
4245+ struct inode *inode, *h_inode;
4246+
4247+ err = -EPERM;
4248+ if (unlikely(!capable(CAP_SYS_ADMIN)))
4249+ goto out;
4250+
4251+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
4252+ if (!err)
ba1aed25
AM
4253+ /* VERIFY_WRITE */
4254+ err = !access_ok(&arg->h_ino, sizeof(arg->h_ino));
027c5e7a
AM
4255+ if (unlikely(err)) {
4256+ err = -EFAULT;
4257+ AuTraceErr(err);
4258+ goto out;
4259+ }
4260+
4261+ err = -EINVAL;
4262+ si_read_lock(sb, AuLock_FLUSH);
5afbbe0d 4263+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbbot(sb)))
027c5e7a
AM
4264+ goto out_unlock;
4265+
4266+ err = 0;
4267+ ibusy.h_ino = 0; /* invalid */
4268+ inode = ilookup(sb, ibusy.ino);
4269+ if (!inode
4270+ || inode->i_ino == AUFS_ROOT_INO
5afbbe0d 4271+ || au_is_bad_inode(inode))
027c5e7a
AM
4272+ goto out_unlock;
4273+
4274+ ii_read_lock_child(inode);
5afbbe0d
AM
4275+ btop = au_ibtop(inode);
4276+ bbot = au_ibbot(inode);
4277+ if (btop <= ibusy.bindex && ibusy.bindex <= bbot) {
027c5e7a 4278+ h_inode = au_h_iptr(inode, ibusy.bindex);
5afbbe0d 4279+ if (h_inode && au_test_ibusy(inode, btop, bbot))
027c5e7a
AM
4280+ ibusy.h_ino = h_inode->i_ino;
4281+ }
4282+ ii_read_unlock(inode);
4283+ iput(inode);
4284+
4285+out_unlock:
4286+ si_read_unlock(sb);
4287+ if (!err) {
4288+ err = __put_user(ibusy.h_ino, &arg->h_ino);
4289+ if (unlikely(err)) {
4290+ err = -EFAULT;
4291+ AuTraceErr(err);
4292+ }
4293+ }
4294+out:
4295+ return err;
4296+}
4297+
4298+long au_ibusy_ioctl(struct file *file, unsigned long arg)
4299+{
2000de60 4300+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg);
027c5e7a
AM
4301+}
4302+
4303+#ifdef CONFIG_COMPAT
4304+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
4305+{
2000de60 4306+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg));
027c5e7a
AM
4307+}
4308+#endif
4309+
4310+/* ---------------------------------------------------------------------- */
4311+
1facf9fc 4312+/*
4313+ * change a branch permission
4314+ */
4315+
dece6358
AM
4316+static void au_warn_ima(void)
4317+{
4318+#ifdef CONFIG_IMA
1308ab2a 4319+ /* since it doesn't support mark_files_ro() */
027c5e7a 4320+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
4321+#endif
4322+}
4323+
1facf9fc 4324+static int do_need_sigen_inc(int a, int b)
4325+{
4326+ return au_br_whable(a) && !au_br_whable(b);
4327+}
4328+
4329+static int need_sigen_inc(int old, int new)
4330+{
4331+ return do_need_sigen_inc(old, new)
4332+ || do_need_sigen_inc(new, old);
4333+}
4334+
4335+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
4336+{
7f207e10 4337+ int err, do_warn;
027c5e7a 4338+ unsigned int mnt_flags;
7f207e10 4339+ unsigned long long ull, max;
e49829fe 4340+ aufs_bindex_t br_id;
38d290e6 4341+ unsigned char verbose, writer;
7f207e10 4342+ struct file *file, *hf, **array;
e49829fe 4343+ struct au_hfile *hfile;
1facf9fc 4344+
027c5e7a
AM
4345+ mnt_flags = au_mntflags(sb);
4346+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
4347+
7f207e10
AM
4348+ array = au_farray_alloc(sb, &max);
4349+ err = PTR_ERR(array);
4350+ if (IS_ERR(array))
1facf9fc 4351+ goto out;
4352+
7f207e10 4353+ do_warn = 0;
e49829fe 4354+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
4355+ for (ull = 0; ull < max; ull++) {
4356+ file = array[ull];
076b876e
AM
4357+ if (unlikely(!file))
4358+ break;
1facf9fc 4359+
523b37e3 4360+ /* AuDbg("%pD\n", file); */
1facf9fc 4361+ fi_read_lock(file);
4362+ if (unlikely(au_test_mmapped(file))) {
4363+ err = -EBUSY;
523b37e3 4364+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 4365+ AuDbgFile(file);
1facf9fc 4366+ FiMustNoWaiters(file);
4367+ fi_read_unlock(file);
7f207e10 4368+ goto out_array;
1facf9fc 4369+ }
4370+
e49829fe
JR
4371+ hfile = &au_fi(file)->fi_htop;
4372+ hf = hfile->hf_file;
7e9cd9fe 4373+ if (!d_is_reg(file->f_path.dentry)
1facf9fc 4374+ || !(file->f_mode & FMODE_WRITE)
e49829fe 4375+ || hfile->hf_br->br_id != br_id
7f207e10
AM
4376+ || !(hf->f_mode & FMODE_WRITE))
4377+ array[ull] = NULL;
4378+ else {
4379+ do_warn = 1;
4380+ get_file(file);
1facf9fc 4381+ }
4382+
1facf9fc 4383+ FiMustNoWaiters(file);
4384+ fi_read_unlock(file);
7f207e10
AM
4385+ fput(file);
4386+ }
1facf9fc 4387+
4388+ err = 0;
7f207e10 4389+ if (do_warn)
dece6358 4390+ au_warn_ima();
7f207e10
AM
4391+
4392+ for (ull = 0; ull < max; ull++) {
4393+ file = array[ull];
4394+ if (!file)
4395+ continue;
4396+
1facf9fc 4397+ /* todo: already flushed? */
523b37e3
AM
4398+ /*
4399+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
4400+ * approach which resets f_mode and calls mnt_drop_write() and
4401+ * file_release_write() for each file, because the branch
4402+ * attribute in aufs world is totally different from the native
4403+ * fs rw/ro mode.
4404+ */
7f207e10
AM
4405+ /* fi_read_lock(file); */
4406+ hfile = &au_fi(file)->fi_htop;
4407+ hf = hfile->hf_file;
4408+ /* fi_read_unlock(file); */
027c5e7a 4409+ spin_lock(&hf->f_lock);
38d290e6
JR
4410+ writer = !!(hf->f_mode & FMODE_WRITER);
4411+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
027c5e7a 4412+ spin_unlock(&hf->f_lock);
38d290e6
JR
4413+ if (writer) {
4414+ put_write_access(file_inode(hf));
c06a8ce3 4415+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 4416+ }
4417+ }
4418+
7f207e10
AM
4419+out_array:
4420+ au_farray_free(array, max);
4f0767ce 4421+out:
7f207e10 4422+ AuTraceErr(err);
1facf9fc 4423+ return err;
4424+}
4425+
4426+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4427+ int *do_refresh)
1facf9fc 4428+{
4429+ int err, rerr;
4430+ aufs_bindex_t bindex;
4431+ struct dentry *root;
4432+ struct au_branch *br;
076b876e 4433+ struct au_br_fhsm *bf;
1facf9fc 4434+
4435+ root = sb->s_root;
1facf9fc 4436+ bindex = au_find_dbindex(root, mod->h_root);
4437+ if (bindex < 0) {
4438+ if (remount)
4439+ return 0; /* success */
4440+ err = -ENOENT;
4a4d8108 4441+ pr_err("%s no such branch\n", mod->path);
1facf9fc 4442+ goto out;
4443+ }
4444+ AuDbg("bindex b%d\n", bindex);
4445+
5527c038 4446+ err = test_br(d_inode(mod->h_root), mod->perm, mod->path);
1facf9fc 4447+ if (unlikely(err))
4448+ goto out;
4449+
4450+ br = au_sbr(sb, bindex);
86dc4139 4451+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 4452+ if (br->br_perm == mod->perm)
4453+ return 0; /* success */
4454+
076b876e
AM
4455+ /* pre-allocate for non-fhsm --> fhsm */
4456+ bf = NULL;
4457+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
4458+ err = au_fhsm_br_alloc(br);
4459+ if (unlikely(err))
4460+ goto out;
4461+ bf = br->br_fhsm;
4462+ br->br_fhsm = NULL;
4463+ }
4464+
1facf9fc 4465+ if (au_br_writable(br->br_perm)) {
4466+ /* remove whiteout base */
86dc4139 4467+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 4468+ if (unlikely(err))
076b876e 4469+ goto out_bf;
1facf9fc 4470+
4471+ if (!au_br_writable(mod->perm)) {
4472+ /* rw --> ro, file might be mmapped */
4473+ DiMustNoWaiters(root);
5527c038 4474+ IiMustNoWaiters(d_inode(root));
1facf9fc 4475+ di_write_unlock(root);
4476+ err = au_br_mod_files_ro(sb, bindex);
4477+ /* aufs_write_lock() calls ..._child() */
4478+ di_write_lock_child(root);
4479+
4480+ if (unlikely(err)) {
4481+ rerr = -ENOMEM;
be52b249 4482+ br->br_wbr = kzalloc(sizeof(*br->br_wbr),
1facf9fc 4483+ GFP_NOFS);
86dc4139
AM
4484+ if (br->br_wbr)
4485+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 4486+ if (unlikely(rerr)) {
4487+ AuIOErr("nested error %d (%d)\n",
4488+ rerr, err);
4489+ br->br_perm = mod->perm;
4490+ }
4491+ }
4492+ }
4493+ } else if (au_br_writable(mod->perm)) {
4494+ /* ro --> rw */
4495+ err = -ENOMEM;
be52b249 4496+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), GFP_NOFS);
1facf9fc 4497+ if (br->br_wbr) {
86dc4139 4498+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 4499+ if (unlikely(err)) {
9f237c51 4500+ au_kfree_rcu(br->br_wbr);
1facf9fc 4501+ br->br_wbr = NULL;
4502+ }
4503+ }
4504+ }
076b876e
AM
4505+ if (unlikely(err))
4506+ goto out_bf;
4507+
4508+ if (au_br_fhsm(br->br_perm)) {
4509+ if (!au_br_fhsm(mod->perm)) {
4510+ /* fhsm --> non-fhsm */
4511+ au_br_fhsm_fin(br->br_fhsm);
9f237c51 4512+ au_kfree_rcu(br->br_fhsm);
076b876e
AM
4513+ br->br_fhsm = NULL;
4514+ }
4515+ } else if (au_br_fhsm(mod->perm))
4516+ /* non-fhsm --> fhsm */
4517+ br->br_fhsm = bf;
4518+
076b876e
AM
4519+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
4520+ br->br_perm = mod->perm;
4521+ goto out; /* success */
1facf9fc 4522+
076b876e 4523+out_bf:
9f237c51 4524+ au_kfree_try_rcu(bf);
076b876e
AM
4525+out:
4526+ AuTraceErr(err);
4527+ return err;
4528+}
4529+
4530+/* ---------------------------------------------------------------------- */
4531+
4532+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
4533+{
4534+ int err;
4535+ struct kstatfs kstfs;
4536+
4537+ err = vfs_statfs(&br->br_path, &kstfs);
1facf9fc 4538+ if (!err) {
076b876e
AM
4539+ stfs->f_blocks = kstfs.f_blocks;
4540+ stfs->f_bavail = kstfs.f_bavail;
4541+ stfs->f_files = kstfs.f_files;
4542+ stfs->f_ffree = kstfs.f_ffree;
1facf9fc 4543+ }
4544+
1facf9fc 4545+ return err;
4546+}
7f207e10
AM
4547diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
4548--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 4549+++ linux/fs/aufs/branch.h 2019-03-05 12:13:00.135890907 +0100
9f237c51 4550@@ -0,0 +1,365 @@
062440b3 4551+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 4552+/*
ba1aed25 4553+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 4554+ *
4555+ * This program, aufs is free software; you can redistribute it and/or modify
4556+ * it under the terms of the GNU General Public License as published by
4557+ * the Free Software Foundation; either version 2 of the License, or
4558+ * (at your option) any later version.
dece6358
AM
4559+ *
4560+ * This program is distributed in the hope that it will be useful,
4561+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4562+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4563+ * GNU General Public License for more details.
4564+ *
4565+ * You should have received a copy of the GNU General Public License
523b37e3 4566+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4567+ */
4568+
4569+/*
4570+ * branch filesystems and xino for them
4571+ */
4572+
4573+#ifndef __AUFS_BRANCH_H__
4574+#define __AUFS_BRANCH_H__
4575+
4576+#ifdef __KERNEL__
4577+
1facf9fc 4578+#include <linux/mount.h>
8b6a4947 4579+#include "dirren.h"
4a4d8108 4580+#include "dynop.h"
acd2b654 4581+#include "lcnt.h"
1facf9fc 4582+#include "rwsem.h"
4583+#include "super.h"
4584+
4585+/* ---------------------------------------------------------------------- */
4586+
4587+/* a xino file */
062440b3 4588+struct au_xino {
acd2b654
AM
4589+ struct file **xi_file;
4590+ unsigned int xi_nfile;
4591+
521ced18
JR
4592+ struct {
4593+ spinlock_t spin;
4594+ ino_t *array;
4595+ int total;
4596+ /* reserved for future use */
4597+ /* unsigned long *bitmap; */
4598+ wait_queue_head_t wqh;
4599+ } xi_nondir;
1facf9fc 4600+
acd2b654 4601+ struct mutex xi_mtx; /* protects xi_file array */
9f237c51 4602+ struct hlist_bl_head xi_writing;
acd2b654 4603+
062440b3 4604+ atomic_t xi_truncating;
1facf9fc 4605+
062440b3 4606+ struct kref xi_kref;
1facf9fc 4607+};
4608+
076b876e
AM
4609+/* File-based Hierarchical Storage Management */
4610+struct au_br_fhsm {
4611+#ifdef CONFIG_AUFS_FHSM
4612+ struct mutex bf_lock;
4613+ unsigned long bf_jiffy;
4614+ struct aufs_stfs bf_stfs;
4615+ int bf_readable;
4616+#endif
4617+};
4618+
1facf9fc 4619+/* members for writable branch only */
4620+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
4621+struct au_wbr {
dece6358 4622+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 4623+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 4624+ atomic_t wbr_wh_running;
1facf9fc 4625+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
4626+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
4627+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
4628+
4629+ /* mfs mode */
4630+ unsigned long long wbr_bytes;
4631+};
4632+
4a4d8108
AM
4633+/* ext2 has 3 types of operations at least, ext3 has 4 */
4634+#define AuBrDynOp (AuDyLast * 4)
4635+
1716fcea
AM
4636+#ifdef CONFIG_AUFS_HFSNOTIFY
4637+/* support for asynchronous destruction */
4638+struct au_br_hfsnotify {
4639+ struct fsnotify_group *hfsn_group;
4640+};
4641+#endif
4642+
392086de
AM
4643+/* sysfs entries */
4644+struct au_brsysfs {
4645+ char name[16];
4646+ struct attribute attr;
4647+};
4648+
4649+enum {
4650+ AuBrSysfs_BR,
4651+ AuBrSysfs_BRID,
4652+ AuBrSysfs_Last
4653+};
4654+
1facf9fc 4655+/* protected by superblock rwsem */
4656+struct au_branch {
062440b3 4657+ struct au_xino *br_xino;
1facf9fc 4658+
4659+ aufs_bindex_t br_id;
4660+
4661+ int br_perm;
86dc4139 4662+ struct path br_path;
4a4d8108
AM
4663+ spinlock_t br_dykey_lock;
4664+ struct au_dykey *br_dykey[AuBrDynOp];
acd2b654
AM
4665+ au_lcnt_t br_nfiles; /* opened files */
4666+ au_lcnt_t br_count; /* in-use for other */
1facf9fc 4667+
4668+ struct au_wbr *br_wbr;
076b876e 4669+ struct au_br_fhsm *br_fhsm;
1facf9fc 4670+
027c5e7a 4671+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 4672+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
4673+#endif
4674+
1facf9fc 4675+#ifdef CONFIG_SYSFS
392086de
AM
4676+ /* entries under sysfs per mount-point */
4677+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 4678+#endif
8b6a4947 4679+
062440b3
AM
4680+#ifdef CONFIG_DEBUG_FS
4681+ struct dentry *br_dbgaufs; /* xino */
4682+#endif
4683+
8b6a4947 4684+ struct au_dr_br br_dirren;
1facf9fc 4685+};
4686+
4687+/* ---------------------------------------------------------------------- */
4688+
86dc4139
AM
4689+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
4690+{
4691+ return br->br_path.mnt;
4692+}
4693+
4694+static inline struct dentry *au_br_dentry(struct au_branch *br)
4695+{
4696+ return br->br_path.dentry;
4697+}
4698+
4699+static inline struct super_block *au_br_sb(struct au_branch *br)
4700+{
4701+ return au_br_mnt(br)->mnt_sb;
4702+}
4703+
1facf9fc 4704+static inline int au_br_rdonly(struct au_branch *br)
4705+{
8b6a4947 4706+ return (sb_rdonly(au_br_sb(br))
1facf9fc 4707+ || !au_br_writable(br->br_perm))
4708+ ? -EROFS : 0;
4709+}
4710+
4a4d8108 4711+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 4712+{
4a4d8108 4713+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 4714+ return !(brperm & AuBrPerm_RR);
1facf9fc 4715+#else
4716+ return 0;
4717+#endif
4718+}
4719+
b912730e
AM
4720+static inline int au_br_test_oflag(int oflag, struct au_branch *br)
4721+{
4722+ int err, exec_flag;
4723+
4724+ err = 0;
4725+ exec_flag = oflag & __FMODE_EXEC;
79b8bda9 4726+ if (unlikely(exec_flag && path_noexec(&br->br_path)))
b912730e
AM
4727+ err = -EACCES;
4728+
4729+ return err;
4730+}
4731+
062440b3
AM
4732+static inline void au_xino_get(struct au_branch *br)
4733+{
4734+ struct au_xino *xi;
4735+
4736+ xi = br->br_xino;
4737+ if (xi)
4738+ kref_get(&xi->xi_kref);
4739+}
4740+
4741+static inline int au_xino_count(struct au_branch *br)
4742+{
4743+ int v;
4744+ struct au_xino *xi;
4745+
4746+ v = 0;
4747+ xi = br->br_xino;
4748+ if (xi)
4749+ v = kref_read(&xi->xi_kref);
4750+
4751+ return v;
4752+}
4753+
1facf9fc 4754+/* ---------------------------------------------------------------------- */
4755+
4756+/* branch.c */
4757+struct au_sbinfo;
4758+void au_br_free(struct au_sbinfo *sinfo);
4759+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
4760+struct au_opt_add;
4761+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
4762+struct au_opt_del;
4763+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
4764+long au_ibusy_ioctl(struct file *file, unsigned long arg);
4765+#ifdef CONFIG_COMPAT
4766+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
4767+#endif
1facf9fc 4768+struct au_opt_mod;
4769+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4770+ int *do_refresh);
076b876e
AM
4771+struct aufs_stfs;
4772+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
1facf9fc 4773+
4774+/* xino.c */
4775+static const loff_t au_loff_max = LLONG_MAX;
4776+
acd2b654 4777+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry);
062440b3
AM
4778+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent);
4779+struct file *au_xino_create2(struct super_block *sb, struct path *base,
4780+ struct file *copy_src);
acd2b654
AM
4781+struct au_xi_new {
4782+ struct au_xino *xi; /* switch between xino and xigen */
4783+ int idx;
4784+ struct path *base;
4785+ struct file *copy_src;
4786+};
4787+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew);
062440b3
AM
4788+
4789+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4790+ ino_t *ino);
4791+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4792+ ino_t ino);
5527c038 4793+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size,
1facf9fc 4794+ loff_t *pos);
5527c038
JR
4795+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
4796+ size_t size, loff_t *pos);
062440b3
AM
4797+
4798+int au_xib_trunc(struct super_block *sb);
acd2b654 4799+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin);
1facf9fc 4800+
acd2b654 4801+struct au_xino *au_xino_alloc(unsigned int nfile);
062440b3 4802+int au_xino_put(struct au_branch *br);
acd2b654 4803+struct file *au_xino_file1(struct au_xino *xi);
062440b3 4804+
1facf9fc 4805+struct au_opt_xino;
1facf9fc 4806+void au_xino_clr(struct super_block *sb);
062440b3 4807+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount);
1facf9fc 4808+struct file *au_xino_def(struct super_block *sb);
062440b3
AM
4809+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t hino,
4810+ struct path *base);
4811+
4812+ino_t au_xino_new_ino(struct super_block *sb);
4813+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 4814+
521ced18
JR
4815+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
4816+ ino_t h_ino, int idx);
4817+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4818+ int *idx);
4819+
062440b3
AM
4820+int au_xino_path(struct seq_file *seq, struct file *file);
4821+
1facf9fc 4822+/* ---------------------------------------------------------------------- */
4823+
acd2b654
AM
4824+/* @idx is signed to accept -1 meaning the first file */
4825+static inline struct file *au_xino_file(struct au_xino *xi, int idx)
4826+{
4827+ struct file *file;
4828+
4829+ file = NULL;
4830+ if (!xi)
4831+ goto out;
4832+
4833+ if (idx >= 0) {
4834+ if (idx < xi->xi_nfile)
4835+ file = xi->xi_file[idx];
4836+ } else
4837+ file = au_xino_file1(xi);
4838+
4839+out:
4840+ return file;
4841+}
4842+
4843+/* ---------------------------------------------------------------------- */
4844+
1facf9fc 4845+/* Superblock to branch */
4846+static inline
4847+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
4848+{
4849+ return au_sbr(sb, bindex)->br_id;
4850+}
4851+
4852+static inline
4853+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
4854+{
86dc4139 4855+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 4856+}
4857+
4858+static inline
4859+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
4860+{
86dc4139 4861+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 4862+}
4863+
1facf9fc 4864+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
4865+{
4866+ return au_sbr(sb, bindex)->br_perm;
4867+}
4868+
4869+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
4870+{
4871+ return au_br_whable(au_sbr_perm(sb, bindex));
4872+}
4873+
4874+/* ---------------------------------------------------------------------- */
4875+
8b6a4947
AM
4876+#define wbr_wh_read_lock(wbr) au_rw_read_lock(&(wbr)->wbr_wh_rwsem)
4877+#define wbr_wh_write_lock(wbr) au_rw_write_lock(&(wbr)->wbr_wh_rwsem)
4878+#define wbr_wh_read_trylock(wbr) au_rw_read_trylock(&(wbr)->wbr_wh_rwsem)
4879+#define wbr_wh_write_trylock(wbr) au_rw_write_trylock(&(wbr)->wbr_wh_rwsem)
1facf9fc 4880+/*
8b6a4947
AM
4881+#define wbr_wh_read_trylock_nested(wbr) \
4882+ au_rw_read_trylock_nested(&(wbr)->wbr_wh_rwsem)
4883+#define wbr_wh_write_trylock_nested(wbr) \
4884+ au_rw_write_trylock_nested(&(wbr)->wbr_wh_rwsem)
4885+*/
1facf9fc 4886+
8b6a4947
AM
4887+#define wbr_wh_read_unlock(wbr) au_rw_read_unlock(&(wbr)->wbr_wh_rwsem)
4888+#define wbr_wh_write_unlock(wbr) au_rw_write_unlock(&(wbr)->wbr_wh_rwsem)
4889+#define wbr_wh_downgrade_lock(wbr) au_rw_dgrade_lock(&(wbr)->wbr_wh_rwsem)
4890+
4891+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&(wbr)->wbr_wh_rwsem)
4892+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&(wbr)->wbr_wh_rwsem)
4893+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&(wbr)->wbr_wh_rwsem)
dece6358 4894+
076b876e
AM
4895+/* ---------------------------------------------------------------------- */
4896+
4897+#ifdef CONFIG_AUFS_FHSM
4898+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
4899+{
4900+ mutex_init(&brfhsm->bf_lock);
4901+ brfhsm->bf_jiffy = 0;
4902+ brfhsm->bf_readable = 0;
4903+}
4904+
4905+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
4906+{
4907+ mutex_destroy(&brfhsm->bf_lock);
4908+}
4909+#else
4910+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
4911+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
4912+#endif
4913+
1facf9fc 4914+#endif /* __KERNEL__ */
4915+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
4916diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
4917--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
b00004a5 4918+++ linux/fs/aufs/conf.mk 2018-06-04 09:08:09.181412645 +0200
2121bcd9
AM
4919@@ -0,0 +1,40 @@
4920+# SPDX-License-Identifier: GPL-2.0
4a4d8108
AM
4921+
4922+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
4923+
4924+define AuConf
4925+ifdef ${1}
4926+AuConfStr += ${1}=${${1}}
4927+endif
4928+endef
4929+
b752ccd1 4930+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 4931+ SBILIST \
7f207e10 4932+ HNOTIFY HFSNOTIFY \
4a4d8108 4933+ EXPORT INO_T_64 \
c1595e42 4934+ XATTR \
076b876e 4935+ FHSM \
4a4d8108 4936+ RDU \
8b6a4947 4937+ DIRREN \
4a4d8108
AM
4938+ SHWH \
4939+ BR_RAMFS \
4940+ BR_FUSE POLL \
4941+ BR_HFSPLUS \
4942+ BDEV_LOOP \
b752ccd1
AM
4943+ DEBUG MAGIC_SYSRQ
4944+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
4945+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
4946+
4947+AuConfName = ${obj}/conf.str
4948+${AuConfName}.tmp: FORCE
4949+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
4950+${AuConfName}: ${AuConfName}.tmp
4951+ @diff -q $< $@ > /dev/null 2>&1 || { \
4952+ echo ' GEN ' $@; \
4953+ cp -p $< $@; \
4954+ }
4955+FORCE:
4956+clean-files += ${AuConfName} ${AuConfName}.tmp
4957+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
4958+
4959+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
4960diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
4961--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 4962+++ linux/fs/aufs/cpup.c 2019-03-05 12:13:00.135890907 +0100
9f237c51 4963@@ -0,0 +1,1458 @@
cd7a4cd9 4964+// SPDX-License-Identifier: GPL-2.0
1facf9fc 4965+/*
ba1aed25 4966+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 4967+ *
4968+ * This program, aufs is free software; you can redistribute it and/or modify
4969+ * it under the terms of the GNU General Public License as published by
4970+ * the Free Software Foundation; either version 2 of the License, or
4971+ * (at your option) any later version.
dece6358
AM
4972+ *
4973+ * This program is distributed in the hope that it will be useful,
4974+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4975+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4976+ * GNU General Public License for more details.
4977+ *
4978+ * You should have received a copy of the GNU General Public License
523b37e3 4979+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4980+ */
4981+
4982+/*
4983+ * copy-up functions, see wbr_policy.c for copy-down
4984+ */
4985+
4986+#include <linux/fs_stack.h>
dece6358 4987+#include <linux/mm.h>
8cdd5066 4988+#include <linux/task_work.h>
1facf9fc 4989+#include "aufs.h"
4990+
86dc4139 4991+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 4992+{
4993+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 4994+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 4995+
86dc4139
AM
4996+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
4997+
4998+ dst->i_flags |= iflags & ~mask;
1facf9fc 4999+ if (au_test_fs_notime(dst->i_sb))
5000+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
5001+}
5002+
5003+void au_cpup_attr_timesizes(struct inode *inode)
5004+{
5005+ struct inode *h_inode;
5006+
5afbbe0d 5007+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 5008+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 5009+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 5010+}
5011+
5012+void au_cpup_attr_nlink(struct inode *inode, int force)
5013+{
5014+ struct inode *h_inode;
5015+ struct super_block *sb;
5afbbe0d 5016+ aufs_bindex_t bindex, bbot;
1facf9fc 5017+
5018+ sb = inode->i_sb;
5afbbe0d 5019+ bindex = au_ibtop(inode);
1facf9fc 5020+ h_inode = au_h_iptr(inode, bindex);
5021+ if (!force
5022+ && !S_ISDIR(h_inode->i_mode)
5023+ && au_opt_test(au_mntflags(sb), PLINK)
5024+ && au_plink_test(inode))
5025+ return;
5026+
7eafdf33
AM
5027+ /*
5028+ * 0 can happen in revalidating.
38d290e6
JR
5029+ * h_inode->i_mutex may not be held here, but it is harmless since once
5030+ * i_nlink reaches 0, it will never become positive except O_TMPFILE
5031+ * case.
5032+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
5033+ * the incorrect link count.
7eafdf33 5034+ */
92d182d2 5035+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 5036+
5037+ /*
5038+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
5039+ * it may includes whplink directory.
5040+ */
5041+ if (S_ISDIR(h_inode->i_mode)) {
5afbbe0d
AM
5042+ bbot = au_ibbot(inode);
5043+ for (bindex++; bindex <= bbot; bindex++) {
1facf9fc 5044+ h_inode = au_h_iptr(inode, bindex);
5045+ if (h_inode)
5046+ au_add_nlink(inode, h_inode);
5047+ }
5048+ }
5049+}
5050+
5051+void au_cpup_attr_changeable(struct inode *inode)
5052+{
5053+ struct inode *h_inode;
5054+
5afbbe0d 5055+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 5056+ inode->i_mode = h_inode->i_mode;
5057+ inode->i_uid = h_inode->i_uid;
5058+ inode->i_gid = h_inode->i_gid;
5059+ au_cpup_attr_timesizes(inode);
86dc4139 5060+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 5061+}
5062+
5063+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
5064+{
5065+ struct au_iinfo *iinfo = au_ii(inode);
5066+
1308ab2a 5067+ IiMustWriteLock(inode);
5068+
1facf9fc 5069+ iinfo->ii_higen = h_inode->i_generation;
5070+ iinfo->ii_hsb1 = h_inode->i_sb;
5071+}
5072+
5073+void au_cpup_attr_all(struct inode *inode, int force)
5074+{
5075+ struct inode *h_inode;
5076+
5afbbe0d 5077+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 5078+ au_cpup_attr_changeable(inode);
5079+ if (inode->i_nlink > 0)
5080+ au_cpup_attr_nlink(inode, force);
5081+ inode->i_rdev = h_inode->i_rdev;
5082+ inode->i_blkbits = h_inode->i_blkbits;
5083+ au_cpup_igen(inode, h_inode);
5084+}
5085+
5086+/* ---------------------------------------------------------------------- */
5087+
5088+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
5089+
5090+/* keep the timestamps of the parent dir when cpup */
5091+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
5092+ struct path *h_path)
5093+{
5094+ struct inode *h_inode;
5095+
5096+ dt->dt_dentry = dentry;
5097+ dt->dt_h_path = *h_path;
5527c038 5098+ h_inode = d_inode(h_path->dentry);
1facf9fc 5099+ dt->dt_atime = h_inode->i_atime;
5100+ dt->dt_mtime = h_inode->i_mtime;
5101+ /* smp_mb(); */
5102+}
5103+
5104+void au_dtime_revert(struct au_dtime *dt)
5105+{
5106+ struct iattr attr;
5107+ int err;
5108+
5109+ attr.ia_atime = dt->dt_atime;
5110+ attr.ia_mtime = dt->dt_mtime;
5111+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
5112+ | ATTR_ATIME | ATTR_ATIME_SET;
5113+
523b37e3
AM
5114+ /* no delegation since this is a directory */
5115+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 5116+ if (unlikely(err))
0c3ec466 5117+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 5118+}
5119+
5120+/* ---------------------------------------------------------------------- */
5121+
86dc4139
AM
5122+/* internal use only */
5123+struct au_cpup_reg_attr {
5124+ int valid;
5125+ struct kstat st;
5126+ unsigned int iflags; /* inode->i_flags */
5127+};
5128+
1facf9fc 5129+static noinline_for_stack
86dc4139
AM
5130+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
5131+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5132+{
c1595e42 5133+ int err, sbits, icex;
7e9cd9fe
AM
5134+ unsigned int mnt_flags;
5135+ unsigned char verbose;
1facf9fc 5136+ struct iattr ia;
5137+ struct path h_path;
1308ab2a 5138+ struct inode *h_isrc, *h_idst;
86dc4139 5139+ struct kstat *h_st;
c1595e42 5140+ struct au_branch *br;
1facf9fc 5141+
5142+ h_path.dentry = au_h_dptr(dst, bindex);
5527c038 5143+ h_idst = d_inode(h_path.dentry);
c1595e42
JR
5144+ br = au_sbr(dst->d_sb, bindex);
5145+ h_path.mnt = au_br_mnt(br);
5527c038 5146+ h_isrc = d_inode(h_src);
1308ab2a 5147+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 5148+ | ATTR_ATIME | ATTR_MTIME
5149+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
5150+ if (h_src_attr && h_src_attr->valid) {
5151+ h_st = &h_src_attr->st;
5152+ ia.ia_uid = h_st->uid;
5153+ ia.ia_gid = h_st->gid;
5154+ ia.ia_atime = h_st->atime;
5155+ ia.ia_mtime = h_st->mtime;
5156+ if (h_idst->i_mode != h_st->mode
5157+ && !S_ISLNK(h_idst->i_mode)) {
5158+ ia.ia_valid |= ATTR_MODE;
5159+ ia.ia_mode = h_st->mode;
5160+ }
5161+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
5162+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
5163+ } else {
5164+ ia.ia_uid = h_isrc->i_uid;
5165+ ia.ia_gid = h_isrc->i_gid;
5166+ ia.ia_atime = h_isrc->i_atime;
5167+ ia.ia_mtime = h_isrc->i_mtime;
5168+ if (h_idst->i_mode != h_isrc->i_mode
5169+ && !S_ISLNK(h_idst->i_mode)) {
5170+ ia.ia_valid |= ATTR_MODE;
5171+ ia.ia_mode = h_isrc->i_mode;
5172+ }
5173+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
5174+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 5175+ }
523b37e3
AM
5176+ /* no delegation since it is just created */
5177+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 5178+
5179+ /* is this nfs only? */
5180+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
5181+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
5182+ ia.ia_mode = h_isrc->i_mode;
523b37e3 5183+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 5184+ }
5185+
c1595e42 5186+ icex = br->br_perm & AuBrAttr_ICEX;
7e9cd9fe
AM
5187+ if (!err) {
5188+ mnt_flags = au_mntflags(dst->d_sb);
5189+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
5190+ err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose);
5191+ }
c1595e42 5192+
1facf9fc 5193+ return err;
5194+}
5195+
5196+/* ---------------------------------------------------------------------- */
5197+
5198+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
5199+ char *buf, unsigned long blksize)
5200+{
5201+ int err;
5202+ size_t sz, rbytes, wbytes;
5203+ unsigned char all_zero;
5204+ char *p, *zp;
febd17d6 5205+ struct inode *h_inode;
1facf9fc 5206+ /* reduce stack usage */
5207+ struct iattr *ia;
5208+
5209+ zp = page_address(ZERO_PAGE(0));
5210+ if (unlikely(!zp))
5211+ return -ENOMEM; /* possible? */
5212+
5213+ err = 0;
5214+ all_zero = 0;
5215+ while (len) {
5216+ AuDbg("len %lld\n", len);
5217+ sz = blksize;
5218+ if (len < blksize)
5219+ sz = len;
5220+
5221+ rbytes = 0;
5222+ /* todo: signal_pending? */
5223+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
5224+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
5225+ err = rbytes;
5226+ }
5227+ if (unlikely(err < 0))
5228+ break;
5229+
5230+ all_zero = 0;
5231+ if (len >= rbytes && rbytes == blksize)
5232+ all_zero = !memcmp(buf, zp, rbytes);
5233+ if (!all_zero) {
5234+ wbytes = rbytes;
5235+ p = buf;
5236+ while (wbytes) {
5237+ size_t b;
5238+
5239+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
5240+ err = b;
5241+ /* todo: signal_pending? */
5242+ if (unlikely(err == -EAGAIN || err == -EINTR))
5243+ continue;
5244+ if (unlikely(err < 0))
5245+ break;
5246+ wbytes -= b;
5247+ p += b;
5248+ }
392086de
AM
5249+ if (unlikely(err < 0))
5250+ break;
1facf9fc 5251+ } else {
5252+ loff_t res;
5253+
5254+ AuLabel(hole);
5255+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
5256+ err = res;
5257+ if (unlikely(res < 0))
5258+ break;
5259+ }
5260+ len -= rbytes;
5261+ err = 0;
5262+ }
5263+
5264+ /* the last block may be a hole */
5265+ if (!err && all_zero) {
5266+ AuLabel(last hole);
5267+
5268+ err = 1;
2000de60 5269+ if (au_test_nfs(dst->f_path.dentry->d_sb)) {
1facf9fc 5270+ /* nfs requires this step to make last hole */
5271+ /* is this only nfs? */
5272+ do {
5273+ /* todo: signal_pending? */
5274+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
5275+ } while (err == -EAGAIN || err == -EINTR);
5276+ if (err == 1)
5277+ dst->f_pos--;
5278+ }
5279+
5280+ if (err == 1) {
5281+ ia = (void *)buf;
5282+ ia->ia_size = dst->f_pos;
5283+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
5284+ ia->ia_file = dst;
febd17d6
JR
5285+ h_inode = file_inode(dst);
5286+ inode_lock_nested(h_inode, AuLsc_I_CHILD2);
523b37e3
AM
5287+ /* no delegation since it is just created */
5288+ err = vfsub_notify_change(&dst->f_path, ia,
5289+ /*delegated*/NULL);
febd17d6 5290+ inode_unlock(h_inode);
1facf9fc 5291+ }
5292+ }
5293+
5294+ return err;
5295+}
5296+
5297+int au_copy_file(struct file *dst, struct file *src, loff_t len)
5298+{
5299+ int err;
5300+ unsigned long blksize;
5301+ unsigned char do_kfree;
5302+ char *buf;
9f237c51 5303+ struct super_block *h_sb;
1facf9fc 5304+
5305+ err = -ENOMEM;
9f237c51
AM
5306+ h_sb = file_inode(dst)->i_sb;
5307+ blksize = h_sb->s_blocksize;
1facf9fc 5308+ if (!blksize || PAGE_SIZE < blksize)
5309+ blksize = PAGE_SIZE;
5310+ AuDbg("blksize %lu\n", blksize);
5311+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
5312+ if (do_kfree)
5313+ buf = kmalloc(blksize, GFP_NOFS);
5314+ else
5315+ buf = (void *)__get_free_page(GFP_NOFS);
5316+ if (unlikely(!buf))
5317+ goto out;
5318+
5319+ if (len > (1 << 22))
5320+ AuDbg("copying a large file %lld\n", (long long)len);
5321+
5322+ src->f_pos = 0;
5323+ dst->f_pos = 0;
5324+ err = au_do_copy_file(dst, src, len, buf, blksize);
9f237c51
AM
5325+ if (do_kfree) {
5326+ AuDebugOn(!au_kfree_do_sz_test(blksize));
5327+ au_kfree_do_rcu(buf);
5328+ } else
1c60b727 5329+ free_page((unsigned long)buf);
1facf9fc 5330+
4f0767ce 5331+out:
1facf9fc 5332+ return err;
5333+}
5334+
1c60b727
AM
5335+static int au_do_copy(struct file *dst, struct file *src, loff_t len)
5336+{
5337+ int err;
5338+ struct super_block *h_src_sb;
5339+ struct inode *h_src_inode;
5340+
5341+ h_src_inode = file_inode(src);
5342+ h_src_sb = h_src_inode->i_sb;
5343+
5344+ /* XFS acquires inode_lock */
5345+ if (!au_test_xfs(h_src_sb))
5346+ err = au_copy_file(dst, src, len);
5347+ else {
3c1bdaff 5348+ inode_unlock_shared(h_src_inode);
1c60b727 5349+ err = au_copy_file(dst, src, len);
be118d29 5350+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
1c60b727
AM
5351+ }
5352+
5353+ return err;
5354+}
5355+
5356+static int au_clone_or_copy(struct file *dst, struct file *src, loff_t len)
5357+{
5358+ int err;
9f237c51 5359+ loff_t lo;
1c60b727
AM
5360+ struct super_block *h_src_sb;
5361+ struct inode *h_src_inode;
5362+
5363+ h_src_inode = file_inode(src);
5364+ h_src_sb = h_src_inode->i_sb;
5365+ if (h_src_sb != file_inode(dst)->i_sb
9f237c51 5366+ || !dst->f_op->remap_file_range) {
1c60b727
AM
5367+ err = au_do_copy(dst, src, len);
5368+ goto out;
5369+ }
5370+
5371+ if (!au_test_nfs(h_src_sb)) {
3c1bdaff 5372+ inode_unlock_shared(h_src_inode);
9f237c51 5373+ lo = vfsub_clone_file_range(src, dst, len);
be118d29 5374+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
1c60b727 5375+ } else
9f237c51
AM
5376+ lo = vfsub_clone_file_range(src, dst, len);
5377+ if (lo == len) {
5378+ err = 0;
5379+ goto out; /* success */
5380+ } else if (lo >= 0)
5381+ /* todo: possible? */
5382+ /* paritially succeeded */
5383+ AuDbg("lo %lld, len %lld. Retrying.\n", lo, len);
5384+ else if (lo != -EOPNOTSUPP) {
5385+ /* older XFS has a condition in cloning */
5386+ err = lo;
1c60b727 5387+ goto out;
9f237c51 5388+ }
1c60b727
AM
5389+
5390+ /* the backend fs on NFS may not support cloning */
5391+ err = au_do_copy(dst, src, len);
5392+
5393+out:
5394+ AuTraceErr(err);
5395+ return err;
5396+}
5397+
1facf9fc 5398+/*
5399+ * to support a sparse file which is opened with O_APPEND,
5400+ * we need to close the file.
5401+ */
c2b27bf2 5402+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 5403+{
5404+ int err, i;
5405+ enum { SRC, DST };
5406+ struct {
5407+ aufs_bindex_t bindex;
5408+ unsigned int flags;
5409+ struct dentry *dentry;
392086de 5410+ int force_wr;
1facf9fc 5411+ struct file *file;
1facf9fc 5412+ } *f, file[] = {
5413+ {
c2b27bf2 5414+ .bindex = cpg->bsrc,
1facf9fc 5415+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
1facf9fc 5416+ },
5417+ {
c2b27bf2 5418+ .bindex = cpg->bdst,
1facf9fc 5419+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 5420+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
1facf9fc 5421+ }
5422+ };
acd2b654 5423+ struct au_branch *br;
521ced18 5424+ struct super_block *sb, *h_src_sb;
e2f27e51 5425+ struct inode *h_src_inode;
8cdd5066 5426+ struct task_struct *tsk = current;
1facf9fc 5427+
5428+ /* bsrc branch can be ro/rw. */
c2b27bf2 5429+ sb = cpg->dentry->d_sb;
1facf9fc 5430+ f = file;
5431+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
5432+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
5433+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 5434+ /*file*/NULL, f->force_wr);
9f237c51
AM
5435+ if (IS_ERR(f->file)) {
5436+ err = PTR_ERR(f->file);
5437+ if (i == SRC)
5438+ goto out;
5439+ else
5440+ goto out_src;
5441+ }
1facf9fc 5442+ }
5443+
5444+ /* try stopping to update while we copyup */
e2f27e51 5445+ h_src_inode = d_inode(file[SRC].dentry);
521ced18
JR
5446+ h_src_sb = h_src_inode->i_sb;
5447+ if (!au_test_nfs(h_src_sb))
e2f27e51 5448+ IMustLock(h_src_inode);
1c60b727 5449+ err = au_clone_or_copy(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 5450+
8cdd5066
JR
5451+ /* i wonder if we had O_NO_DELAY_FPUT flag */
5452+ if (tsk->flags & PF_KTHREAD)
5453+ __fput_sync(file[DST].file);
5454+ else {
062440b3 5455+ /* it happened actually */
8cdd5066
JR
5456+ fput(file[DST].file);
5457+ /*
5458+ * too bad.
5459+ * we have to call both since we don't know which place the file
5460+ * was added to.
5461+ */
5462+ task_work_run();
5463+ flush_delayed_fput();
5464+ }
acd2b654
AM
5465+ br = au_sbr(sb, file[DST].bindex);
5466+ au_lcnt_dec(&br->br_nfiles);
523b37e3 5467+
4f0767ce 5468+out_src:
1facf9fc 5469+ fput(file[SRC].file);
acd2b654
AM
5470+ br = au_sbr(sb, file[SRC].bindex);
5471+ au_lcnt_dec(&br->br_nfiles);
4f0767ce 5472+out:
1facf9fc 5473+ return err;
5474+}
5475+
c2b27bf2 5476+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 5477+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5478+{
5479+ int err, rerr;
5480+ loff_t l;
86dc4139 5481+ struct path h_path;
38d290e6 5482+ struct inode *h_src_inode, *h_dst_inode;
1facf9fc 5483+
5484+ err = 0;
5527c038 5485+ h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc);
86dc4139 5486+ l = i_size_read(h_src_inode);
c2b27bf2
AM
5487+ if (cpg->len == -1 || l < cpg->len)
5488+ cpg->len = l;
5489+ if (cpg->len) {
86dc4139 5490+ /* try stopping to update while we are referencing */
be118d29 5491+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
c2b27bf2 5492+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 5493+
c2b27bf2
AM
5494+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5495+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139 5496+ h_src_attr->iflags = h_src_inode->i_flags;
5527c038 5497+ if (!au_test_nfs(h_src_inode->i_sb))
521ced18 5498+ err = vfsub_getattr(&h_path, &h_src_attr->st);
5527c038 5499+ else {
3c1bdaff 5500+ inode_unlock_shared(h_src_inode);
521ced18 5501+ err = vfsub_getattr(&h_path, &h_src_attr->st);
be118d29 5502+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
5527c038 5503+ }
86dc4139 5504+ if (unlikely(err)) {
3c1bdaff 5505+ inode_unlock_shared(h_src_inode);
86dc4139
AM
5506+ goto out;
5507+ }
5508+ h_src_attr->valid = 1;
e2f27e51
AM
5509+ if (!au_test_nfs(h_src_inode->i_sb)) {
5510+ err = au_cp_regular(cpg);
3c1bdaff 5511+ inode_unlock_shared(h_src_inode);
e2f27e51 5512+ } else {
3c1bdaff 5513+ inode_unlock_shared(h_src_inode);
e2f27e51
AM
5514+ err = au_cp_regular(cpg);
5515+ }
c2b27bf2 5516+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
5517+ if (!err && rerr)
5518+ err = rerr;
1facf9fc 5519+ }
38d290e6
JR
5520+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
5521+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
5527c038 5522+ h_dst_inode = d_inode(h_path.dentry);
38d290e6
JR
5523+ spin_lock(&h_dst_inode->i_lock);
5524+ h_dst_inode->i_state |= I_LINKABLE;
5525+ spin_unlock(&h_dst_inode->i_lock);
5526+ }
1facf9fc 5527+
4f0767ce 5528+out:
1facf9fc 5529+ return err;
5530+}
5531+
5532+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
5533+ struct inode *h_dir)
5534+{
5535+ int err, symlen;
5536+ mm_segment_t old_fs;
b752ccd1
AM
5537+ union {
5538+ char *k;
5539+ char __user *u;
5540+ } sym;
1facf9fc 5541+
5542+ err = -ENOMEM;
537831f9 5543+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 5544+ if (unlikely(!sym.k))
1facf9fc 5545+ goto out;
5546+
9dbd164d 5547+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 5548+ old_fs = get_fs();
5549+ set_fs(KERNEL_DS);
a2654f78 5550+ symlen = vfs_readlink(h_src, sym.u, PATH_MAX);
1facf9fc 5551+ err = symlen;
5552+ set_fs(old_fs);
5553+
5554+ if (symlen > 0) {
b752ccd1
AM
5555+ sym.k[symlen] = 0;
5556+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 5557+ }
1c60b727 5558+ free_page((unsigned long)sym.k);
1facf9fc 5559+
4f0767ce 5560+out:
1facf9fc 5561+ return err;
5562+}
5563+
8cdd5066
JR
5564+/*
5565+ * regardless 'acl' option, reset all ACL.
5566+ * All ACL will be copied up later from the original entry on the lower branch.
5567+ */
5568+static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode)
5569+{
5570+ int err;
5571+ struct dentry *h_dentry;
5572+ struct inode *h_inode;
5573+
5574+ h_dentry = h_path->dentry;
5575+ h_inode = d_inode(h_dentry);
5576+ /* forget_all_cached_acls(h_inode)); */
5577+ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS);
5578+ AuTraceErr(err);
5579+ if (err == -EOPNOTSUPP)
5580+ err = 0;
5581+ if (!err)
5582+ err = vfsub_acl_chmod(h_inode, mode);
5583+
5584+ AuTraceErr(err);
5585+ return err;
5586+}
5587+
5588+static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent,
5589+ struct inode *h_dir, struct path *h_path)
5590+{
5591+ int err;
5592+ struct inode *dir, *inode;
5593+
5594+ err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT);
5595+ AuTraceErr(err);
5596+ if (err == -EOPNOTSUPP)
5597+ err = 0;
5598+ if (unlikely(err))
5599+ goto out;
5600+
5601+ /*
5602+ * strange behaviour from the users view,
acd2b654 5603+ * particularly setattr case
8cdd5066
JR
5604+ */
5605+ dir = d_inode(dst_parent);
5afbbe0d 5606+ if (au_ibtop(dir) == cpg->bdst)
8cdd5066
JR
5607+ au_cpup_attr_nlink(dir, /*force*/1);
5608+ inode = d_inode(cpg->dentry);
5609+ au_cpup_attr_nlink(inode, /*force*/1);
5610+
5611+out:
5612+ return err;
5613+}
5614+
1facf9fc 5615+static noinline_for_stack
c2b27bf2 5616+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 5617+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5618+{
5619+ int err;
5620+ umode_t mode;
5621+ unsigned int mnt_flags;
076b876e 5622+ unsigned char isdir, isreg, force;
c2b27bf2 5623+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5624+ struct au_dtime dt;
5625+ struct path h_path;
5626+ struct dentry *h_src, *h_dst, *h_parent;
8cdd5066 5627+ struct inode *h_inode, *h_dir;
1facf9fc 5628+ struct super_block *sb;
5629+
5630+ /* bsrc branch can be ro/rw. */
c2b27bf2 5631+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038
JR
5632+ h_inode = d_inode(h_src);
5633+ AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc));
1facf9fc 5634+
5635+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
5636+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
5637+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
5638+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
5639+ AUFS_WH_PFX_LEN));
1facf9fc 5640+ h_parent = h_dst->d_parent; /* dir inode is locked */
5527c038 5641+ h_dir = d_inode(h_parent);
1facf9fc 5642+ IMustLock(h_dir);
5643+ AuDebugOn(h_parent != h_dst->d_parent);
5644+
c2b27bf2
AM
5645+ sb = cpg->dentry->d_sb;
5646+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 5647+ if (do_dt) {
5648+ h_path.dentry = h_parent;
5649+ au_dtime_store(&dt, dst_parent, &h_path);
5650+ }
5651+ h_path.dentry = h_dst;
5652+
076b876e 5653+ isreg = 0;
1facf9fc 5654+ isdir = 0;
5655+ mode = h_inode->i_mode;
5656+ switch (mode & S_IFMT) {
5657+ case S_IFREG:
076b876e 5658+ isreg = 1;
cd7a4cd9 5659+ err = vfsub_create(h_dir, &h_path, 0600, /*want_excl*/true);
1facf9fc 5660+ if (!err)
c2b27bf2 5661+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 5662+ break;
5663+ case S_IFDIR:
5664+ isdir = 1;
5665+ err = vfsub_mkdir(h_dir, &h_path, mode);
8cdd5066
JR
5666+ if (!err)
5667+ err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path);
1facf9fc 5668+ break;
5669+ case S_IFLNK:
5670+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
5671+ break;
5672+ case S_IFCHR:
5673+ case S_IFBLK:
5674+ AuDebugOn(!capable(CAP_MKNOD));
5675+ /*FALLTHROUGH*/
5676+ case S_IFIFO:
5677+ case S_IFSOCK:
5678+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
5679+ break;
5680+ default:
5681+ AuIOErr("Unknown inode type 0%o\n", mode);
5682+ err = -EIO;
5683+ }
8cdd5066
JR
5684+ if (!err)
5685+ err = au_reset_acl(h_dir, &h_path, mode);
1facf9fc 5686+
5687+ mnt_flags = au_mntflags(sb);
5688+ if (!au_opt_test(mnt_flags, UDBA_NONE)
5689+ && !isdir
5690+ && au_opt_test(mnt_flags, XINO)
38d290e6
JR
5691+ && (h_inode->i_nlink == 1
5692+ || (h_inode->i_state & I_LINKABLE))
1facf9fc 5693+ /* todo: unnecessary? */
5527c038 5694+ /* && d_inode(cpg->dentry)->i_nlink == 1 */
c2b27bf2
AM
5695+ && cpg->bdst < cpg->bsrc
5696+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
5697+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 5698+ /* ignore this error */
5699+
076b876e
AM
5700+ if (!err) {
5701+ force = 0;
5702+ if (isreg) {
5703+ force = !!cpg->len;
5704+ if (cpg->len == -1)
5705+ force = !!i_size_read(h_inode);
5706+ }
5707+ au_fhsm_wrote(sb, cpg->bdst, force);
5708+ }
5709+
1facf9fc 5710+ if (do_dt)
5711+ au_dtime_revert(&dt);
5712+ return err;
5713+}
5714+
392086de 5715+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
5716+{
5717+ int err;
392086de 5718+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 5719+ struct inode *h_dir;
392086de 5720+ aufs_bindex_t bdst;
86dc4139 5721+
392086de
AM
5722+ dentry = cpg->dentry;
5723+ bdst = cpg->bdst;
5724+ h_dentry = au_h_dptr(dentry, bdst);
5725+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
5726+ dget(h_dentry);
5727+ au_set_h_dptr(dentry, bdst, NULL);
5728+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
5729+ if (!err)
5730+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 5731+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
5732+ } else {
5733+ err = 0;
5734+ parent = dget_parent(dentry);
5735+ h_parent = au_h_dptr(parent, bdst);
5736+ dput(parent);
5737+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
5738+ if (IS_ERR(h_path->dentry))
5739+ err = PTR_ERR(h_path->dentry);
86dc4139 5740+ }
392086de
AM
5741+ if (unlikely(err))
5742+ goto out;
86dc4139 5743+
86dc4139 5744+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5527c038 5745+ h_dir = d_inode(h_parent);
86dc4139 5746+ IMustLock(h_dir);
523b37e3
AM
5747+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
5748+ /* no delegation since it is just created */
f2c43d5f
AM
5749+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL,
5750+ /*flags*/0);
86dc4139
AM
5751+ dput(h_path->dentry);
5752+
5753+out:
5754+ return err;
5755+}
5756+
1facf9fc 5757+/*
5758+ * copyup the @dentry from @bsrc to @bdst.
5759+ * the caller must set the both of lower dentries.
5760+ * @len is for truncating when it is -1 copyup the entire file.
5761+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 5762+ * basic->bsrc can be larger than basic->bdst.
f2c43d5f 5763+ * aufs doesn't touch the credential so
acd2b654 5764+ * security_inode_copy_up{,_xattr}() are unnecessary.
1facf9fc 5765+ */
c2b27bf2 5766+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5767+{
5768+ int err, rerr;
5afbbe0d 5769+ aufs_bindex_t old_ibtop;
1facf9fc 5770+ unsigned char isdir, plink;
1facf9fc 5771+ struct dentry *h_src, *h_dst, *h_parent;
5527c038 5772+ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode;
1facf9fc 5773+ struct super_block *sb;
86dc4139 5774+ struct au_branch *br;
acd2b654 5775+ /* to reduce stack size */
c2b27bf2
AM
5776+ struct {
5777+ struct au_dtime dt;
5778+ struct path h_path;
5779+ struct au_cpup_reg_attr h_src_attr;
5780+ } *a;
1facf9fc 5781+
c2b27bf2
AM
5782+ err = -ENOMEM;
5783+ a = kmalloc(sizeof(*a), GFP_NOFS);
5784+ if (unlikely(!a))
5785+ goto out;
5786+ a->h_src_attr.valid = 0;
1facf9fc 5787+
c2b27bf2
AM
5788+ sb = cpg->dentry->d_sb;
5789+ br = au_sbr(sb, cpg->bdst);
5790+ a->h_path.mnt = au_br_mnt(br);
5791+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 5792+ h_parent = h_dst->d_parent; /* dir inode is locked */
5527c038 5793+ h_dir = d_inode(h_parent);
1facf9fc 5794+ IMustLock(h_dir);
5795+
c2b27bf2 5796+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038 5797+ inode = d_inode(cpg->dentry);
1facf9fc 5798+
5799+ if (!dst_parent)
c2b27bf2 5800+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 5801+ else
5802+ dget(dst_parent);
5803+
5804+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 5805+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 5806+ if (dst_inode) {
5807+ if (unlikely(!plink)) {
5808+ err = -EIO;
027c5e7a
AM
5809+ AuIOErr("hi%lu(i%lu) exists on b%d "
5810+ "but plink is disabled\n",
c2b27bf2
AM
5811+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
5812+ goto out_parent;
1facf9fc 5813+ }
5814+
5815+ if (dst_inode->i_nlink) {
c2b27bf2 5816+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5817+
c2b27bf2 5818+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 5819+ err = PTR_ERR(h_src);
5820+ if (IS_ERR(h_src))
c2b27bf2 5821+ goto out_parent;
5527c038 5822+ if (unlikely(d_is_negative(h_src))) {
1facf9fc 5823+ err = -EIO;
79b8bda9 5824+ AuIOErr("i%lu exists on b%d "
027c5e7a 5825+ "but not pseudo-linked\n",
79b8bda9 5826+ inode->i_ino, cpg->bdst);
1facf9fc 5827+ dput(h_src);
c2b27bf2 5828+ goto out_parent;
1facf9fc 5829+ }
5830+
5831+ if (do_dt) {
c2b27bf2
AM
5832+ a->h_path.dentry = h_parent;
5833+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 5834+ }
86dc4139 5835+
c2b27bf2 5836+ a->h_path.dentry = h_dst;
523b37e3
AM
5837+ delegated = NULL;
5838+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 5839+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 5840+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 5841+ if (do_dt)
c2b27bf2 5842+ au_dtime_revert(&a->dt);
523b37e3
AM
5843+ if (unlikely(err == -EWOULDBLOCK)) {
5844+ pr_warn("cannot retry for NFSv4 delegation"
5845+ " for an internal link\n");
5846+ iput(delegated);
5847+ }
1facf9fc 5848+ dput(h_src);
c2b27bf2 5849+ goto out_parent;
1facf9fc 5850+ } else
5851+ /* todo: cpup_wh_file? */
5852+ /* udba work */
4a4d8108 5853+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 5854+ }
5855+
86dc4139 5856+ isdir = S_ISDIR(inode->i_mode);
5afbbe0d 5857+ old_ibtop = au_ibtop(inode);
c2b27bf2 5858+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 5859+ if (unlikely(err))
86dc4139 5860+ goto out_rev;
5527c038 5861+ dst_inode = d_inode(h_dst);
febd17d6 5862+ inode_lock_nested(dst_inode, AuLsc_I_CHILD2);
86dc4139 5863+ /* todo: necessary? */
c2b27bf2 5864+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 5865+
c2b27bf2 5866+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
5867+ if (unlikely(err)) {
5868+ /* todo: necessary? */
c2b27bf2 5869+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
febd17d6 5870+ inode_unlock(dst_inode);
86dc4139
AM
5871+ goto out_rev;
5872+ }
5873+
5afbbe0d 5874+ if (cpg->bdst < old_ibtop) {
86dc4139 5875+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 5876+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 5877+ if (unlikely(err)) {
c2b27bf2
AM
5878+ /* ignore an error */
5879+ /* au_pin_hdir_relock(cpg->pin); */
febd17d6 5880+ inode_unlock(dst_inode);
86dc4139 5881+ goto out_rev;
4a4d8108 5882+ }
4a4d8108 5883+ }
5afbbe0d 5884+ au_set_ibtop(inode, cpg->bdst);
c2b27bf2 5885+ } else
5afbbe0d 5886+ au_set_ibbot(inode, cpg->bdst);
c2b27bf2 5887+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
5888+ au_hi_flags(inode, isdir));
5889+
5890+ /* todo: necessary? */
c2b27bf2 5891+ /* err = au_pin_hdir_relock(cpg->pin); */
febd17d6 5892+ inode_unlock(dst_inode);
86dc4139
AM
5893+ if (unlikely(err))
5894+ goto out_rev;
5895+
5527c038 5896+ src_inode = d_inode(h_src);
86dc4139 5897+ if (!isdir
5527c038
JR
5898+ && (src_inode->i_nlink > 1
5899+ || src_inode->i_state & I_LINKABLE)
86dc4139 5900+ && plink)
c2b27bf2 5901+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 5902+
c2b27bf2
AM
5903+ if (au_ftest_cpup(cpg->flags, RENAME)) {
5904+ a->h_path.dentry = h_dst;
392086de 5905+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
5906+ }
5907+ if (!err)
c2b27bf2 5908+ goto out_parent; /* success */
1facf9fc 5909+
5910+ /* revert */
4a4d8108 5911+out_rev:
c2b27bf2
AM
5912+ a->h_path.dentry = h_parent;
5913+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5914+ a->h_path.dentry = h_dst;
86dc4139 5915+ rerr = 0;
5527c038 5916+ if (d_is_positive(h_dst)) {
523b37e3
AM
5917+ if (!isdir) {
5918+ /* no delegation since it is just created */
5919+ rerr = vfsub_unlink(h_dir, &a->h_path,
5920+ /*delegated*/NULL, /*force*/0);
5921+ } else
c2b27bf2 5922+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 5923+ }
c2b27bf2 5924+ au_dtime_revert(&a->dt);
1facf9fc 5925+ if (rerr) {
5926+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
5927+ err = -EIO;
5928+ }
c2b27bf2 5929+out_parent:
1facf9fc 5930+ dput(dst_parent);
9f237c51 5931+ au_kfree_rcu(a);
c2b27bf2 5932+out:
1facf9fc 5933+ return err;
5934+}
5935+
7e9cd9fe 5936+#if 0 /* reserved */
1facf9fc 5937+struct au_cpup_single_args {
5938+ int *errp;
c2b27bf2 5939+ struct au_cp_generic *cpg;
1facf9fc 5940+ struct dentry *dst_parent;
5941+};
5942+
5943+static void au_call_cpup_single(void *args)
5944+{
5945+ struct au_cpup_single_args *a = args;
86dc4139 5946+
c2b27bf2
AM
5947+ au_pin_hdir_acquire_nest(a->cpg->pin);
5948+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
5949+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5950+}
c2b27bf2 5951+#endif
1facf9fc 5952+
53392da6
AM
5953+/*
5954+ * prevent SIGXFSZ in copy-up.
5955+ * testing CAP_MKNOD is for generic fs,
5956+ * but CAP_FSETID is for xfs only, currently.
5957+ */
86dc4139 5958+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
5959+{
5960+ int do_sio;
86dc4139
AM
5961+ struct super_block *sb;
5962+ struct inode *h_dir;
53392da6
AM
5963+
5964+ do_sio = 0;
86dc4139 5965+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
5966+ if (!au_wkq_test()
5967+ && (!au_sbi(sb)->si_plink_maint_pid
5968+ || au_plink_maint(sb, AuLock_NOPLM))) {
5969+ switch (mode & S_IFMT) {
5970+ case S_IFREG:
5971+ /* no condition about RLIMIT_FSIZE and the file size */
5972+ do_sio = 1;
5973+ break;
5974+ case S_IFCHR:
5975+ case S_IFBLK:
5976+ do_sio = !capable(CAP_MKNOD);
5977+ break;
5978+ }
5979+ if (!do_sio)
5980+ do_sio = ((mode & (S_ISUID | S_ISGID))
5981+ && !capable(CAP_FSETID));
86dc4139
AM
5982+ /* this workaround may be removed in the future */
5983+ if (!do_sio) {
5984+ h_dir = au_pinned_h_dir(pin);
5985+ do_sio = h_dir->i_mode & S_ISVTX;
5986+ }
53392da6
AM
5987+ }
5988+
5989+ return do_sio;
5990+}
5991+
7e9cd9fe 5992+#if 0 /* reserved */
c2b27bf2 5993+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5994+{
5995+ int err, wkq_err;
1facf9fc 5996+ struct dentry *h_dentry;
5997+
c2b27bf2 5998+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038 5999+ if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode))
c2b27bf2 6000+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 6001+ else {
6002+ struct au_cpup_single_args args = {
6003+ .errp = &err,
c2b27bf2
AM
6004+ .cpg = cpg,
6005+ .dst_parent = dst_parent
1facf9fc 6006+ };
6007+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
6008+ if (unlikely(wkq_err))
6009+ err = wkq_err;
6010+ }
6011+
6012+ return err;
6013+}
c2b27bf2 6014+#endif
1facf9fc 6015+
6016+/*
6017+ * copyup the @dentry from the first active lower branch to @bdst,
6018+ * using au_cpup_single().
6019+ */
c2b27bf2 6020+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 6021+{
6022+ int err;
c2b27bf2
AM
6023+ unsigned int flags_orig;
6024+ struct dentry *dentry;
6025+
6026+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 6027+
c2b27bf2 6028+ dentry = cpg->dentry;
86dc4139 6029+ DiMustWriteLock(dentry);
1facf9fc 6030+
c2b27bf2 6031+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 6032+ if (!err) {
c2b27bf2
AM
6033+ flags_orig = cpg->flags;
6034+ au_fset_cpup(cpg->flags, RENAME);
6035+ err = au_cpup_single(cpg, NULL);
6036+ cpg->flags = flags_orig;
1facf9fc 6037+ if (!err)
6038+ return 0; /* success */
6039+
6040+ /* revert */
c2b27bf2 6041+ au_set_h_dptr(dentry, cpg->bdst, NULL);
5afbbe0d 6042+ au_set_dbtop(dentry, cpg->bsrc);
1facf9fc 6043+ }
6044+
6045+ return err;
6046+}
6047+
6048+struct au_cpup_simple_args {
6049+ int *errp;
c2b27bf2 6050+ struct au_cp_generic *cpg;
1facf9fc 6051+};
6052+
6053+static void au_call_cpup_simple(void *args)
6054+{
6055+ struct au_cpup_simple_args *a = args;
86dc4139 6056+
c2b27bf2
AM
6057+ au_pin_hdir_acquire_nest(a->cpg->pin);
6058+ *a->errp = au_cpup_simple(a->cpg);
6059+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 6060+}
6061+
c2b27bf2 6062+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 6063+{
6064+ int err, wkq_err;
c2b27bf2
AM
6065+ struct dentry *dentry, *parent;
6066+ struct file *h_file;
1facf9fc 6067+ struct inode *h_dir;
6068+
c2b27bf2
AM
6069+ dentry = cpg->dentry;
6070+ h_file = NULL;
6071+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
6072+ AuDebugOn(cpg->bsrc < 0);
392086de 6073+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
6074+ err = PTR_ERR(h_file);
6075+ if (IS_ERR(h_file))
6076+ goto out;
6077+ }
6078+
1facf9fc 6079+ parent = dget_parent(dentry);
5527c038 6080+ h_dir = au_h_iptr(d_inode(parent), cpg->bdst);
53392da6 6081+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
5527c038 6082+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
c2b27bf2 6083+ err = au_cpup_simple(cpg);
1facf9fc 6084+ else {
6085+ struct au_cpup_simple_args args = {
6086+ .errp = &err,
c2b27bf2 6087+ .cpg = cpg
1facf9fc 6088+ };
6089+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
6090+ if (unlikely(wkq_err))
6091+ err = wkq_err;
6092+ }
6093+
6094+ dput(parent);
c2b27bf2
AM
6095+ if (h_file)
6096+ au_h_open_post(dentry, cpg->bsrc, h_file);
6097+
6098+out:
1facf9fc 6099+ return err;
6100+}
6101+
c2b27bf2 6102+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 6103+{
5afbbe0d 6104+ aufs_bindex_t bsrc, bbot;
c2b27bf2 6105+ struct dentry *dentry, *h_dentry;
367653fa 6106+
c2b27bf2
AM
6107+ if (cpg->bsrc < 0) {
6108+ dentry = cpg->dentry;
5afbbe0d
AM
6109+ bbot = au_dbbot(dentry);
6110+ for (bsrc = cpg->bdst + 1; bsrc <= bbot; bsrc++) {
c2b27bf2
AM
6111+ h_dentry = au_h_dptr(dentry, bsrc);
6112+ if (h_dentry) {
5527c038 6113+ AuDebugOn(d_is_negative(h_dentry));
c2b27bf2
AM
6114+ break;
6115+ }
6116+ }
5afbbe0d 6117+ AuDebugOn(bsrc > bbot);
c2b27bf2 6118+ cpg->bsrc = bsrc;
367653fa 6119+ }
c2b27bf2
AM
6120+ AuDebugOn(cpg->bsrc <= cpg->bdst);
6121+ return au_do_sio_cpup_simple(cpg);
6122+}
367653fa 6123+
c2b27bf2
AM
6124+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
6125+{
6126+ AuDebugOn(cpg->bdst <= cpg->bsrc);
6127+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
6128+}
6129+
1facf9fc 6130+/* ---------------------------------------------------------------------- */
6131+
6132+/*
6133+ * copyup the deleted file for writing.
6134+ */
c2b27bf2
AM
6135+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
6136+ struct file *file)
1facf9fc 6137+{
6138+ int err;
c2b27bf2
AM
6139+ unsigned int flags_orig;
6140+ aufs_bindex_t bsrc_orig;
c2b27bf2 6141+ struct au_dinfo *dinfo;
5afbbe0d
AM
6142+ struct {
6143+ struct au_hdentry *hd;
6144+ struct dentry *h_dentry;
6145+ } hdst, hsrc;
1facf9fc 6146+
c2b27bf2 6147+ dinfo = au_di(cpg->dentry);
1308ab2a 6148+ AuRwMustWriteLock(&dinfo->di_rwsem);
6149+
c2b27bf2 6150+ bsrc_orig = cpg->bsrc;
5afbbe0d
AM
6151+ cpg->bsrc = dinfo->di_btop;
6152+ hdst.hd = au_hdentry(dinfo, cpg->bdst);
6153+ hdst.h_dentry = hdst.hd->hd_dentry;
6154+ hdst.hd->hd_dentry = wh_dentry;
6155+ dinfo->di_btop = cpg->bdst;
6156+
6157+ hsrc.h_dentry = NULL;
027c5e7a 6158+ if (file) {
5afbbe0d
AM
6159+ hsrc.hd = au_hdentry(dinfo, cpg->bsrc);
6160+ hsrc.h_dentry = hsrc.hd->hd_dentry;
6161+ hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry;
027c5e7a 6162+ }
c2b27bf2
AM
6163+ flags_orig = cpg->flags;
6164+ cpg->flags = !AuCpup_DTIME;
6165+ err = au_cpup_single(cpg, /*h_parent*/NULL);
6166+ cpg->flags = flags_orig;
027c5e7a
AM
6167+ if (file) {
6168+ if (!err)
6169+ err = au_reopen_nondir(file);
5afbbe0d 6170+ hsrc.hd->hd_dentry = hsrc.h_dentry;
1facf9fc 6171+ }
5afbbe0d
AM
6172+ hdst.hd->hd_dentry = hdst.h_dentry;
6173+ dinfo->di_btop = cpg->bsrc;
c2b27bf2 6174+ cpg->bsrc = bsrc_orig;
1facf9fc 6175+
6176+ return err;
6177+}
6178+
c2b27bf2 6179+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 6180+{
6181+ int err;
c2b27bf2 6182+ aufs_bindex_t bdst;
1facf9fc 6183+ struct au_dtime dt;
c2b27bf2 6184+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 6185+ struct au_branch *br;
6186+ struct path h_path;
6187+
c2b27bf2
AM
6188+ dentry = cpg->dentry;
6189+ bdst = cpg->bdst;
1facf9fc 6190+ br = au_sbr(dentry->d_sb, bdst);
6191+ parent = dget_parent(dentry);
6192+ h_parent = au_h_dptr(parent, bdst);
6193+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
6194+ err = PTR_ERR(wh_dentry);
6195+ if (IS_ERR(wh_dentry))
6196+ goto out;
6197+
6198+ h_path.dentry = h_parent;
86dc4139 6199+ h_path.mnt = au_br_mnt(br);
1facf9fc 6200+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 6201+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 6202+ if (unlikely(err))
6203+ goto out_wh;
6204+
6205+ dget(wh_dentry);
6206+ h_path.dentry = wh_dentry;
2000de60 6207+ if (!d_is_dir(wh_dentry)) {
523b37e3 6208+ /* no delegation since it is just created */
5527c038 6209+ err = vfsub_unlink(d_inode(h_parent), &h_path,
523b37e3
AM
6210+ /*delegated*/NULL, /*force*/0);
6211+ } else
5527c038 6212+ err = vfsub_rmdir(d_inode(h_parent), &h_path);
1facf9fc 6213+ if (unlikely(err)) {
523b37e3
AM
6214+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
6215+ wh_dentry, err);
1facf9fc 6216+ err = -EIO;
6217+ }
6218+ au_dtime_revert(&dt);
5527c038 6219+ au_set_hi_wh(d_inode(dentry), bdst, wh_dentry);
1facf9fc 6220+
4f0767ce 6221+out_wh:
1facf9fc 6222+ dput(wh_dentry);
4f0767ce 6223+out:
1facf9fc 6224+ dput(parent);
6225+ return err;
6226+}
6227+
6228+struct au_cpup_wh_args {
6229+ int *errp;
c2b27bf2 6230+ struct au_cp_generic *cpg;
1facf9fc 6231+ struct file *file;
6232+};
6233+
6234+static void au_call_cpup_wh(void *args)
6235+{
6236+ struct au_cpup_wh_args *a = args;
86dc4139 6237+
c2b27bf2
AM
6238+ au_pin_hdir_acquire_nest(a->cpg->pin);
6239+ *a->errp = au_cpup_wh(a->cpg, a->file);
6240+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 6241+}
6242+
c2b27bf2 6243+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 6244+{
6245+ int err, wkq_err;
c2b27bf2 6246+ aufs_bindex_t bdst;
c1595e42 6247+ struct dentry *dentry, *parent, *h_orph, *h_parent;
86dc4139 6248+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 6249+ struct au_wbr *wbr;
c2b27bf2 6250+ struct au_pin wh_pin, *pin_orig;
1facf9fc 6251+
c2b27bf2
AM
6252+ dentry = cpg->dentry;
6253+ bdst = cpg->bdst;
1facf9fc 6254+ parent = dget_parent(dentry);
5527c038 6255+ dir = d_inode(parent);
1facf9fc 6256+ h_orph = NULL;
6257+ h_parent = NULL;
6258+ h_dir = au_igrab(au_h_iptr(dir, bdst));
6259+ h_tmpdir = h_dir;
c2b27bf2 6260+ pin_orig = NULL;
1facf9fc 6261+ if (!h_dir->i_nlink) {
6262+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
6263+ h_orph = wbr->wbr_orph;
6264+
6265+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 6266+ au_set_h_dptr(parent, bdst, dget(h_orph));
5527c038 6267+ h_tmpdir = d_inode(h_orph);
1facf9fc 6268+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
6269+
febd17d6 6270+ inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3);
4a4d8108 6271+ /* todo: au_h_open_pre()? */
86dc4139 6272+
c2b27bf2 6273+ pin_orig = cpg->pin;
86dc4139 6274+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
6275+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
6276+ cpg->pin = &wh_pin;
1facf9fc 6277+ }
6278+
53392da6 6279+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
5527c038 6280+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
c2b27bf2 6281+ err = au_cpup_wh(cpg, file);
1facf9fc 6282+ else {
6283+ struct au_cpup_wh_args args = {
6284+ .errp = &err,
c2b27bf2
AM
6285+ .cpg = cpg,
6286+ .file = file
1facf9fc 6287+ };
6288+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
6289+ if (unlikely(wkq_err))
6290+ err = wkq_err;
6291+ }
6292+
6293+ if (h_orph) {
febd17d6 6294+ inode_unlock(h_tmpdir);
4a4d8108 6295+ /* todo: au_h_open_post()? */
1facf9fc 6296+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 6297+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
6298+ AuDebugOn(!pin_orig);
6299+ cpg->pin = pin_orig;
1facf9fc 6300+ }
6301+ iput(h_dir);
6302+ dput(parent);
6303+
6304+ return err;
6305+}
6306+
6307+/* ---------------------------------------------------------------------- */
6308+
6309+/*
6310+ * generic routine for both of copy-up and copy-down.
6311+ */
6312+/* cf. revalidate function in file.c */
6313+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
6314+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6315+ struct au_pin *pin,
1facf9fc 6316+ struct dentry *h_parent, void *arg),
6317+ void *arg)
6318+{
6319+ int err;
6320+ struct au_pin pin;
5527c038 6321+ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry;
1facf9fc 6322+
6323+ err = 0;
6324+ parent = dget_parent(dentry);
6325+ if (IS_ROOT(parent))
6326+ goto out;
6327+
6328+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
6329+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
6330+
6331+ /* do not use au_dpage */
6332+ real_parent = parent;
6333+ while (1) {
6334+ dput(parent);
6335+ parent = dget_parent(dentry);
6336+ h_parent = au_h_dptr(parent, bdst);
6337+ if (h_parent)
6338+ goto out; /* success */
6339+
6340+ /* find top dir which is necessary to cpup */
6341+ do {
6342+ d = parent;
6343+ dput(parent);
6344+ parent = dget_parent(d);
6345+ di_read_lock_parent3(parent, !AuLock_IR);
6346+ h_parent = au_h_dptr(parent, bdst);
6347+ di_read_unlock(parent, !AuLock_IR);
6348+ } while (!h_parent);
6349+
6350+ if (d != real_parent)
6351+ di_write_lock_child3(d);
6352+
6353+ /* somebody else might create while we were sleeping */
5527c038
JR
6354+ h_dentry = au_h_dptr(d, bdst);
6355+ if (!h_dentry || d_is_negative(h_dentry)) {
6356+ if (h_dentry)
5afbbe0d 6357+ au_update_dbtop(d);
1facf9fc 6358+
6359+ au_pin_set_dentry(&pin, d);
6360+ err = au_do_pin(&pin);
6361+ if (!err) {
86dc4139 6362+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 6363+ au_unpin(&pin);
6364+ }
6365+ }
6366+
6367+ if (d != real_parent)
6368+ di_write_unlock(d);
6369+ if (unlikely(err))
6370+ break;
6371+ }
6372+
4f0767ce 6373+out:
1facf9fc 6374+ dput(parent);
6375+ return err;
6376+}
6377+
6378+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6379+ struct au_pin *pin,
2000de60 6380+ struct dentry *h_parent __maybe_unused,
1facf9fc 6381+ void *arg __maybe_unused)
6382+{
c2b27bf2
AM
6383+ struct au_cp_generic cpg = {
6384+ .dentry = dentry,
6385+ .bdst = bdst,
6386+ .bsrc = -1,
6387+ .len = 0,
6388+ .pin = pin,
6389+ .flags = AuCpup_DTIME
6390+ };
6391+ return au_sio_cpup_simple(&cpg);
1facf9fc 6392+}
6393+
6394+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
6395+{
6396+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
6397+}
6398+
6399+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
6400+{
6401+ int err;
6402+ struct dentry *parent;
6403+ struct inode *dir;
6404+
6405+ parent = dget_parent(dentry);
5527c038 6406+ dir = d_inode(parent);
1facf9fc 6407+ err = 0;
6408+ if (au_h_iptr(dir, bdst))
6409+ goto out;
6410+
6411+ di_read_unlock(parent, AuLock_IR);
6412+ di_write_lock_parent(parent);
6413+ /* someone else might change our inode while we were sleeping */
6414+ if (!au_h_iptr(dir, bdst))
6415+ err = au_cpup_dirs(dentry, bdst);
6416+ di_downgrade_lock(parent, AuLock_IR);
6417+
4f0767ce 6418+out:
1facf9fc 6419+ dput(parent);
6420+ return err;
6421+}
7f207e10
AM
6422diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
6423--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 6424+++ linux/fs/aufs/cpup.h 2019-03-05 12:13:00.135890907 +0100
062440b3
AM
6425@@ -0,0 +1,100 @@
6426+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 6427+/*
ba1aed25 6428+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 6429+ *
6430+ * This program, aufs is free software; you can redistribute it and/or modify
6431+ * it under the terms of the GNU General Public License as published by
6432+ * the Free Software Foundation; either version 2 of the License, or
6433+ * (at your option) any later version.
dece6358
AM
6434+ *
6435+ * This program is distributed in the hope that it will be useful,
6436+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6437+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6438+ * GNU General Public License for more details.
6439+ *
6440+ * You should have received a copy of the GNU General Public License
523b37e3 6441+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6442+ */
6443+
6444+/*
6445+ * copy-up/down functions
6446+ */
6447+
6448+#ifndef __AUFS_CPUP_H__
6449+#define __AUFS_CPUP_H__
6450+
6451+#ifdef __KERNEL__
6452+
dece6358 6453+#include <linux/path.h>
1facf9fc 6454+
dece6358
AM
6455+struct inode;
6456+struct file;
86dc4139 6457+struct au_pin;
dece6358 6458+
86dc4139 6459+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 6460+void au_cpup_attr_timesizes(struct inode *inode);
6461+void au_cpup_attr_nlink(struct inode *inode, int force);
6462+void au_cpup_attr_changeable(struct inode *inode);
6463+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
6464+void au_cpup_attr_all(struct inode *inode, int force);
6465+
6466+/* ---------------------------------------------------------------------- */
6467+
c2b27bf2
AM
6468+struct au_cp_generic {
6469+ struct dentry *dentry;
6470+ aufs_bindex_t bdst, bsrc;
6471+ loff_t len;
6472+ struct au_pin *pin;
6473+ unsigned int flags;
6474+};
6475+
1facf9fc 6476+/* cpup flags */
392086de
AM
6477+#define AuCpup_DTIME 1 /* do dtime_store/revert */
6478+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
6479+ for link(2) */
6480+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
6481+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
6482+ cpup */
6483+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
6484+ existing entry */
6485+#define AuCpup_RWDST (1 << 5) /* force write target even if
6486+ the branch is marked as RO */
c2b27bf2 6487+
8b6a4947
AM
6488+#ifndef CONFIG_AUFS_BR_HFSPLUS
6489+#undef AuCpup_HOPEN
6490+#define AuCpup_HOPEN 0
6491+#endif
6492+
1facf9fc 6493+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
6494+#define au_fset_cpup(flags, name) \
6495+ do { (flags) |= AuCpup_##name; } while (0)
6496+#define au_fclr_cpup(flags, name) \
6497+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 6498+
6499+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
6500+int au_sio_cpup_simple(struct au_cp_generic *cpg);
6501+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
6502+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 6503+
6504+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
6505+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6506+ struct au_pin *pin,
1facf9fc 6507+ struct dentry *h_parent, void *arg),
6508+ void *arg);
6509+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
6510+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
6511+
6512+/* ---------------------------------------------------------------------- */
6513+
6514+/* keep timestamps when copyup */
6515+struct au_dtime {
6516+ struct dentry *dt_dentry;
6517+ struct path dt_h_path;
cd7a4cd9 6518+ struct timespec64 dt_atime, dt_mtime;
1facf9fc 6519+};
6520+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
6521+ struct path *h_path);
6522+void au_dtime_revert(struct au_dtime *dt);
6523+
6524+#endif /* __KERNEL__ */
6525+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
6526diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
6527--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 6528+++ linux/fs/aufs/dbgaufs.c 2019-03-05 12:13:00.135890907 +0100
9f237c51 6529@@ -0,0 +1,526 @@
cd7a4cd9 6530+// SPDX-License-Identifier: GPL-2.0
1facf9fc 6531+/*
ba1aed25 6532+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 6533+ *
6534+ * This program, aufs is free software; you can redistribute it and/or modify
6535+ * it under the terms of the GNU General Public License as published by
6536+ * the Free Software Foundation; either version 2 of the License, or
6537+ * (at your option) any later version.
dece6358
AM
6538+ *
6539+ * This program is distributed in the hope that it will be useful,
6540+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6541+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6542+ * GNU General Public License for more details.
6543+ *
6544+ * You should have received a copy of the GNU General Public License
523b37e3 6545+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6546+ */
6547+
6548+/*
6549+ * debugfs interface
6550+ */
6551+
6552+#include <linux/debugfs.h>
6553+#include "aufs.h"
6554+
6555+#ifndef CONFIG_SYSFS
6556+#error DEBUG_FS depends upon SYSFS
6557+#endif
6558+
6559+static struct dentry *dbgaufs;
cd7a4cd9 6560+static const mode_t dbgaufs_mode = 0444;
1facf9fc 6561+
6562+/* 20 is max digits length of ulong 64 */
6563+struct dbgaufs_arg {
6564+ int n;
6565+ char a[20 * 4];
6566+};
6567+
6568+/*
6569+ * common function for all XINO files
6570+ */
6571+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
6572+ struct file *file)
6573+{
9f237c51
AM
6574+ void *p;
6575+
6576+ p = file->private_data;
6577+ if (p) {
6578+ /* this is struct dbgaufs_arg */
6579+ AuDebugOn(!au_kfree_sz_test(p));
6580+ au_kfree_do_rcu(p);
6581+ }
1facf9fc 6582+ return 0;
6583+}
6584+
062440b3
AM
6585+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt,
6586+ int cnt)
1facf9fc 6587+{
6588+ int err;
6589+ struct kstat st;
6590+ struct dbgaufs_arg *p;
6591+
6592+ err = -ENOMEM;
6593+ p = kmalloc(sizeof(*p), GFP_NOFS);
6594+ if (unlikely(!p))
6595+ goto out;
6596+
6597+ err = 0;
6598+ p->n = 0;
6599+ file->private_data = p;
6600+ if (!xf)
6601+ goto out;
6602+
521ced18 6603+ err = vfsub_getattr(&xf->f_path, &st);
1facf9fc 6604+ if (!err) {
6605+ if (do_fcnt)
6606+ p->n = snprintf
062440b3
AM
6607+ (p->a, sizeof(p->a), "%d, %llux%u %lld\n",
6608+ cnt, st.blocks, st.blksize,
1facf9fc 6609+ (long long)st.size);
6610+ else
521ced18 6611+ p->n = snprintf(p->a, sizeof(p->a), "%llux%u %lld\n",
1facf9fc 6612+ st.blocks, st.blksize,
6613+ (long long)st.size);
6614+ AuDebugOn(p->n >= sizeof(p->a));
6615+ } else {
6616+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
6617+ err = 0;
6618+ }
6619+
4f0767ce 6620+out:
1facf9fc 6621+ return err;
1facf9fc 6622+}
6623+
6624+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
6625+ size_t count, loff_t *ppos)
6626+{
6627+ struct dbgaufs_arg *p;
6628+
6629+ p = file->private_data;
6630+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6631+}
6632+
6633+/* ---------------------------------------------------------------------- */
6634+
86dc4139
AM
6635+struct dbgaufs_plink_arg {
6636+ int n;
6637+ char a[];
6638+};
6639+
6640+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
6641+ struct file *file)
6642+{
1c60b727 6643+ free_page((unsigned long)file->private_data);
86dc4139
AM
6644+ return 0;
6645+}
6646+
6647+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
6648+{
6649+ int err, i, limit;
6650+ unsigned long n, sum;
6651+ struct dbgaufs_plink_arg *p;
6652+ struct au_sbinfo *sbinfo;
6653+ struct super_block *sb;
8b6a4947 6654+ struct hlist_bl_head *hbl;
86dc4139
AM
6655+
6656+ err = -ENOMEM;
6657+ p = (void *)get_zeroed_page(GFP_NOFS);
6658+ if (unlikely(!p))
6659+ goto out;
6660+
6661+ err = -EFBIG;
6662+ sbinfo = inode->i_private;
6663+ sb = sbinfo->si_sb;
6664+ si_noflush_read_lock(sb);
6665+ if (au_opt_test(au_mntflags(sb), PLINK)) {
6666+ limit = PAGE_SIZE - sizeof(p->n);
6667+
6668+ /* the number of buckets */
6669+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
6670+ p->n += n;
6671+ limit -= n;
6672+
6673+ sum = 0;
8b6a4947
AM
6674+ for (i = 0, hbl = sbinfo->si_plink; i < AuPlink_NHASH;
6675+ i++, hbl++) {
6676+ n = au_hbl_count(hbl);
86dc4139
AM
6677+ sum += n;
6678+
6679+ n = snprintf(p->a + p->n, limit, "%lu ", n);
6680+ p->n += n;
6681+ limit -= n;
6682+ if (unlikely(limit <= 0))
6683+ goto out_free;
6684+ }
6685+ p->a[p->n - 1] = '\n';
6686+
6687+ /* the sum of plinks */
6688+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
6689+ p->n += n;
6690+ limit -= n;
6691+ if (unlikely(limit <= 0))
6692+ goto out_free;
6693+ } else {
6694+#define str "1\n0\n0\n"
6695+ p->n = sizeof(str) - 1;
6696+ strcpy(p->a, str);
6697+#undef str
6698+ }
6699+ si_read_unlock(sb);
6700+
6701+ err = 0;
6702+ file->private_data = p;
6703+ goto out; /* success */
6704+
6705+out_free:
1c60b727 6706+ free_page((unsigned long)p);
86dc4139
AM
6707+out:
6708+ return err;
6709+}
6710+
6711+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
6712+ size_t count, loff_t *ppos)
6713+{
6714+ struct dbgaufs_plink_arg *p;
6715+
6716+ p = file->private_data;
6717+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6718+}
6719+
6720+static const struct file_operations dbgaufs_plink_fop = {
6721+ .owner = THIS_MODULE,
6722+ .open = dbgaufs_plink_open,
6723+ .release = dbgaufs_plink_release,
6724+ .read = dbgaufs_plink_read
6725+};
6726+
6727+/* ---------------------------------------------------------------------- */
6728+
1facf9fc 6729+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
6730+{
6731+ int err;
6732+ struct au_sbinfo *sbinfo;
6733+ struct super_block *sb;
6734+
6735+ sbinfo = inode->i_private;
6736+ sb = sbinfo->si_sb;
6737+ si_noflush_read_lock(sb);
062440b3 6738+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0, /*cnt*/0);
1facf9fc 6739+ si_read_unlock(sb);
6740+ return err;
6741+}
6742+
6743+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 6744+ .owner = THIS_MODULE,
1facf9fc 6745+ .open = dbgaufs_xib_open,
6746+ .release = dbgaufs_xi_release,
6747+ .read = dbgaufs_xi_read
6748+};
6749+
6750+/* ---------------------------------------------------------------------- */
6751+
6752+#define DbgaufsXi_PREFIX "xi"
6753+
6754+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
6755+{
acd2b654 6756+ int err, idx;
1facf9fc 6757+ long l;
acd2b654
AM
6758+ aufs_bindex_t bindex;
6759+ char *p, a[sizeof(DbgaufsXi_PREFIX) + 8];
1facf9fc 6760+ struct au_sbinfo *sbinfo;
6761+ struct super_block *sb;
acd2b654 6762+ struct au_xino *xi;
1facf9fc 6763+ struct file *xf;
6764+ struct qstr *name;
062440b3 6765+ struct au_branch *br;
1facf9fc 6766+
6767+ err = -ENOENT;
2000de60 6768+ name = &file->f_path.dentry->d_name;
1facf9fc 6769+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
6770+ || memcmp(name->name, DbgaufsXi_PREFIX,
6771+ sizeof(DbgaufsXi_PREFIX) - 1)))
6772+ goto out;
acd2b654
AM
6773+
6774+ AuDebugOn(name->len >= sizeof(a));
6775+ memcpy(a, name->name, name->len);
6776+ a[name->len] = '\0';
6777+ p = strchr(a, '-');
6778+ if (p)
6779+ *p = '\0';
6780+ err = kstrtol(a + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 6781+ if (unlikely(err))
6782+ goto out;
acd2b654
AM
6783+ bindex = l;
6784+ idx = 0;
6785+ if (p) {
6786+ err = kstrtol(p + 1, 10, &l);
6787+ if (unlikely(err))
6788+ goto out;
6789+ idx = l;
6790+ }
1facf9fc 6791+
acd2b654 6792+ err = -ENOENT;
1facf9fc 6793+ sbinfo = inode->i_private;
6794+ sb = sbinfo->si_sb;
6795+ si_noflush_read_lock(sb);
acd2b654
AM
6796+ if (unlikely(bindex < 0 || bindex > au_sbbot(sb)))
6797+ goto out_si;
6798+ br = au_sbr(sb, bindex);
6799+ xi = br->br_xino;
6800+ if (unlikely(idx >= xi->xi_nfile))
6801+ goto out_si;
6802+ xf = au_xino_file(xi, idx);
6803+ if (xf)
062440b3
AM
6804+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1,
6805+ au_xino_count(br));
1facf9fc 6806+
acd2b654
AM
6807+out_si:
6808+ si_read_unlock(sb);
4f0767ce 6809+out:
acd2b654 6810+ AuTraceErr(err);
1facf9fc 6811+ return err;
6812+}
6813+
6814+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 6815+ .owner = THIS_MODULE,
1facf9fc 6816+ .open = dbgaufs_xino_open,
6817+ .release = dbgaufs_xi_release,
6818+ .read = dbgaufs_xi_read
6819+};
6820+
062440b3
AM
6821+void dbgaufs_xino_del(struct au_branch *br)
6822+{
6823+ struct dentry *dbgaufs;
6824+
6825+ dbgaufs = br->br_dbgaufs;
6826+ if (!dbgaufs)
6827+ return;
6828+
6829+ br->br_dbgaufs = NULL;
6830+ /* debugfs acquires the parent i_mutex */
6831+ lockdep_off();
6832+ debugfs_remove(dbgaufs);
6833+ lockdep_on();
6834+}
6835+
1facf9fc 6836+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
6837+{
5afbbe0d 6838+ aufs_bindex_t bbot;
1facf9fc 6839+ struct au_branch *br;
1facf9fc 6840+
6841+ if (!au_sbi(sb)->si_dbgaufs)
6842+ return;
6843+
5afbbe0d
AM
6844+ bbot = au_sbbot(sb);
6845+ for (; bindex <= bbot; bindex++) {
1facf9fc 6846+ br = au_sbr(sb, bindex);
062440b3
AM
6847+ dbgaufs_xino_del(br);
6848+ }
6849+}
6850+
acd2b654
AM
6851+static void dbgaufs_br_do_add(struct super_block *sb, aufs_bindex_t bindex,
6852+ unsigned int idx, struct dentry *parent,
6853+ struct au_sbinfo *sbinfo)
062440b3
AM
6854+{
6855+ struct au_branch *br;
6856+ struct dentry *d;
acd2b654
AM
6857+ /* "xi" bindex(5) "-" idx(2) NULL */
6858+ char name[sizeof(DbgaufsXi_PREFIX) + 8];
062440b3 6859+
acd2b654
AM
6860+ if (!idx)
6861+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
6862+ else
6863+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d-%u",
6864+ bindex, idx);
062440b3
AM
6865+ br = au_sbr(sb, bindex);
6866+ if (br->br_dbgaufs) {
6867+ struct qstr qstr = QSTR_INIT(name, strlen(name));
6868+
6869+ if (!au_qstreq(&br->br_dbgaufs->d_name, &qstr)) {
6870+ /* debugfs acquires the parent i_mutex */
6871+ lockdep_off();
6872+ d = debugfs_rename(parent, br->br_dbgaufs, parent,
6873+ name);
6874+ lockdep_on();
6875+ if (unlikely(!d))
6876+ pr_warn("failed renaming %pd/%s, ignored.\n",
6877+ parent, name);
6878+ }
6879+ } else {
e2f27e51 6880+ lockdep_off();
062440b3
AM
6881+ br->br_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
6882+ sbinfo, &dbgaufs_xino_fop);
e2f27e51 6883+ lockdep_on();
062440b3 6884+ if (unlikely(!br->br_dbgaufs))
acd2b654 6885+ pr_warn("failed creating %pd/%s, ignored.\n",
062440b3 6886+ parent, name);
1facf9fc 6887+ }
6888+}
6889+
acd2b654
AM
6890+static void dbgaufs_br_add(struct super_block *sb, aufs_bindex_t bindex,
6891+ struct dentry *parent, struct au_sbinfo *sbinfo)
6892+{
6893+ struct au_branch *br;
6894+ struct au_xino *xi;
6895+ unsigned int u;
6896+
6897+ br = au_sbr(sb, bindex);
6898+ xi = br->br_xino;
6899+ for (u = 0; u < xi->xi_nfile; u++)
6900+ dbgaufs_br_do_add(sb, bindex, u, parent, sbinfo);
6901+}
6902+
062440b3 6903+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown)
1facf9fc 6904+{
6905+ struct au_sbinfo *sbinfo;
6906+ struct dentry *parent;
5afbbe0d 6907+ aufs_bindex_t bbot;
062440b3
AM
6908+
6909+ if (!au_opt_test(au_mntflags(sb), XINO))
6910+ return;
1facf9fc 6911+
6912+ sbinfo = au_sbi(sb);
6913+ parent = sbinfo->si_dbgaufs;
6914+ if (!parent)
6915+ return;
6916+
5afbbe0d 6917+ bbot = au_sbbot(sb);
062440b3
AM
6918+ if (topdown)
6919+ for (; bindex <= bbot; bindex++)
6920+ dbgaufs_br_add(sb, bindex, parent, sbinfo);
6921+ else
6922+ for (; bbot >= bindex; bbot--)
6923+ dbgaufs_br_add(sb, bbot, parent, sbinfo);
1facf9fc 6924+}
6925+
6926+/* ---------------------------------------------------------------------- */
6927+
6928+#ifdef CONFIG_AUFS_EXPORT
6929+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
6930+{
6931+ int err;
6932+ struct au_sbinfo *sbinfo;
6933+ struct super_block *sb;
6934+
6935+ sbinfo = inode->i_private;
6936+ sb = sbinfo->si_sb;
6937+ si_noflush_read_lock(sb);
062440b3 6938+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0, /*cnt*/0);
1facf9fc 6939+ si_read_unlock(sb);
6940+ return err;
6941+}
6942+
6943+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 6944+ .owner = THIS_MODULE,
1facf9fc 6945+ .open = dbgaufs_xigen_open,
6946+ .release = dbgaufs_xi_release,
6947+ .read = dbgaufs_xi_read
6948+};
6949+
6950+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6951+{
6952+ int err;
6953+
dece6358 6954+ /*
c1595e42 6955+ * This function is a dynamic '__init' function actually,
dece6358
AM
6956+ * so the tiny check for si_rwsem is unnecessary.
6957+ */
6958+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6959+
1facf9fc 6960+ err = -EIO;
6961+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
6962+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6963+ &dbgaufs_xigen_fop);
6964+ if (sbinfo->si_dbgaufs_xigen)
6965+ err = 0;
6966+
6967+ return err;
6968+}
6969+#else
6970+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6971+{
6972+ return 0;
6973+}
6974+#endif /* CONFIG_AUFS_EXPORT */
6975+
6976+/* ---------------------------------------------------------------------- */
6977+
6978+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
6979+{
dece6358 6980+ /*
7e9cd9fe 6981+ * This function is a dynamic '__fin' function actually,
dece6358
AM
6982+ * so the tiny check for si_rwsem is unnecessary.
6983+ */
6984+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6985+
1facf9fc 6986+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
6987+ sbinfo->si_dbgaufs = NULL;
1facf9fc 6988+}
6989+
6990+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
6991+{
6992+ int err;
6993+ char name[SysaufsSiNameLen];
6994+
dece6358 6995+ /*
c1595e42 6996+ * This function is a dynamic '__init' function actually,
dece6358
AM
6997+ * so the tiny check for si_rwsem is unnecessary.
6998+ */
6999+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
7000+
1facf9fc 7001+ err = -ENOENT;
7002+ if (!dbgaufs) {
7003+ AuErr1("/debug/aufs is uninitialized\n");
7004+ goto out;
7005+ }
7006+
7007+ err = -EIO;
7008+ sysaufs_name(sbinfo, name);
7009+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
7010+ if (unlikely(!sbinfo->si_dbgaufs))
7011+ goto out;
1facf9fc 7012+
062440b3 7013+ /* regardless plink/noplink option */
86dc4139
AM
7014+ sbinfo->si_dbgaufs_plink = debugfs_create_file
7015+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
7016+ &dbgaufs_plink_fop);
7017+ if (unlikely(!sbinfo->si_dbgaufs_plink))
7018+ goto out_dir;
7019+
062440b3
AM
7020+ /* regardless xino/noxino option */
7021+ sbinfo->si_dbgaufs_xib = debugfs_create_file
7022+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
7023+ &dbgaufs_xib_fop);
7024+ if (unlikely(!sbinfo->si_dbgaufs_xib))
7025+ goto out_dir;
7026+
1facf9fc 7027+ err = dbgaufs_xigen_init(sbinfo);
7028+ if (!err)
7029+ goto out; /* success */
7030+
4f0767ce 7031+out_dir:
1facf9fc 7032+ dbgaufs_si_fin(sbinfo);
4f0767ce 7033+out:
062440b3
AM
7034+ if (unlikely(err))
7035+ pr_err("debugfs/aufs failed\n");
1facf9fc 7036+ return err;
7037+}
7038+
7039+/* ---------------------------------------------------------------------- */
7040+
7041+void dbgaufs_fin(void)
7042+{
7043+ debugfs_remove(dbgaufs);
7044+}
7045+
7046+int __init dbgaufs_init(void)
7047+{
7048+ int err;
7049+
7050+ err = -EIO;
7051+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
7052+ if (dbgaufs)
7053+ err = 0;
7054+ return err;
7055+}
7f207e10
AM
7056diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
7057--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 7058+++ linux/fs/aufs/dbgaufs.h 2019-03-05 12:13:00.135890907 +0100
062440b3
AM
7059@@ -0,0 +1,53 @@
7060+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 7061+/*
ba1aed25 7062+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 7063+ *
7064+ * This program, aufs is free software; you can redistribute it and/or modify
7065+ * it under the terms of the GNU General Public License as published by
7066+ * the Free Software Foundation; either version 2 of the License, or
7067+ * (at your option) any later version.
dece6358
AM
7068+ *
7069+ * This program is distributed in the hope that it will be useful,
7070+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7071+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7072+ * GNU General Public License for more details.
7073+ *
7074+ * You should have received a copy of the GNU General Public License
523b37e3 7075+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7076+ */
7077+
7078+/*
7079+ * debugfs interface
7080+ */
7081+
7082+#ifndef __DBGAUFS_H__
7083+#define __DBGAUFS_H__
7084+
7085+#ifdef __KERNEL__
7086+
dece6358 7087+struct super_block;
1facf9fc 7088+struct au_sbinfo;
062440b3 7089+struct au_branch;
dece6358 7090+
1facf9fc 7091+#ifdef CONFIG_DEBUG_FS
7092+/* dbgaufs.c */
062440b3 7093+void dbgaufs_xino_del(struct au_branch *br);
1facf9fc 7094+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
062440b3 7095+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown);
1facf9fc 7096+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
7097+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
7098+void dbgaufs_fin(void);
7099+int __init dbgaufs_init(void);
1facf9fc 7100+#else
062440b3 7101+AuStubVoid(dbgaufs_xino_del, struct au_branch *br)
4a4d8108 7102+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
062440b3
AM
7103+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex,
7104+ int topdown)
4a4d8108
AM
7105+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
7106+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
7107+AuStubVoid(dbgaufs_fin, void)
7108+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 7109+#endif /* CONFIG_DEBUG_FS */
7110+
7111+#endif /* __KERNEL__ */
7112+#endif /* __DBGAUFS_H__ */
7f207e10
AM
7113diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
7114--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 7115+++ linux/fs/aufs/dcsub.c 2019-03-05 12:13:00.135890907 +0100
cd7a4cd9
AM
7116@@ -0,0 +1,225 @@
7117+// SPDX-License-Identifier: GPL-2.0
1facf9fc 7118+/*
ba1aed25 7119+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 7120+ *
7121+ * This program, aufs is free software; you can redistribute it and/or modify
7122+ * it under the terms of the GNU General Public License as published by
7123+ * the Free Software Foundation; either version 2 of the License, or
7124+ * (at your option) any later version.
dece6358
AM
7125+ *
7126+ * This program is distributed in the hope that it will be useful,
7127+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7128+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7129+ * GNU General Public License for more details.
7130+ *
7131+ * You should have received a copy of the GNU General Public License
523b37e3 7132+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7133+ */
7134+
7135+/*
7136+ * sub-routines for dentry cache
7137+ */
7138+
7139+#include "aufs.h"
7140+
7141+static void au_dpage_free(struct au_dpage *dpage)
7142+{
7143+ int i;
7144+ struct dentry **p;
7145+
7146+ p = dpage->dentries;
7147+ for (i = 0; i < dpage->ndentry; i++)
7148+ dput(*p++);
1c60b727 7149+ free_page((unsigned long)dpage->dentries);
1facf9fc 7150+}
7151+
7152+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
7153+{
7154+ int err;
7155+ void *p;
7156+
7157+ err = -ENOMEM;
7158+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
7159+ if (unlikely(!dpages->dpages))
7160+ goto out;
7161+
7162+ p = (void *)__get_free_page(gfp);
7163+ if (unlikely(!p))
7164+ goto out_dpages;
7165+
7166+ dpages->dpages[0].ndentry = 0;
7167+ dpages->dpages[0].dentries = p;
7168+ dpages->ndpage = 1;
7169+ return 0; /* success */
7170+
4f0767ce 7171+out_dpages:
9f237c51 7172+ au_kfree_try_rcu(dpages->dpages);
4f0767ce 7173+out:
1facf9fc 7174+ return err;
7175+}
7176+
7177+void au_dpages_free(struct au_dcsub_pages *dpages)
7178+{
7179+ int i;
7180+ struct au_dpage *p;
7181+
7182+ p = dpages->dpages;
7183+ for (i = 0; i < dpages->ndpage; i++)
7184+ au_dpage_free(p++);
9f237c51 7185+ au_kfree_try_rcu(dpages->dpages);
1facf9fc 7186+}
7187+
7188+static int au_dpages_append(struct au_dcsub_pages *dpages,
7189+ struct dentry *dentry, gfp_t gfp)
7190+{
7191+ int err, sz;
7192+ struct au_dpage *dpage;
7193+ void *p;
7194+
7195+ dpage = dpages->dpages + dpages->ndpage - 1;
7196+ sz = PAGE_SIZE / sizeof(dentry);
7197+ if (unlikely(dpage->ndentry >= sz)) {
7198+ AuLabel(new dpage);
7199+ err = -ENOMEM;
7200+ sz = dpages->ndpage * sizeof(*dpages->dpages);
7201+ p = au_kzrealloc(dpages->dpages, sz,
e2f27e51
AM
7202+ sz + sizeof(*dpages->dpages), gfp,
7203+ /*may_shrink*/0);
1facf9fc 7204+ if (unlikely(!p))
7205+ goto out;
7206+
7207+ dpages->dpages = p;
7208+ dpage = dpages->dpages + dpages->ndpage;
7209+ p = (void *)__get_free_page(gfp);
7210+ if (unlikely(!p))
7211+ goto out;
7212+
7213+ dpage->ndentry = 0;
7214+ dpage->dentries = p;
7215+ dpages->ndpage++;
7216+ }
7217+
c1595e42 7218+ AuDebugOn(au_dcount(dentry) <= 0);
027c5e7a 7219+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 7220+ return 0; /* success */
7221+
4f0767ce 7222+out:
1facf9fc 7223+ return err;
7224+}
7225+
c1595e42
JR
7226+/* todo: BAD approach */
7227+/* copied from linux/fs/dcache.c */
7228+enum d_walk_ret {
7229+ D_WALK_CONTINUE,
7230+ D_WALK_QUIT,
7231+ D_WALK_NORETRY,
7232+ D_WALK_SKIP,
7233+};
7234+
7235+extern void d_walk(struct dentry *parent, void *data,
cd7a4cd9 7236+ enum d_walk_ret (*enter)(void *, struct dentry *));
c1595e42
JR
7237+
7238+struct ac_dpages_arg {
1facf9fc 7239+ int err;
c1595e42
JR
7240+ struct au_dcsub_pages *dpages;
7241+ struct super_block *sb;
7242+ au_dpages_test test;
7243+ void *arg;
7244+};
1facf9fc 7245+
c1595e42
JR
7246+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry)
7247+{
7248+ enum d_walk_ret ret;
7249+ struct ac_dpages_arg *arg = _arg;
1facf9fc 7250+
c1595e42
JR
7251+ ret = D_WALK_CONTINUE;
7252+ if (dentry->d_sb == arg->sb
7253+ && !IS_ROOT(dentry)
7254+ && au_dcount(dentry) > 0
7255+ && au_di(dentry)
7256+ && (!arg->test || arg->test(dentry, arg->arg))) {
7257+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC);
7258+ if (unlikely(arg->err))
7259+ ret = D_WALK_QUIT;
1facf9fc 7260+ }
7261+
c1595e42
JR
7262+ return ret;
7263+}
027c5e7a 7264+
c1595e42
JR
7265+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
7266+ au_dpages_test test, void *arg)
7267+{
7268+ struct ac_dpages_arg args = {
7269+ .err = 0,
7270+ .dpages = dpages,
7271+ .sb = root->d_sb,
7272+ .test = test,
7273+ .arg = arg
7274+ };
027c5e7a 7275+
cd7a4cd9 7276+ d_walk(root, &args, au_call_dpages_append);
c1595e42
JR
7277+
7278+ return args.err;
1facf9fc 7279+}
7280+
7281+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
7282+ int do_include, au_dpages_test test, void *arg)
7283+{
7284+ int err;
7285+
7286+ err = 0;
027c5e7a
AM
7287+ write_seqlock(&rename_lock);
7288+ spin_lock(&dentry->d_lock);
7289+ if (do_include
c1595e42 7290+ && au_dcount(dentry) > 0
027c5e7a 7291+ && (!test || test(dentry, arg)))
1facf9fc 7292+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
7293+ spin_unlock(&dentry->d_lock);
7294+ if (unlikely(err))
7295+ goto out;
7296+
7297+ /*
523b37e3 7298+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
7299+ * mount
7300+ */
1facf9fc 7301+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
7302+ dentry = dentry->d_parent; /* rename_lock is locked */
7303+ spin_lock(&dentry->d_lock);
c1595e42 7304+ if (au_dcount(dentry) > 0
027c5e7a 7305+ && (!test || test(dentry, arg)))
1facf9fc 7306+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
7307+ spin_unlock(&dentry->d_lock);
7308+ if (unlikely(err))
7309+ break;
1facf9fc 7310+ }
7311+
4f0767ce 7312+out:
027c5e7a 7313+ write_sequnlock(&rename_lock);
1facf9fc 7314+ return err;
7315+}
7316+
027c5e7a
AM
7317+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
7318+{
7319+ return au_di(dentry) && dentry->d_sb == arg;
7320+}
7321+
7322+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
7323+ struct dentry *dentry, int do_include)
7324+{
7325+ return au_dcsub_pages_rev(dpages, dentry, do_include,
7326+ au_dcsub_dpages_aufs, dentry->d_sb);
7327+}
7328+
4a4d8108 7329+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 7330+{
4a4d8108
AM
7331+ struct path path[2] = {
7332+ {
7333+ .dentry = d1
7334+ },
7335+ {
7336+ .dentry = d2
7337+ }
7338+ };
1facf9fc 7339+
4a4d8108 7340+ return path_is_under(path + 0, path + 1);
1facf9fc 7341+}
7f207e10
AM
7342diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
7343--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 7344+++ linux/fs/aufs/dcsub.h 2019-03-05 12:13:00.135890907 +0100
062440b3
AM
7345@@ -0,0 +1,137 @@
7346+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 7347+/*
ba1aed25 7348+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 7349+ *
7350+ * This program, aufs is free software; you can redistribute it and/or modify
7351+ * it under the terms of the GNU General Public License as published by
7352+ * the Free Software Foundation; either version 2 of the License, or
7353+ * (at your option) any later version.
dece6358
AM
7354+ *
7355+ * This program is distributed in the hope that it will be useful,
7356+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7357+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7358+ * GNU General Public License for more details.
7359+ *
7360+ * You should have received a copy of the GNU General Public License
523b37e3 7361+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7362+ */
7363+
7364+/*
7365+ * sub-routines for dentry cache
7366+ */
7367+
7368+#ifndef __AUFS_DCSUB_H__
7369+#define __AUFS_DCSUB_H__
7370+
7371+#ifdef __KERNEL__
7372+
7f207e10 7373+#include <linux/dcache.h>
027c5e7a 7374+#include <linux/fs.h>
dece6358 7375+
1facf9fc 7376+struct au_dpage {
7377+ int ndentry;
7378+ struct dentry **dentries;
7379+};
7380+
7381+struct au_dcsub_pages {
7382+ int ndpage;
7383+ struct au_dpage *dpages;
7384+};
7385+
7386+/* ---------------------------------------------------------------------- */
7387+
7f207e10 7388+/* dcsub.c */
1facf9fc 7389+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
7390+void au_dpages_free(struct au_dcsub_pages *dpages);
7391+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
7392+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
7393+ au_dpages_test test, void *arg);
7394+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
7395+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
7396+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
7397+ struct dentry *dentry, int do_include);
4a4d8108 7398+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 7399+
7f207e10
AM
7400+/* ---------------------------------------------------------------------- */
7401+
523b37e3
AM
7402+/*
7403+ * todo: in linux-3.13, several similar (but faster) helpers are added to
7404+ * include/linux/dcache.h. Try them (in the future).
7405+ */
7406+
027c5e7a
AM
7407+static inline int au_d_hashed_positive(struct dentry *d)
7408+{
7409+ int err;
5527c038 7410+ struct inode *inode = d_inode(d);
076b876e 7411+
027c5e7a 7412+ err = 0;
5527c038
JR
7413+ if (unlikely(d_unhashed(d)
7414+ || d_is_negative(d)
7415+ || !inode->i_nlink))
027c5e7a
AM
7416+ err = -ENOENT;
7417+ return err;
7418+}
7419+
38d290e6
JR
7420+static inline int au_d_linkable(struct dentry *d)
7421+{
7422+ int err;
5527c038 7423+ struct inode *inode = d_inode(d);
076b876e 7424+
38d290e6
JR
7425+ err = au_d_hashed_positive(d);
7426+ if (err
5527c038 7427+ && d_is_positive(d)
38d290e6
JR
7428+ && (inode->i_state & I_LINKABLE))
7429+ err = 0;
7430+ return err;
7431+}
7432+
027c5e7a
AM
7433+static inline int au_d_alive(struct dentry *d)
7434+{
7435+ int err;
7436+ struct inode *inode;
076b876e 7437+
027c5e7a
AM
7438+ err = 0;
7439+ if (!IS_ROOT(d))
7440+ err = au_d_hashed_positive(d);
7441+ else {
5527c038
JR
7442+ inode = d_inode(d);
7443+ if (unlikely(d_unlinked(d)
7444+ || d_is_negative(d)
7445+ || !inode->i_nlink))
027c5e7a
AM
7446+ err = -ENOENT;
7447+ }
7448+ return err;
7449+}
7450+
7451+static inline int au_alive_dir(struct dentry *d)
7f207e10 7452+{
027c5e7a 7453+ int err;
076b876e 7454+
027c5e7a 7455+ err = au_d_alive(d);
5527c038 7456+ if (unlikely(err || IS_DEADDIR(d_inode(d))))
027c5e7a
AM
7457+ err = -ENOENT;
7458+ return err;
7f207e10
AM
7459+}
7460+
38d290e6
JR
7461+static inline int au_qstreq(struct qstr *a, struct qstr *b)
7462+{
7463+ return a->len == b->len
7464+ && !memcmp(a->name, b->name, a->len);
7465+}
7466+
7e9cd9fe
AM
7467+/*
7468+ * by the commit
7469+ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without
7470+ * taking d_lock
7471+ * the type of d_lockref.count became int, but the inlined function d_count()
7472+ * still returns unsigned int.
7473+ * I don't know why. Maybe it is for every d_count() users?
7474+ * Anyway au_dcount() lives on.
7475+ */
c1595e42
JR
7476+static inline int au_dcount(struct dentry *d)
7477+{
7478+ return (int)d_count(d);
7479+}
7480+
1facf9fc 7481+#endif /* __KERNEL__ */
7482+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
7483diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
7484--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
7485+++ linux/fs/aufs/debug.c 2019-05-06 09:03:04.816810402 +0200
7486@@ -0,0 +1,441 @@
cd7a4cd9 7487+// SPDX-License-Identifier: GPL-2.0
1facf9fc 7488+/*
ba1aed25 7489+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 7490+ *
7491+ * This program, aufs is free software; you can redistribute it and/or modify
7492+ * it under the terms of the GNU General Public License as published by
7493+ * the Free Software Foundation; either version 2 of the License, or
7494+ * (at your option) any later version.
dece6358
AM
7495+ *
7496+ * This program is distributed in the hope that it will be useful,
7497+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7498+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7499+ * GNU General Public License for more details.
7500+ *
7501+ * You should have received a copy of the GNU General Public License
523b37e3 7502+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7503+ */
7504+
7505+/*
7506+ * debug print functions
7507+ */
7508+
eca801bf 7509+#include <linux/iversion.h>
1facf9fc 7510+#include "aufs.h"
7511+
392086de
AM
7512+/* Returns 0, or -errno. arg is in kp->arg. */
7513+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
7514+{
7515+ int err, n;
7516+
7517+ err = kstrtoint(val, 0, &n);
7518+ if (!err) {
7519+ if (n > 0)
7520+ au_debug_on();
7521+ else
7522+ au_debug_off();
7523+ }
7524+ return err;
7525+}
7526+
7527+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
7528+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
7529+{
7530+ atomic_t *a;
7531+
7532+ a = kp->arg;
7533+ return sprintf(buffer, "%d", atomic_read(a));
7534+}
7535+
7536+static struct kernel_param_ops param_ops_atomic_t = {
7537+ .set = param_atomic_t_set,
7538+ .get = param_atomic_t_get
7539+ /* void (*free)(void *arg) */
7540+};
7541+
7542+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 7543+MODULE_PARM_DESC(debug, "debug print");
cd7a4cd9 7544+module_param_named(debug, aufs_debug, atomic_t, 0664);
1facf9fc 7545+
c1595e42 7546+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */
1facf9fc 7547+char *au_plevel = KERN_DEBUG;
e49829fe
JR
7548+#define dpri(fmt, ...) do { \
7549+ if ((au_plevel \
7550+ && strcmp(au_plevel, KERN_DEBUG)) \
7551+ || au_debug_test()) \
7552+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 7553+} while (0)
7554+
7555+/* ---------------------------------------------------------------------- */
7556+
7557+void au_dpri_whlist(struct au_nhash *whlist)
7558+{
7559+ unsigned long ul, n;
7560+ struct hlist_head *head;
c06a8ce3 7561+ struct au_vdir_wh *pos;
1facf9fc 7562+
7563+ n = whlist->nh_num;
7564+ head = whlist->nh_head;
7565+ for (ul = 0; ul < n; ul++) {
c06a8ce3 7566+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 7567+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
7568+ pos->wh_bindex,
7569+ pos->wh_str.len, pos->wh_str.name,
7570+ pos->wh_str.len);
1facf9fc 7571+ head++;
7572+ }
7573+}
7574+
7575+void au_dpri_vdir(struct au_vdir *vdir)
7576+{
7577+ unsigned long ul;
7578+ union au_vdir_deblk_p p;
7579+ unsigned char *o;
7580+
7581+ if (!vdir || IS_ERR(vdir)) {
7582+ dpri("err %ld\n", PTR_ERR(vdir));
7583+ return;
7584+ }
7585+
be118d29 7586+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %llu\n",
1facf9fc 7587+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
7588+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
7589+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
7590+ p.deblk = vdir->vd_deblk[ul];
7591+ o = p.deblk;
7592+ dpri("[%lu]: %p\n", ul, o);
7593+ }
7594+}
7595+
53392da6 7596+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 7597+ struct dentry *wh)
7598+{
7599+ char *n = NULL;
7600+ int l = 0;
7601+
7602+ if (!inode || IS_ERR(inode)) {
7603+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
7604+ return -1;
7605+ }
7606+
c2b27bf2 7607+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 7608+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
7609+ && sizeof(inode->i_blocks) != sizeof(u64));
7610+ if (wh) {
7611+ n = (void *)wh->d_name.name;
7612+ l = wh->d_name.len;
7613+ }
7614+
53392da6
AM
7615+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
7616+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
7617+ bindex, inode,
1facf9fc 7618+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
7619+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
7620+ i_size_read(inode), (unsigned long long)inode->i_blocks,
cd7a4cd9 7621+ hn, (long long)timespec64_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 7622+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
be118d29 7623+ inode->i_state, inode->i_flags, inode_peek_iversion(inode),
b752ccd1 7624+ inode->i_generation,
1facf9fc 7625+ l ? ", wh " : "", l, n);
7626+ return 0;
7627+}
7628+
7629+void au_dpri_inode(struct inode *inode)
7630+{
7631+ struct au_iinfo *iinfo;
5afbbe0d 7632+ struct au_hinode *hi;
1facf9fc 7633+ aufs_bindex_t bindex;
53392da6 7634+ int err, hn;
1facf9fc 7635+
53392da6 7636+ err = do_pri_inode(-1, inode, -1, NULL);
5afbbe0d 7637+ if (err || !au_test_aufs(inode->i_sb) || au_is_bad_inode(inode))
1facf9fc 7638+ return;
7639+
7640+ iinfo = au_ii(inode);
5afbbe0d
AM
7641+ dpri("i-1: btop %d, bbot %d, gen %d\n",
7642+ iinfo->ii_btop, iinfo->ii_bbot, au_iigen(inode, NULL));
7643+ if (iinfo->ii_btop < 0)
1facf9fc 7644+ return;
53392da6 7645+ hn = 0;
5afbbe0d
AM
7646+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; bindex++) {
7647+ hi = au_hinode(iinfo, bindex);
7648+ hn = !!au_hn(hi);
7649+ do_pri_inode(bindex, hi->hi_inode, hn, hi->hi_whdentry);
53392da6 7650+ }
1facf9fc 7651+}
7652+
2cbb1c4b
JR
7653+void au_dpri_dalias(struct inode *inode)
7654+{
7655+ struct dentry *d;
7656+
7657+ spin_lock(&inode->i_lock);
c1595e42 7658+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias)
2cbb1c4b
JR
7659+ au_dpri_dentry(d);
7660+ spin_unlock(&inode->i_lock);
7661+}
7662+
1facf9fc 7663+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
7664+{
7665+ struct dentry *wh = NULL;
53392da6 7666+ int hn;
5afbbe0d 7667+ struct inode *inode;
076b876e 7668+ struct au_iinfo *iinfo;
5afbbe0d 7669+ struct au_hinode *hi;
1facf9fc 7670+
7671+ if (!dentry || IS_ERR(dentry)) {
7672+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
7673+ return -1;
7674+ }
7675+ /* do not call dget_parent() here */
027c5e7a 7676+ /* note: access d_xxx without d_lock */
523b37e3
AM
7677+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
7678+ bindex, dentry, dentry,
1facf9fc 7679+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
c1595e42 7680+ au_dcount(dentry), dentry->d_flags,
523b37e3 7681+ d_unhashed(dentry) ? "un" : "");
53392da6 7682+ hn = -1;
5afbbe0d
AM
7683+ inode = NULL;
7684+ if (d_is_positive(dentry))
7685+ inode = d_inode(dentry);
7686+ if (inode
7687+ && au_test_aufs(dentry->d_sb)
7688+ && bindex >= 0
7689+ && !au_is_bad_inode(inode)) {
7690+ iinfo = au_ii(inode);
7691+ hi = au_hinode(iinfo, bindex);
7692+ hn = !!au_hn(hi);
7693+ wh = hi->hi_whdentry;
7694+ }
7695+ do_pri_inode(bindex, inode, hn, wh);
1facf9fc 7696+ return 0;
7697+}
7698+
7699+void au_dpri_dentry(struct dentry *dentry)
7700+{
7701+ struct au_dinfo *dinfo;
7702+ aufs_bindex_t bindex;
7703+ int err;
7704+
7705+ err = do_pri_dentry(-1, dentry);
7706+ if (err || !au_test_aufs(dentry->d_sb))
7707+ return;
7708+
7709+ dinfo = au_di(dentry);
7710+ if (!dinfo)
7711+ return;
5afbbe0d
AM
7712+ dpri("d-1: btop %d, bbot %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
7713+ dinfo->di_btop, dinfo->di_bbot,
38d290e6
JR
7714+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
7715+ dinfo->di_tmpfile);
5afbbe0d 7716+ if (dinfo->di_btop < 0)
1facf9fc 7717+ return;
5afbbe0d
AM
7718+ for (bindex = dinfo->di_btop; bindex <= dinfo->di_bbot; bindex++)
7719+ do_pri_dentry(bindex, au_hdentry(dinfo, bindex)->hd_dentry);
1facf9fc 7720+}
7721+
7722+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
7723+{
7724+ char a[32];
7725+
7726+ if (!file || IS_ERR(file)) {
7727+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
7728+ return -1;
7729+ }
7730+ a[0] = 0;
7731+ if (bindex < 0
b912730e 7732+ && !IS_ERR_OR_NULL(file->f_path.dentry)
2000de60 7733+ && au_test_aufs(file->f_path.dentry->d_sb)
1facf9fc 7734+ && au_fi(file))
e49829fe 7735+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 7736+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 7737+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 7738+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 7739+ file->f_version, file->f_pos, a);
b912730e 7740+ if (!IS_ERR_OR_NULL(file->f_path.dentry))
2000de60 7741+ do_pri_dentry(bindex, file->f_path.dentry);
1facf9fc 7742+ return 0;
7743+}
7744+
7745+void au_dpri_file(struct file *file)
7746+{
7747+ struct au_finfo *finfo;
4a4d8108
AM
7748+ struct au_fidir *fidir;
7749+ struct au_hfile *hfile;
1facf9fc 7750+ aufs_bindex_t bindex;
7751+ int err;
7752+
7753+ err = do_pri_file(-1, file);
2000de60 7754+ if (err
b912730e 7755+ || IS_ERR_OR_NULL(file->f_path.dentry)
2000de60 7756+ || !au_test_aufs(file->f_path.dentry->d_sb))
1facf9fc 7757+ return;
7758+
7759+ finfo = au_fi(file);
7760+ if (!finfo)
7761+ return;
4a4d8108 7762+ if (finfo->fi_btop < 0)
1facf9fc 7763+ return;
4a4d8108
AM
7764+ fidir = finfo->fi_hdir;
7765+ if (!fidir)
7766+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
7767+ else
e49829fe
JR
7768+ for (bindex = finfo->fi_btop;
7769+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
7770+ bindex++) {
7771+ hfile = fidir->fd_hfile + bindex;
7772+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
7773+ }
1facf9fc 7774+}
7775+
7776+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
7777+{
7778+ struct vfsmount *mnt;
7779+ struct super_block *sb;
7780+
7781+ if (!br || IS_ERR(br))
7782+ goto out;
86dc4139 7783+ mnt = au_br_mnt(br);
1facf9fc 7784+ if (!mnt || IS_ERR(mnt))
7785+ goto out;
7786+ sb = mnt->mnt_sb;
7787+ if (!sb || IS_ERR(sb))
7788+ goto out;
7789+
acd2b654 7790+ dpri("s%d: {perm 0x%x, id %d, wbr %p}, "
b752ccd1 7791+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 7792+ "xino %d\n",
acd2b654
AM
7793+ bindex, br->br_perm, br->br_id, br->br_wbr,
7794+ au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 7795+ sb->s_flags, sb->s_count,
acd2b654
AM
7796+ atomic_read(&sb->s_active),
7797+ !!au_xino_file(br->br_xino, /*idx*/-1));
1facf9fc 7798+ return 0;
7799+
4f0767ce 7800+out:
1facf9fc 7801+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
7802+ return -1;
7803+}
7804+
7805+void au_dpri_sb(struct super_block *sb)
7806+{
7807+ struct au_sbinfo *sbinfo;
7808+ aufs_bindex_t bindex;
7809+ int err;
acd2b654 7810+ /* to reduce stack size */
1facf9fc 7811+ struct {
7812+ struct vfsmount mnt;
7813+ struct au_branch fake;
7814+ } *a;
7815+
7816+ /* this function can be called from magic sysrq */
7817+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
7818+ if (unlikely(!a)) {
7819+ dpri("no memory\n");
7820+ return;
7821+ }
7822+
7823+ a->mnt.mnt_sb = sb;
86dc4139 7824+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 7825+ err = do_pri_br(-1, &a->fake);
9f237c51 7826+ au_kfree_rcu(a);
1facf9fc 7827+ dpri("dev 0x%x\n", sb->s_dev);
7828+ if (err || !au_test_aufs(sb))
7829+ return;
7830+
7831+ sbinfo = au_sbi(sb);
7832+ if (!sbinfo)
7833+ return;
f0c0a007
AM
7834+ dpri("nw %d, gen %u, kobj %d\n",
7835+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
521ced18 7836+ kref_read(&sbinfo->si_kobj.kref));
5afbbe0d 7837+ for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++)
1facf9fc 7838+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
7839+}
7840+
7841+/* ---------------------------------------------------------------------- */
7842+
027c5e7a
AM
7843+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
7844+{
5527c038 7845+ struct inode *h_inode, *inode = d_inode(dentry);
027c5e7a 7846+ struct dentry *h_dentry;
5afbbe0d 7847+ aufs_bindex_t bindex, bbot, bi;
027c5e7a
AM
7848+
7849+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
7850+ return;
7851+
5afbbe0d
AM
7852+ bbot = au_dbbot(dentry);
7853+ bi = au_ibbot(inode);
7854+ if (bi < bbot)
7855+ bbot = bi;
7856+ bindex = au_dbtop(dentry);
7857+ bi = au_ibtop(inode);
027c5e7a
AM
7858+ if (bi > bindex)
7859+ bindex = bi;
7860+
5afbbe0d 7861+ for (; bindex <= bbot; bindex++) {
027c5e7a
AM
7862+ h_dentry = au_h_dptr(dentry, bindex);
7863+ if (!h_dentry)
7864+ continue;
7865+ h_inode = au_h_iptr(inode, bindex);
5527c038 7866+ if (unlikely(h_inode != d_inode(h_dentry))) {
392086de 7867+ au_debug_on();
027c5e7a
AM
7868+ AuDbg("b%d, %s:%d\n", bindex, func, line);
7869+ AuDbgDentry(dentry);
7870+ AuDbgInode(inode);
392086de 7871+ au_debug_off();
027c5e7a
AM
7872+ BUG();
7873+ }
7874+ }
7875+}
7876+
1facf9fc 7877+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
7878+{
7879+ int err, i, j;
7880+ struct au_dcsub_pages dpages;
7881+ struct au_dpage *dpage;
7882+ struct dentry **dentries;
7883+
7884+ err = au_dpages_init(&dpages, GFP_NOFS);
7885+ AuDebugOn(err);
027c5e7a 7886+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 7887+ AuDebugOn(err);
7888+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
7889+ dpage = dpages.dpages + i;
7890+ dentries = dpage->dentries;
7891+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 7892+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 7893+ }
7894+ au_dpages_free(&dpages);
7895+}
7896+
1facf9fc 7897+void au_dbg_verify_kthread(void)
7898+{
53392da6 7899+ if (au_wkq_test()) {
1facf9fc 7900+ au_dbg_blocked();
1e00d052
AM
7901+ /*
7902+ * It may be recursive, but udba=notify between two aufs mounts,
7903+ * where a single ro branch is shared, is not a problem.
7904+ */
7905+ /* WARN_ON(1); */
1facf9fc 7906+ }
7907+}
7908+
7909+/* ---------------------------------------------------------------------- */
7910+
1facf9fc 7911+int __init au_debug_init(void)
7912+{
7913+ aufs_bindex_t bindex;
7914+ struct au_vdir_destr destr;
7915+
7916+ bindex = -1;
7917+ AuDebugOn(bindex >= 0);
7918+
7919+ destr.len = -1;
7920+ AuDebugOn(destr.len < NAME_MAX);
7921+
7922+#ifdef CONFIG_4KSTACKS
0c3ec466 7923+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 7924+#endif
7925+
1facf9fc 7926+ return 0;
7927+}
7f207e10
AM
7928diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
7929--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 7930+++ linux/fs/aufs/debug.h 2019-03-05 12:13:00.135890907 +0100
062440b3
AM
7931@@ -0,0 +1,226 @@
7932+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 7933+/*
ba1aed25 7934+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 7935+ *
7936+ * This program, aufs is free software; you can redistribute it and/or modify
7937+ * it under the terms of the GNU General Public License as published by
7938+ * the Free Software Foundation; either version 2 of the License, or
7939+ * (at your option) any later version.
dece6358
AM
7940+ *
7941+ * This program is distributed in the hope that it will be useful,
7942+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7943+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7944+ * GNU General Public License for more details.
7945+ *
7946+ * You should have received a copy of the GNU General Public License
523b37e3 7947+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7948+ */
7949+
7950+/*
7951+ * debug print functions
7952+ */
7953+
7954+#ifndef __AUFS_DEBUG_H__
7955+#define __AUFS_DEBUG_H__
7956+
7957+#ifdef __KERNEL__
7958+
392086de 7959+#include <linux/atomic.h>
4a4d8108
AM
7960+#include <linux/module.h>
7961+#include <linux/kallsyms.h>
1facf9fc 7962+#include <linux/sysrq.h>
4a4d8108 7963+
1facf9fc 7964+#ifdef CONFIG_AUFS_DEBUG
7965+#define AuDebugOn(a) BUG_ON(a)
7966+
7967+/* module parameter */
392086de
AM
7968+extern atomic_t aufs_debug;
7969+static inline void au_debug_on(void)
1facf9fc 7970+{
392086de
AM
7971+ atomic_inc(&aufs_debug);
7972+}
7973+static inline void au_debug_off(void)
7974+{
7975+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 7976+}
7977+
7978+static inline int au_debug_test(void)
7979+{
392086de 7980+ return atomic_read(&aufs_debug) > 0;
1facf9fc 7981+}
7982+#else
7983+#define AuDebugOn(a) do {} while (0)
392086de
AM
7984+AuStubVoid(au_debug_on, void)
7985+AuStubVoid(au_debug_off, void)
4a4d8108 7986+AuStubInt0(au_debug_test, void)
1facf9fc 7987+#endif /* CONFIG_AUFS_DEBUG */
7988+
392086de
AM
7989+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
7990+
1facf9fc 7991+/* ---------------------------------------------------------------------- */
7992+
7993+/* debug print */
7994+
4a4d8108 7995+#define AuDbg(fmt, ...) do { \
1facf9fc 7996+ if (au_debug_test()) \
4a4d8108 7997+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 7998+} while (0)
4a4d8108
AM
7999+#define AuLabel(l) AuDbg(#l "\n")
8000+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
8001+#define AuWarn1(fmt, ...) do { \
1facf9fc 8002+ static unsigned char _c; \
8003+ if (!_c++) \
0c3ec466 8004+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 8005+} while (0)
8006+
4a4d8108 8007+#define AuErr1(fmt, ...) do { \
1facf9fc 8008+ static unsigned char _c; \
8009+ if (!_c++) \
4a4d8108 8010+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 8011+} while (0)
8012+
4a4d8108 8013+#define AuIOErr1(fmt, ...) do { \
1facf9fc 8014+ static unsigned char _c; \
8015+ if (!_c++) \
4a4d8108 8016+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 8017+} while (0)
8018+
8019+#define AuUnsupportMsg "This operation is not supported." \
8020+ " Please report this application to aufs-users ML."
4a4d8108
AM
8021+#define AuUnsupport(fmt, ...) do { \
8022+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 8023+ dump_stack(); \
8024+} while (0)
8025+
8026+#define AuTraceErr(e) do { \
8027+ if (unlikely((e) < 0)) \
8028+ AuDbg("err %d\n", (int)(e)); \
8029+} while (0)
8030+
8031+#define AuTraceErrPtr(p) do { \
8032+ if (IS_ERR(p)) \
8033+ AuDbg("err %ld\n", PTR_ERR(p)); \
8034+} while (0)
8035+
8036+/* dirty macros for debug print, use with "%.*s" and caution */
8037+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 8038+
8039+/* ---------------------------------------------------------------------- */
8040+
dece6358 8041+struct dentry;
1facf9fc 8042+#ifdef CONFIG_AUFS_DEBUG
c1595e42 8043+extern struct mutex au_dbg_mtx;
1facf9fc 8044+extern char *au_plevel;
8045+struct au_nhash;
8046+void au_dpri_whlist(struct au_nhash *whlist);
8047+struct au_vdir;
8048+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 8049+struct inode;
1facf9fc 8050+void au_dpri_inode(struct inode *inode);
2cbb1c4b 8051+void au_dpri_dalias(struct inode *inode);
1facf9fc 8052+void au_dpri_dentry(struct dentry *dentry);
dece6358 8053+struct file;
1facf9fc 8054+void au_dpri_file(struct file *filp);
dece6358 8055+struct super_block;
1facf9fc 8056+void au_dpri_sb(struct super_block *sb);
8057+
027c5e7a
AM
8058+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
8059+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 8060+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 8061+void au_dbg_verify_kthread(void);
8062+
8063+int __init au_debug_init(void);
7e9cd9fe 8064+
1facf9fc 8065+#define AuDbgWhlist(w) do { \
c1595e42 8066+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8067+ AuDbg(#w "\n"); \
8068+ au_dpri_whlist(w); \
c1595e42 8069+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8070+} while (0)
8071+
8072+#define AuDbgVdir(v) do { \
c1595e42 8073+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8074+ AuDbg(#v "\n"); \
8075+ au_dpri_vdir(v); \
c1595e42 8076+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8077+} while (0)
8078+
8079+#define AuDbgInode(i) do { \
c1595e42 8080+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8081+ AuDbg(#i "\n"); \
8082+ au_dpri_inode(i); \
c1595e42 8083+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8084+} while (0)
8085+
2cbb1c4b 8086+#define AuDbgDAlias(i) do { \
c1595e42 8087+ mutex_lock(&au_dbg_mtx); \
2cbb1c4b
JR
8088+ AuDbg(#i "\n"); \
8089+ au_dpri_dalias(i); \
c1595e42 8090+ mutex_unlock(&au_dbg_mtx); \
2cbb1c4b
JR
8091+} while (0)
8092+
1facf9fc 8093+#define AuDbgDentry(d) do { \
c1595e42 8094+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8095+ AuDbg(#d "\n"); \
8096+ au_dpri_dentry(d); \
c1595e42 8097+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8098+} while (0)
8099+
8100+#define AuDbgFile(f) do { \
c1595e42 8101+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8102+ AuDbg(#f "\n"); \
8103+ au_dpri_file(f); \
c1595e42 8104+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8105+} while (0)
8106+
8107+#define AuDbgSb(sb) do { \
c1595e42 8108+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8109+ AuDbg(#sb "\n"); \
8110+ au_dpri_sb(sb); \
c1595e42 8111+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8112+} while (0)
8113+
4a4d8108
AM
8114+#define AuDbgSym(addr) do { \
8115+ char sym[KSYM_SYMBOL_LEN]; \
8116+ sprint_symbol(sym, (unsigned long)addr); \
8117+ AuDbg("%s\n", sym); \
8118+} while (0)
1facf9fc 8119+#else
027c5e7a 8120+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
8121+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
8122+AuStubVoid(au_dbg_verify_kthread, void)
8123+AuStubInt0(__init au_debug_init, void)
1facf9fc 8124+
1facf9fc 8125+#define AuDbgWhlist(w) do {} while (0)
8126+#define AuDbgVdir(v) do {} while (0)
8127+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 8128+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 8129+#define AuDbgDentry(d) do {} while (0)
8130+#define AuDbgFile(f) do {} while (0)
8131+#define AuDbgSb(sb) do {} while (0)
4a4d8108 8132+#define AuDbgSym(addr) do {} while (0)
1facf9fc 8133+#endif /* CONFIG_AUFS_DEBUG */
8134+
8135+/* ---------------------------------------------------------------------- */
8136+
8137+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
8138+int __init au_sysrq_init(void);
8139+void au_sysrq_fin(void);
8140+
8141+#ifdef CONFIG_HW_CONSOLE
8142+#define au_dbg_blocked() do { \
8143+ WARN_ON(1); \
0c5527e5 8144+ handle_sysrq('w'); \
1facf9fc 8145+} while (0)
8146+#else
4a4d8108 8147+AuStubVoid(au_dbg_blocked, void)
1facf9fc 8148+#endif
8149+
8150+#else
4a4d8108
AM
8151+AuStubInt0(__init au_sysrq_init, void)
8152+AuStubVoid(au_sysrq_fin, void)
8153+AuStubVoid(au_dbg_blocked, void)
1facf9fc 8154+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
8155+
8156+#endif /* __KERNEL__ */
8157+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
8158diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
8159--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
8160+++ linux/fs/aufs/dentry.c 2019-05-06 09:03:04.816810402 +0200
8161@@ -0,0 +1,1154 @@
cd7a4cd9 8162+// SPDX-License-Identifier: GPL-2.0
1facf9fc 8163+/*
ba1aed25 8164+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 8165+ *
8166+ * This program, aufs is free software; you can redistribute it and/or modify
8167+ * it under the terms of the GNU General Public License as published by
8168+ * the Free Software Foundation; either version 2 of the License, or
8169+ * (at your option) any later version.
dece6358
AM
8170+ *
8171+ * This program is distributed in the hope that it will be useful,
8172+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8173+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8174+ * GNU General Public License for more details.
8175+ *
8176+ * You should have received a copy of the GNU General Public License
523b37e3 8177+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8178+ */
8179+
8180+/*
8181+ * lookup and dentry operations
8182+ */
8183+
eca801bf 8184+#include <linux/iversion.h>
dece6358 8185+#include <linux/namei.h>
1facf9fc 8186+#include "aufs.h"
8187+
1facf9fc 8188+/*
8189+ * returns positive/negative dentry, NULL or an error.
8190+ * NULL means whiteout-ed or not-found.
8191+ */
8192+static struct dentry*
8193+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
8b6a4947 8194+ aufs_bindex_t bindex, struct au_do_lookup_args *args)
1facf9fc 8195+{
8196+ struct dentry *h_dentry;
2000de60 8197+ struct inode *h_inode;
1facf9fc 8198+ struct au_branch *br;
8199+ int wh_found, opq;
8200+ unsigned char wh_able;
8201+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
076b876e
AM
8202+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
8203+ IGNORE_PERM);
1facf9fc 8204+
1facf9fc 8205+ wh_found = 0;
8206+ br = au_sbr(dentry->d_sb, bindex);
8207+ wh_able = !!au_br_whable(br->br_perm);
8208+ if (wh_able)
8b6a4947 8209+ wh_found = au_wh_test(h_parent, &args->whname, ignore_perm);
1facf9fc 8210+ h_dentry = ERR_PTR(wh_found);
8211+ if (!wh_found)
8212+ goto real_lookup;
8213+ if (unlikely(wh_found < 0))
8214+ goto out;
8215+
8216+ /* We found a whiteout */
5afbbe0d 8217+ /* au_set_dbbot(dentry, bindex); */
1facf9fc 8218+ au_set_dbwh(dentry, bindex);
8219+ if (!allow_neg)
8220+ return NULL; /* success */
8221+
4f0767ce 8222+real_lookup:
076b876e 8223+ if (!ignore_perm)
8b6a4947 8224+ h_dentry = vfsub_lkup_one(args->name, h_parent);
076b876e 8225+ else
8b6a4947 8226+ h_dentry = au_sio_lkup_one(args->name, h_parent);
2000de60
JR
8227+ if (IS_ERR(h_dentry)) {
8228+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG
8229+ && !allow_neg)
8230+ h_dentry = NULL;
1facf9fc 8231+ goto out;
2000de60 8232+ }
1facf9fc 8233+
5527c038
JR
8234+ h_inode = d_inode(h_dentry);
8235+ if (d_is_negative(h_dentry)) {
1facf9fc 8236+ if (!allow_neg)
8237+ goto out_neg;
8238+ } else if (wh_found
8239+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
8240+ goto out_neg;
8b6a4947
AM
8241+ else if (au_ftest_lkup(args->flags, DIRREN)
8242+ /* && h_inode */
8243+ && !au_dr_lkup_h_ino(args, bindex, h_inode->i_ino)) {
8244+ AuDbg("b%d %pd ignored hi%llu\n", bindex, h_dentry,
8245+ (unsigned long long)h_inode->i_ino);
8246+ goto out_neg;
8247+ }
1facf9fc 8248+
5afbbe0d
AM
8249+ if (au_dbbot(dentry) <= bindex)
8250+ au_set_dbbot(dentry, bindex);
8251+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
8252+ au_set_dbtop(dentry, bindex);
1facf9fc 8253+ au_set_h_dptr(dentry, bindex, h_dentry);
8254+
2000de60
JR
8255+ if (!d_is_dir(h_dentry)
8256+ || !wh_able
5527c038 8257+ || (d_really_is_positive(dentry) && !d_is_dir(dentry)))
1facf9fc 8258+ goto out; /* success */
8259+
be118d29 8260+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD);
076b876e 8261+ opq = au_diropq_test(h_dentry);
3c1bdaff 8262+ inode_unlock_shared(h_inode);
1facf9fc 8263+ if (opq > 0)
8264+ au_set_dbdiropq(dentry, bindex);
8265+ else if (unlikely(opq < 0)) {
8266+ au_set_h_dptr(dentry, bindex, NULL);
8267+ h_dentry = ERR_PTR(opq);
8268+ }
8269+ goto out;
8270+
4f0767ce 8271+out_neg:
1facf9fc 8272+ dput(h_dentry);
8273+ h_dentry = NULL;
4f0767ce 8274+out:
1facf9fc 8275+ return h_dentry;
8276+}
8277+
dece6358
AM
8278+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
8279+{
8280+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
8281+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
8282+ return -EPERM;
8283+ return 0;
8284+}
8285+
1facf9fc 8286+/*
8287+ * returns the number of lower positive dentries,
8288+ * otherwise an error.
8289+ * can be called at unlinking with @type is zero.
8290+ */
5afbbe0d
AM
8291+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
8292+ unsigned int flags)
1facf9fc 8293+{
8294+ int npositive, err;
8295+ aufs_bindex_t bindex, btail, bdiropq;
8b6a4947 8296+ unsigned char isdir, dirperm1, dirren;
1facf9fc 8297+ struct au_do_lookup_args args = {
8b6a4947
AM
8298+ .flags = flags,
8299+ .name = &dentry->d_name
1facf9fc 8300+ };
1facf9fc 8301+ struct dentry *parent;
076b876e 8302+ struct super_block *sb;
1facf9fc 8303+
076b876e 8304+ sb = dentry->d_sb;
8b6a4947 8305+ err = au_test_shwh(sb, args.name);
dece6358 8306+ if (unlikely(err))
1facf9fc 8307+ goto out;
8308+
8b6a4947 8309+ err = au_wh_name_alloc(&args.whname, args.name);
1facf9fc 8310+ if (unlikely(err))
8311+ goto out;
8312+
2000de60 8313+ isdir = !!d_is_dir(dentry);
076b876e 8314+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
8b6a4947
AM
8315+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN);
8316+ if (dirren)
8317+ au_fset_lkup(args.flags, DIRREN);
1facf9fc 8318+
8319+ npositive = 0;
4a4d8108 8320+ parent = dget_parent(dentry);
1facf9fc 8321+ btail = au_dbtaildir(parent);
5afbbe0d 8322+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 8323+ struct dentry *h_parent, *h_dentry;
8324+ struct inode *h_inode, *h_dir;
8b6a4947 8325+ struct au_branch *br;
1facf9fc 8326+
8327+ h_dentry = au_h_dptr(dentry, bindex);
8328+ if (h_dentry) {
5527c038 8329+ if (d_is_positive(h_dentry))
1facf9fc 8330+ npositive++;
5afbbe0d 8331+ break;
1facf9fc 8332+ }
8333+ h_parent = au_h_dptr(parent, bindex);
2000de60 8334+ if (!h_parent || !d_is_dir(h_parent))
1facf9fc 8335+ continue;
8336+
8b6a4947
AM
8337+ if (dirren) {
8338+ /* if the inum matches, then use the prepared name */
8339+ err = au_dr_lkup_name(&args, bindex);
8340+ if (unlikely(err))
8341+ goto out_parent;
8342+ }
8343+
5527c038 8344+ h_dir = d_inode(h_parent);
be118d29 8345+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
8b6a4947 8346+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &args);
3c1bdaff 8347+ inode_unlock_shared(h_dir);
1facf9fc 8348+ err = PTR_ERR(h_dentry);
8349+ if (IS_ERR(h_dentry))
4a4d8108 8350+ goto out_parent;
2000de60
JR
8351+ if (h_dentry)
8352+ au_fclr_lkup(args.flags, ALLOW_NEG);
076b876e
AM
8353+ if (dirperm1)
8354+ au_fset_lkup(args.flags, IGNORE_PERM);
1facf9fc 8355+
79b8bda9 8356+ if (au_dbwh(dentry) == bindex)
1facf9fc 8357+ break;
8358+ if (!h_dentry)
8359+ continue;
5527c038 8360+ if (d_is_negative(h_dentry))
1facf9fc 8361+ continue;
5527c038 8362+ h_inode = d_inode(h_dentry);
1facf9fc 8363+ npositive++;
8364+ if (!args.type)
8365+ args.type = h_inode->i_mode & S_IFMT;
8366+ if (args.type != S_IFDIR)
8367+ break;
8368+ else if (isdir) {
8369+ /* the type of lower may be different */
8370+ bdiropq = au_dbdiropq(dentry);
8371+ if (bdiropq >= 0 && bdiropq <= bindex)
8372+ break;
8373+ }
8b6a4947
AM
8374+ br = au_sbr(sb, bindex);
8375+ if (dirren
8376+ && au_dr_hino_test_add(&br->br_dirren, h_inode->i_ino,
8377+ /*add_ent*/NULL)) {
8378+ /* prepare next name to lookup */
8379+ err = au_dr_lkup(&args, dentry, bindex);
8380+ if (unlikely(err))
8381+ goto out_parent;
8382+ }
1facf9fc 8383+ }
8384+
8385+ if (npositive) {
8386+ AuLabel(positive);
5afbbe0d 8387+ au_update_dbtop(dentry);
1facf9fc 8388+ }
8389+ err = npositive;
076b876e 8390+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
5afbbe0d 8391+ && au_dbtop(dentry) < 0)) {
1facf9fc 8392+ err = -EIO;
523b37e3
AM
8393+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
8394+ dentry, err);
027c5e7a 8395+ }
1facf9fc 8396+
4f0767ce 8397+out_parent:
4a4d8108 8398+ dput(parent);
9f237c51 8399+ au_kfree_try_rcu(args.whname.name);
8b6a4947
AM
8400+ if (dirren)
8401+ au_dr_lkup_fin(&args);
4f0767ce 8402+out:
1facf9fc 8403+ return err;
8404+}
8405+
076b876e 8406+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
1facf9fc 8407+{
8408+ struct dentry *dentry;
8409+ int wkq_err;
8410+
5527c038 8411+ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC))
b4510431 8412+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 8413+ else {
b4510431
AM
8414+ struct vfsub_lkup_one_args args = {
8415+ .errp = &dentry,
8416+ .name = name,
8417+ .parent = parent
1facf9fc 8418+ };
8419+
b4510431 8420+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 8421+ if (unlikely(wkq_err))
8422+ dentry = ERR_PTR(wkq_err);
8423+ }
8424+
8425+ return dentry;
8426+}
8427+
8428+/*
8429+ * lookup @dentry on @bindex which should be negative.
8430+ */
86dc4139 8431+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 8432+{
8433+ int err;
8434+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 8435+ struct au_branch *br;
1facf9fc 8436+
1facf9fc 8437+ parent = dget_parent(dentry);
8438+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
8439+ br = au_sbr(dentry->d_sb, bindex);
8440+ if (wh)
8441+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
8442+ else
076b876e 8443+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 8444+ err = PTR_ERR(h_dentry);
8445+ if (IS_ERR(h_dentry))
8446+ goto out;
5527c038 8447+ if (unlikely(d_is_positive(h_dentry))) {
1facf9fc 8448+ err = -EIO;
523b37e3 8449+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 8450+ dput(h_dentry);
8451+ goto out;
8452+ }
8453+
4a4d8108 8454+ err = 0;
5afbbe0d
AM
8455+ if (bindex < au_dbtop(dentry))
8456+ au_set_dbtop(dentry, bindex);
8457+ if (au_dbbot(dentry) < bindex)
8458+ au_set_dbbot(dentry, bindex);
1facf9fc 8459+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 8460+
4f0767ce 8461+out:
1facf9fc 8462+ dput(parent);
8463+ return err;
8464+}
8465+
8466+/* ---------------------------------------------------------------------- */
8467+
8468+/* subset of struct inode */
8469+struct au_iattr {
8470+ unsigned long i_ino;
8471+ /* unsigned int i_nlink; */
0c3ec466
AM
8472+ kuid_t i_uid;
8473+ kgid_t i_gid;
1facf9fc 8474+ u64 i_version;
8475+/*
8476+ loff_t i_size;
8477+ blkcnt_t i_blocks;
8478+*/
8479+ umode_t i_mode;
8480+};
8481+
8482+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
8483+{
8484+ ia->i_ino = h_inode->i_ino;
8485+ /* ia->i_nlink = h_inode->i_nlink; */
8486+ ia->i_uid = h_inode->i_uid;
8487+ ia->i_gid = h_inode->i_gid;
be118d29 8488+ ia->i_version = inode_query_iversion(h_inode);
1facf9fc 8489+/*
8490+ ia->i_size = h_inode->i_size;
8491+ ia->i_blocks = h_inode->i_blocks;
8492+*/
8493+ ia->i_mode = (h_inode->i_mode & S_IFMT);
8494+}
8495+
8496+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
8497+{
8498+ return ia->i_ino != h_inode->i_ino
8499+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 8500+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 8501+ || !gid_eq(ia->i_gid, h_inode->i_gid)
be118d29 8502+ || !inode_eq_iversion(h_inode, ia->i_version)
1facf9fc 8503+/*
8504+ || ia->i_size != h_inode->i_size
8505+ || ia->i_blocks != h_inode->i_blocks
8506+*/
8507+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
8508+}
8509+
8510+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
8511+ struct au_branch *br)
8512+{
8513+ int err;
8514+ struct au_iattr ia;
8515+ struct inode *h_inode;
8516+ struct dentry *h_d;
8517+ struct super_block *h_sb;
8518+
8519+ err = 0;
8520+ memset(&ia, -1, sizeof(ia));
8521+ h_sb = h_dentry->d_sb;
5527c038
JR
8522+ h_inode = NULL;
8523+ if (d_is_positive(h_dentry)) {
8524+ h_inode = d_inode(h_dentry);
1facf9fc 8525+ au_iattr_save(&ia, h_inode);
5527c038 8526+ } else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
1facf9fc 8527+ /* nfs d_revalidate may return 0 for negative dentry */
8528+ /* fuse d_revalidate always return 0 for negative dentry */
8529+ goto out;
8530+
8531+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 8532+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 8533+ err = PTR_ERR(h_d);
8534+ if (IS_ERR(h_d))
8535+ goto out;
8536+
8537+ err = 0;
8538+ if (unlikely(h_d != h_dentry
5527c038 8539+ || d_inode(h_d) != h_inode
1facf9fc 8540+ || (h_inode && au_iattr_test(&ia, h_inode))))
8541+ err = au_busy_or_stale();
8542+ dput(h_d);
8543+
4f0767ce 8544+out:
1facf9fc 8545+ AuTraceErr(err);
8546+ return err;
8547+}
8548+
8549+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8550+ struct dentry *h_parent, struct au_branch *br)
8551+{
8552+ int err;
8553+
8554+ err = 0;
027c5e7a
AM
8555+ if (udba == AuOpt_UDBA_REVAL
8556+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 8557+ IMustLock(h_dir);
5527c038 8558+ err = (d_inode(h_dentry->d_parent) != h_dir);
027c5e7a 8559+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 8560+ err = au_h_verify_dentry(h_dentry, h_parent, br);
8561+
8562+ return err;
8563+}
8564+
8565+/* ---------------------------------------------------------------------- */
8566+
027c5e7a 8567+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 8568+{
027c5e7a 8569+ int err;
5afbbe0d 8570+ aufs_bindex_t new_bindex, bindex, bbot, bwh, bdiropq;
027c5e7a
AM
8571+ struct au_hdentry tmp, *p, *q;
8572+ struct au_dinfo *dinfo;
8573+ struct super_block *sb;
1facf9fc 8574+
027c5e7a 8575+ DiMustWriteLock(dentry);
1308ab2a 8576+
027c5e7a
AM
8577+ sb = dentry->d_sb;
8578+ dinfo = au_di(dentry);
5afbbe0d 8579+ bbot = dinfo->di_bbot;
1facf9fc 8580+ bwh = dinfo->di_bwh;
8581+ bdiropq = dinfo->di_bdiropq;
5afbbe0d
AM
8582+ bindex = dinfo->di_btop;
8583+ p = au_hdentry(dinfo, bindex);
8584+ for (; bindex <= bbot; bindex++, p++) {
027c5e7a 8585+ if (!p->hd_dentry)
1facf9fc 8586+ continue;
8587+
027c5e7a
AM
8588+ new_bindex = au_br_index(sb, p->hd_id);
8589+ if (new_bindex == bindex)
1facf9fc 8590+ continue;
1facf9fc 8591+
1facf9fc 8592+ if (dinfo->di_bwh == bindex)
8593+ bwh = new_bindex;
8594+ if (dinfo->di_bdiropq == bindex)
8595+ bdiropq = new_bindex;
8596+ if (new_bindex < 0) {
8597+ au_hdput(p);
8598+ p->hd_dentry = NULL;
8599+ continue;
8600+ }
8601+
8602+ /* swap two lower dentries, and loop again */
5afbbe0d 8603+ q = au_hdentry(dinfo, new_bindex);
1facf9fc 8604+ tmp = *q;
8605+ *q = *p;
8606+ *p = tmp;
8607+ if (tmp.hd_dentry) {
8608+ bindex--;
8609+ p--;
8610+ }
8611+ }
8612+
1facf9fc 8613+ dinfo->di_bwh = -1;
5afbbe0d 8614+ if (bwh >= 0 && bwh <= au_sbbot(sb) && au_sbr_whable(sb, bwh))
1facf9fc 8615+ dinfo->di_bwh = bwh;
8616+
8617+ dinfo->di_bdiropq = -1;
8618+ if (bdiropq >= 0
5afbbe0d 8619+ && bdiropq <= au_sbbot(sb)
1facf9fc 8620+ && au_sbr_whable(sb, bdiropq))
8621+ dinfo->di_bdiropq = bdiropq;
8622+
027c5e7a 8623+ err = -EIO;
5afbbe0d
AM
8624+ dinfo->di_btop = -1;
8625+ dinfo->di_bbot = -1;
8626+ bbot = au_dbbot(parent);
8627+ bindex = 0;
8628+ p = au_hdentry(dinfo, bindex);
8629+ for (; bindex <= bbot; bindex++, p++)
1facf9fc 8630+ if (p->hd_dentry) {
5afbbe0d 8631+ dinfo->di_btop = bindex;
1facf9fc 8632+ break;
8633+ }
8634+
5afbbe0d
AM
8635+ if (dinfo->di_btop >= 0) {
8636+ bindex = bbot;
8637+ p = au_hdentry(dinfo, bindex);
8638+ for (; bindex >= 0; bindex--, p--)
027c5e7a 8639+ if (p->hd_dentry) {
5afbbe0d 8640+ dinfo->di_bbot = bindex;
027c5e7a
AM
8641+ err = 0;
8642+ break;
8643+ }
8644+ }
8645+
8646+ return err;
1facf9fc 8647+}
8648+
027c5e7a 8649+static void au_do_hide(struct dentry *dentry)
1facf9fc 8650+{
027c5e7a 8651+ struct inode *inode;
1facf9fc 8652+
5527c038
JR
8653+ if (d_really_is_positive(dentry)) {
8654+ inode = d_inode(dentry);
8655+ if (!d_is_dir(dentry)) {
027c5e7a
AM
8656+ if (inode->i_nlink && !d_unhashed(dentry))
8657+ drop_nlink(inode);
8658+ } else {
8659+ clear_nlink(inode);
8660+ /* stop next lookup */
8661+ inode->i_flags |= S_DEAD;
8662+ }
8663+ smp_mb(); /* necessary? */
8664+ }
8665+ d_drop(dentry);
8666+}
1308ab2a 8667+
027c5e7a
AM
8668+static int au_hide_children(struct dentry *parent)
8669+{
8670+ int err, i, j, ndentry;
8671+ struct au_dcsub_pages dpages;
8672+ struct au_dpage *dpage;
8673+ struct dentry *dentry;
1facf9fc 8674+
027c5e7a 8675+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 8676+ if (unlikely(err))
8677+ goto out;
027c5e7a
AM
8678+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
8679+ if (unlikely(err))
8680+ goto out_dpages;
1facf9fc 8681+
027c5e7a
AM
8682+ /* in reverse order */
8683+ for (i = dpages.ndpage - 1; i >= 0; i--) {
8684+ dpage = dpages.dpages + i;
8685+ ndentry = dpage->ndentry;
8686+ for (j = ndentry - 1; j >= 0; j--) {
8687+ dentry = dpage->dentries[j];
8688+ if (dentry != parent)
8689+ au_do_hide(dentry);
8690+ }
8691+ }
1facf9fc 8692+
027c5e7a
AM
8693+out_dpages:
8694+ au_dpages_free(&dpages);
4f0767ce 8695+out:
027c5e7a 8696+ return err;
1facf9fc 8697+}
8698+
027c5e7a 8699+static void au_hide(struct dentry *dentry)
1facf9fc 8700+{
027c5e7a 8701+ int err;
1facf9fc 8702+
027c5e7a 8703+ AuDbgDentry(dentry);
2000de60 8704+ if (d_is_dir(dentry)) {
027c5e7a
AM
8705+ /* shrink_dcache_parent(dentry); */
8706+ err = au_hide_children(dentry);
8707+ if (unlikely(err))
523b37e3
AM
8708+ AuIOErr("%pd, failed hiding children, ignored %d\n",
8709+ dentry, err);
027c5e7a
AM
8710+ }
8711+ au_do_hide(dentry);
8712+}
1facf9fc 8713+
027c5e7a
AM
8714+/*
8715+ * By adding a dirty branch, a cached dentry may be affected in various ways.
8716+ *
8717+ * a dirty branch is added
8718+ * - on the top of layers
8719+ * - in the middle of layers
8720+ * - to the bottom of layers
8721+ *
8722+ * on the added branch there exists
8723+ * - a whiteout
8724+ * - a diropq
8725+ * - a same named entry
8726+ * + exist
8727+ * * negative --> positive
8728+ * * positive --> positive
8729+ * - type is unchanged
8730+ * - type is changed
8731+ * + doesn't exist
8732+ * * negative --> negative
8733+ * * positive --> negative (rejected by au_br_del() for non-dir case)
8734+ * - none
8735+ */
8736+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
8737+ struct au_dinfo *tmp)
8738+{
8739+ int err;
5afbbe0d 8740+ aufs_bindex_t bindex, bbot;
027c5e7a
AM
8741+ struct {
8742+ struct dentry *dentry;
8743+ struct inode *inode;
8744+ mode_t mode;
be52b249
AM
8745+ } orig_h, tmp_h = {
8746+ .dentry = NULL
8747+ };
027c5e7a
AM
8748+ struct au_hdentry *hd;
8749+ struct inode *inode, *h_inode;
8750+ struct dentry *h_dentry;
8751+
8752+ err = 0;
5afbbe0d 8753+ AuDebugOn(dinfo->di_btop < 0);
027c5e7a 8754+ orig_h.mode = 0;
5afbbe0d 8755+ orig_h.dentry = au_hdentry(dinfo, dinfo->di_btop)->hd_dentry;
5527c038
JR
8756+ orig_h.inode = NULL;
8757+ if (d_is_positive(orig_h.dentry)) {
8758+ orig_h.inode = d_inode(orig_h.dentry);
027c5e7a 8759+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
5527c038 8760+ }
5afbbe0d
AM
8761+ if (tmp->di_btop >= 0) {
8762+ tmp_h.dentry = au_hdentry(tmp, tmp->di_btop)->hd_dentry;
5527c038
JR
8763+ if (d_is_positive(tmp_h.dentry)) {
8764+ tmp_h.inode = d_inode(tmp_h.dentry);
027c5e7a 8765+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
5527c038 8766+ }
027c5e7a
AM
8767+ }
8768+
5527c038
JR
8769+ inode = NULL;
8770+ if (d_really_is_positive(dentry))
8771+ inode = d_inode(dentry);
027c5e7a 8772+ if (!orig_h.inode) {
acd2b654 8773+ AuDbg("negative originally\n");
027c5e7a
AM
8774+ if (inode) {
8775+ au_hide(dentry);
8776+ goto out;
8777+ }
8778+ AuDebugOn(inode);
5afbbe0d 8779+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
027c5e7a
AM
8780+ AuDebugOn(dinfo->di_bdiropq != -1);
8781+
8782+ if (!tmp_h.inode) {
8783+ AuDbg("negative --> negative\n");
8784+ /* should have only one negative lower */
5afbbe0d
AM
8785+ if (tmp->di_btop >= 0
8786+ && tmp->di_btop < dinfo->di_btop) {
8787+ AuDebugOn(tmp->di_btop != tmp->di_bbot);
8788+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
8789+ au_set_h_dptr(dentry, dinfo->di_btop, NULL);
027c5e7a 8790+ au_di_cp(dinfo, tmp);
5afbbe0d
AM
8791+ hd = au_hdentry(tmp, tmp->di_btop);
8792+ au_set_h_dptr(dentry, tmp->di_btop,
027c5e7a
AM
8793+ dget(hd->hd_dentry));
8794+ }
8795+ au_dbg_verify_dinode(dentry);
8796+ } else {
8797+ AuDbg("negative --> positive\n");
8798+ /*
8799+ * similar to the behaviour of creating with bypassing
8800+ * aufs.
8801+ * unhash it in order to force an error in the
8802+ * succeeding create operation.
8803+ * we should not set S_DEAD here.
8804+ */
8805+ d_drop(dentry);
8806+ /* au_di_swap(tmp, dinfo); */
8807+ au_dbg_verify_dinode(dentry);
8808+ }
8809+ } else {
8810+ AuDbg("positive originally\n");
8811+ /* inode may be NULL */
8812+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
8813+ if (!tmp_h.inode) {
8814+ AuDbg("positive --> negative\n");
8815+ /* or bypassing aufs */
8816+ au_hide(dentry);
5afbbe0d 8817+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_btop)
027c5e7a
AM
8818+ dinfo->di_bwh = tmp->di_bwh;
8819+ if (inode)
8820+ err = au_refresh_hinode_self(inode);
8821+ au_dbg_verify_dinode(dentry);
8822+ } else if (orig_h.mode == tmp_h.mode) {
8823+ AuDbg("positive --> positive, same type\n");
8824+ if (!S_ISDIR(orig_h.mode)
5afbbe0d 8825+ && dinfo->di_btop > tmp->di_btop) {
027c5e7a
AM
8826+ /*
8827+ * similar to the behaviour of removing and
8828+ * creating.
8829+ */
8830+ au_hide(dentry);
8831+ if (inode)
8832+ err = au_refresh_hinode_self(inode);
8833+ au_dbg_verify_dinode(dentry);
8834+ } else {
8835+ /* fill empty slots */
5afbbe0d
AM
8836+ if (dinfo->di_btop > tmp->di_btop)
8837+ dinfo->di_btop = tmp->di_btop;
8838+ if (dinfo->di_bbot < tmp->di_bbot)
8839+ dinfo->di_bbot = tmp->di_bbot;
027c5e7a
AM
8840+ dinfo->di_bwh = tmp->di_bwh;
8841+ dinfo->di_bdiropq = tmp->di_bdiropq;
5afbbe0d
AM
8842+ bbot = dinfo->di_bbot;
8843+ bindex = tmp->di_btop;
8844+ hd = au_hdentry(tmp, bindex);
8845+ for (; bindex <= bbot; bindex++, hd++) {
027c5e7a
AM
8846+ if (au_h_dptr(dentry, bindex))
8847+ continue;
5afbbe0d 8848+ h_dentry = hd->hd_dentry;
027c5e7a
AM
8849+ if (!h_dentry)
8850+ continue;
5527c038
JR
8851+ AuDebugOn(d_is_negative(h_dentry));
8852+ h_inode = d_inode(h_dentry);
027c5e7a
AM
8853+ AuDebugOn(orig_h.mode
8854+ != (h_inode->i_mode
8855+ & S_IFMT));
8856+ au_set_h_dptr(dentry, bindex,
8857+ dget(h_dentry));
8858+ }
5afbbe0d
AM
8859+ if (inode)
8860+ err = au_refresh_hinode(inode, dentry);
027c5e7a
AM
8861+ au_dbg_verify_dinode(dentry);
8862+ }
8863+ } else {
8864+ AuDbg("positive --> positive, different type\n");
8865+ /* similar to the behaviour of removing and creating */
8866+ au_hide(dentry);
8867+ if (inode)
8868+ err = au_refresh_hinode_self(inode);
8869+ au_dbg_verify_dinode(dentry);
8870+ }
8871+ }
8872+
8873+out:
8874+ return err;
8875+}
8876+
79b8bda9
AM
8877+void au_refresh_dop(struct dentry *dentry, int force_reval)
8878+{
8879+ const struct dentry_operations *dop
8880+ = force_reval ? &aufs_dop : dentry->d_sb->s_d_op;
8881+ static const unsigned int mask
8882+ = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE;
8883+
8884+ BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags));
8885+
8886+ if (dentry->d_op == dop)
8887+ return;
8888+
8889+ AuDbg("%pd\n", dentry);
8890+ spin_lock(&dentry->d_lock);
8891+ if (dop == &aufs_dop)
8892+ dentry->d_flags |= mask;
8893+ else
8894+ dentry->d_flags &= ~mask;
8895+ dentry->d_op = dop;
8896+ spin_unlock(&dentry->d_lock);
8897+}
8898+
027c5e7a
AM
8899+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
8900+{
e2f27e51 8901+ int err, ebrange, nbr;
027c5e7a
AM
8902+ unsigned int sigen;
8903+ struct au_dinfo *dinfo, *tmp;
8904+ struct super_block *sb;
8905+ struct inode *inode;
8906+
8907+ DiMustWriteLock(dentry);
8908+ AuDebugOn(IS_ROOT(dentry));
5527c038 8909+ AuDebugOn(d_really_is_negative(parent));
027c5e7a
AM
8910+
8911+ sb = dentry->d_sb;
027c5e7a
AM
8912+ sigen = au_sigen(sb);
8913+ err = au_digen_test(parent, sigen);
8914+ if (unlikely(err))
8915+ goto out;
8916+
e2f27e51 8917+ nbr = au_sbbot(sb) + 1;
027c5e7a 8918+ dinfo = au_di(dentry);
e2f27e51 8919+ err = au_di_realloc(dinfo, nbr, /*may_shrink*/0);
027c5e7a
AM
8920+ if (unlikely(err))
8921+ goto out;
8922+ ebrange = au_dbrange_test(dentry);
8923+ if (!ebrange)
8924+ ebrange = au_do_refresh_hdentry(dentry, parent);
8925+
38d290e6 8926+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
5afbbe0d 8927+ AuDebugOn(au_dbtop(dentry) < 0 && au_dbbot(dentry) >= 0);
5527c038
JR
8928+ if (d_really_is_positive(dentry)) {
8929+ inode = d_inode(dentry);
027c5e7a 8930+ err = au_refresh_hinode_self(inode);
5527c038 8931+ }
027c5e7a
AM
8932+ au_dbg_verify_dinode(dentry);
8933+ if (!err)
8934+ goto out_dgen; /* success */
8935+ goto out;
8936+ }
8937+
8938+ /* temporary dinfo */
8939+ AuDbgDentry(dentry);
8940+ err = -ENOMEM;
8941+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
8942+ if (unlikely(!tmp))
8943+ goto out;
8944+ au_di_swap(tmp, dinfo);
8945+ /* returns the number of positive dentries */
8946+ /*
8947+ * if current working dir is removed, it returns an error.
8948+ * but the dentry is legal.
8949+ */
5afbbe0d 8950+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG);
027c5e7a
AM
8951+ AuDbgDentry(dentry);
8952+ au_di_swap(tmp, dinfo);
8953+ if (err == -ENOENT)
8954+ err = 0;
8955+ if (err >= 0) {
8956+ /* compare/refresh by dinfo */
8957+ AuDbgDentry(dentry);
8958+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
8959+ au_dbg_verify_dinode(dentry);
8960+ AuTraceErr(err);
8961+ }
e2f27e51 8962+ au_di_realloc(dinfo, nbr, /*may_shrink*/1); /* harmless if err */
027c5e7a
AM
8963+ au_rw_write_unlock(&tmp->di_rwsem);
8964+ au_di_free(tmp);
8965+ if (unlikely(err))
8966+ goto out;
8967+
8968+out_dgen:
8969+ au_update_digen(dentry);
8970+out:
8971+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 8972+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
8973+ AuDbgDentry(dentry);
8974+ }
8975+ AuTraceErr(err);
8976+ return err;
8977+}
8978+
b4510431
AM
8979+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
8980+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
8981+{
8982+ int err, valid;
027c5e7a
AM
8983+
8984+ err = 0;
8985+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
8986+ goto out;
027c5e7a
AM
8987+
8988+ AuDbg("b%d\n", bindex);
b4510431
AM
8989+ /*
8990+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
8991+ * due to whiteout and branch permission.
8992+ */
8993+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
8994+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
8995+ /* it may return tri-state */
8996+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 8997+
8998+ if (unlikely(valid < 0))
8999+ err = valid;
9000+ else if (!valid)
9001+ err = -EINVAL;
9002+
4f0767ce 9003+out:
1facf9fc 9004+ AuTraceErr(err);
9005+ return err;
9006+}
9007+
9008+/* todo: remove this */
9009+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
8b6a4947 9010+ unsigned int flags, int do_udba, int dirren)
1facf9fc 9011+{
9012+ int err;
9013+ umode_t mode, h_mode;
5afbbe0d 9014+ aufs_bindex_t bindex, btail, btop, ibs, ibe;
38d290e6 9015+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
4a4d8108 9016+ struct inode *h_inode, *h_cached_inode;
1facf9fc 9017+ struct dentry *h_dentry;
9018+ struct qstr *name, *h_name;
9019+
9020+ err = 0;
9021+ plus = 0;
9022+ mode = 0;
1facf9fc 9023+ ibs = -1;
9024+ ibe = -1;
9025+ unhashed = !!d_unhashed(dentry);
9026+ is_root = !!IS_ROOT(dentry);
9027+ name = &dentry->d_name;
38d290e6 9028+ tmpfile = au_di(dentry)->di_tmpfile;
1facf9fc 9029+
9030+ /*
7f207e10
AM
9031+ * Theoretically, REVAL test should be unnecessary in case of
9032+ * {FS,I}NOTIFY.
9033+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 9034+ * IN_ATTRIB for atime/nlink/pageio
1facf9fc 9035+ * Let's do REVAL test too.
9036+ */
9037+ if (do_udba && inode) {
9038+ mode = (inode->i_mode & S_IFMT);
9039+ plus = (inode->i_nlink > 0);
5afbbe0d
AM
9040+ ibs = au_ibtop(inode);
9041+ ibe = au_ibbot(inode);
1facf9fc 9042+ }
9043+
5afbbe0d
AM
9044+ btop = au_dbtop(dentry);
9045+ btail = btop;
1facf9fc 9046+ if (inode && S_ISDIR(inode->i_mode))
9047+ btail = au_dbtaildir(dentry);
5afbbe0d 9048+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 9049+ h_dentry = au_h_dptr(dentry, bindex);
9050+ if (!h_dentry)
9051+ continue;
9052+
523b37e3
AM
9053+ AuDbg("b%d, %pd\n", bindex, h_dentry);
9054+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 9055+ spin_lock(&h_dentry->d_lock);
1facf9fc 9056+ h_name = &h_dentry->d_name;
9057+ if (unlikely(do_udba
9058+ && !is_root
523b37e3
AM
9059+ && ((!h_nfs
9060+ && (unhashed != !!d_unhashed(h_dentry)
8b6a4947 9061+ || (!tmpfile && !dirren
38d290e6
JR
9062+ && !au_qstreq(name, h_name))
9063+ ))
523b37e3
AM
9064+ || (h_nfs
9065+ && !(flags & LOOKUP_OPEN)
9066+ && (h_dentry->d_flags
9067+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 9068+ )) {
38d290e6
JR
9069+ int h_unhashed;
9070+
9071+ h_unhashed = d_unhashed(h_dentry);
027c5e7a 9072+ spin_unlock(&h_dentry->d_lock);
38d290e6
JR
9073+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
9074+ unhashed, h_unhashed, dentry, h_dentry);
1facf9fc 9075+ goto err;
9076+ }
027c5e7a 9077+ spin_unlock(&h_dentry->d_lock);
1facf9fc 9078+
b4510431 9079+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 9080+ if (unlikely(err))
9081+ /* do not goto err, to keep the errno */
9082+ break;
9083+
9084+ /* todo: plink too? */
9085+ if (!do_udba)
9086+ continue;
9087+
9088+ /* UDBA tests */
5527c038 9089+ if (unlikely(!!inode != d_is_positive(h_dentry)))
1facf9fc 9090+ goto err;
9091+
5527c038
JR
9092+ h_inode = NULL;
9093+ if (d_is_positive(h_dentry))
9094+ h_inode = d_inode(h_dentry);
1facf9fc 9095+ h_plus = plus;
9096+ h_mode = mode;
9097+ h_cached_inode = h_inode;
9098+ if (h_inode) {
9099+ h_mode = (h_inode->i_mode & S_IFMT);
9100+ h_plus = (h_inode->i_nlink > 0);
9101+ }
9102+ if (inode && ibs <= bindex && bindex <= ibe)
9103+ h_cached_inode = au_h_iptr(inode, bindex);
9104+
523b37e3 9105+ if (!h_nfs) {
38d290e6 9106+ if (unlikely(plus != h_plus && !tmpfile))
523b37e3
AM
9107+ goto err;
9108+ } else {
9109+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
9110+ && !is_root
9111+ && !IS_ROOT(h_dentry)
9112+ && unhashed != d_unhashed(h_dentry)))
9113+ goto err;
9114+ }
9115+ if (unlikely(mode != h_mode
1facf9fc 9116+ || h_cached_inode != h_inode))
9117+ goto err;
9118+ continue;
9119+
f6b6e03d 9120+err:
1facf9fc 9121+ err = -EINVAL;
9122+ break;
9123+ }
9124+
523b37e3 9125+ AuTraceErr(err);
1facf9fc 9126+ return err;
9127+}
9128+
027c5e7a 9129+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 9130+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
9131+{
9132+ int err;
9133+ struct dentry *parent;
1facf9fc 9134+
027c5e7a 9135+ if (!au_digen_test(dentry, sigen))
1facf9fc 9136+ return 0;
9137+
9138+ parent = dget_parent(dentry);
9139+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 9140+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 9141+ au_dbg_verify_gen(parent, sigen);
027c5e7a 9142+ err = au_refresh_dentry(dentry, parent);
1facf9fc 9143+ di_read_unlock(parent, AuLock_IR);
9144+ dput(parent);
027c5e7a 9145+ AuTraceErr(err);
1facf9fc 9146+ return err;
9147+}
9148+
9149+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
9150+{
9151+ int err;
9152+ struct dentry *d, *parent;
1facf9fc 9153+
027c5e7a 9154+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 9155+ return simple_reval_dpath(dentry, sigen);
9156+
9157+ /* slow loop, keep it simple and stupid */
9158+ /* cf: au_cpup_dirs() */
9159+ err = 0;
9160+ parent = NULL;
027c5e7a 9161+ while (au_digen_test(dentry, sigen)) {
1facf9fc 9162+ d = dentry;
9163+ while (1) {
9164+ dput(parent);
9165+ parent = dget_parent(d);
027c5e7a 9166+ if (!au_digen_test(parent, sigen))
1facf9fc 9167+ break;
9168+ d = parent;
9169+ }
9170+
1facf9fc 9171+ if (d != dentry)
027c5e7a 9172+ di_write_lock_child2(d);
1facf9fc 9173+
9174+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
9175+ if (au_digen_test(d, sigen)) {
9176+ /*
9177+ * todo: consolidate with simple_reval_dpath(),
9178+ * do_refresh() and au_reval_for_attr().
9179+ */
1facf9fc 9180+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 9181+ err = au_refresh_dentry(d, parent);
1facf9fc 9182+ di_read_unlock(parent, AuLock_IR);
9183+ }
9184+
9185+ if (d != dentry)
9186+ di_write_unlock(d);
9187+ dput(parent);
9188+ if (unlikely(err))
9189+ break;
9190+ }
9191+
9192+ return err;
9193+}
9194+
9195+/*
9196+ * if valid returns 1, otherwise 0.
9197+ */
b4510431 9198+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 9199+{
9200+ int valid, err;
9201+ unsigned int sigen;
8b6a4947 9202+ unsigned char do_udba, dirren;
1facf9fc 9203+ struct super_block *sb;
9204+ struct inode *inode;
9205+
027c5e7a 9206+ /* todo: support rcu-walk? */
b4510431 9207+ if (flags & LOOKUP_RCU)
027c5e7a
AM
9208+ return -ECHILD;
9209+
9210+ valid = 0;
9211+ if (unlikely(!au_di(dentry)))
9212+ goto out;
9213+
e49829fe 9214+ valid = 1;
1facf9fc 9215+ sb = dentry->d_sb;
e49829fe
JR
9216+ /*
9217+ * todo: very ugly
9218+ * i_mutex of parent dir may be held,
9219+ * but we should not return 'invalid' due to busy.
9220+ */
9221+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
9222+ if (unlikely(err)) {
9223+ valid = err;
027c5e7a 9224+ AuTraceErr(err);
e49829fe
JR
9225+ goto out;
9226+ }
5527c038
JR
9227+ inode = NULL;
9228+ if (d_really_is_positive(dentry))
9229+ inode = d_inode(dentry);
5afbbe0d 9230+ if (unlikely(inode && au_is_bad_inode(inode))) {
c1595e42
JR
9231+ err = -EINVAL;
9232+ AuTraceErr(err);
9233+ goto out_dgrade;
9234+ }
027c5e7a
AM
9235+ if (unlikely(au_dbrange_test(dentry))) {
9236+ err = -EINVAL;
9237+ AuTraceErr(err);
9238+ goto out_dgrade;
1facf9fc 9239+ }
027c5e7a
AM
9240+
9241+ sigen = au_sigen(sb);
9242+ if (au_digen_test(dentry, sigen)) {
1facf9fc 9243+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
9244+ err = au_reval_dpath(dentry, sigen);
9245+ if (unlikely(err)) {
9246+ AuTraceErr(err);
1facf9fc 9247+ goto out_dgrade;
027c5e7a 9248+ }
1facf9fc 9249+ }
9250+ di_downgrade_lock(dentry, AuLock_IR);
9251+
1facf9fc 9252+ err = -EINVAL;
c1595e42 9253+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
523b37e3 9254+ && inode
38d290e6 9255+ && !(inode->i_state && I_LINKABLE)
79b8bda9
AM
9256+ && (IS_DEADDIR(inode) || !inode->i_nlink)) {
9257+ AuTraceErr(err);
027c5e7a 9258+ goto out_inval;
79b8bda9 9259+ }
027c5e7a 9260+
1facf9fc 9261+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
9262+ if (do_udba && inode) {
5afbbe0d 9263+ aufs_bindex_t btop = au_ibtop(inode);
027c5e7a 9264+ struct inode *h_inode;
1facf9fc 9265+
5afbbe0d
AM
9266+ if (btop >= 0) {
9267+ h_inode = au_h_iptr(inode, btop);
79b8bda9
AM
9268+ if (h_inode && au_test_higen(inode, h_inode)) {
9269+ AuTraceErr(err);
027c5e7a 9270+ goto out_inval;
79b8bda9 9271+ }
027c5e7a 9272+ }
1facf9fc 9273+ }
9274+
8b6a4947
AM
9275+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN);
9276+ err = h_d_revalidate(dentry, inode, flags, do_udba, dirren);
5afbbe0d 9277+ if (unlikely(!err && do_udba && au_dbtop(dentry) < 0)) {
1facf9fc 9278+ err = -EIO;
523b37e3
AM
9279+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
9280+ dentry, err);
027c5e7a 9281+ }
e49829fe 9282+ goto out_inval;
1facf9fc 9283+
4f0767ce 9284+out_dgrade:
1facf9fc 9285+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 9286+out_inval:
1facf9fc 9287+ aufs_read_unlock(dentry, AuLock_IR);
9288+ AuTraceErr(err);
9289+ valid = !err;
e49829fe 9290+out:
027c5e7a 9291+ if (!valid) {
523b37e3 9292+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
9293+ d_drop(dentry);
9294+ }
1facf9fc 9295+ return valid;
9296+}
9297+
9298+static void aufs_d_release(struct dentry *dentry)
9299+{
027c5e7a 9300+ if (au_di(dentry)) {
4a4d8108
AM
9301+ au_di_fin(dentry);
9302+ au_hn_di_reinit(dentry);
1facf9fc 9303+ }
1facf9fc 9304+}
9305+
4a4d8108 9306+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
9307+ .d_revalidate = aufs_d_revalidate,
9308+ .d_weak_revalidate = aufs_d_revalidate,
9309+ .d_release = aufs_d_release
1facf9fc 9310+};
79b8bda9
AM
9311+
9312+/* aufs_dop without d_revalidate */
9313+const struct dentry_operations aufs_dop_noreval = {
9314+ .d_release = aufs_d_release
9315+};
7f207e10
AM
9316diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
9317--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 9318+++ linux/fs/aufs/dentry.h 2019-03-05 12:13:00.135890907 +0100
9f237c51 9319@@ -0,0 +1,268 @@
062440b3 9320+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 9321+/*
ba1aed25 9322+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 9323+ *
9324+ * This program, aufs is free software; you can redistribute it and/or modify
9325+ * it under the terms of the GNU General Public License as published by
9326+ * the Free Software Foundation; either version 2 of the License, or
9327+ * (at your option) any later version.
dece6358
AM
9328+ *
9329+ * This program is distributed in the hope that it will be useful,
9330+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9331+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9332+ * GNU General Public License for more details.
9333+ *
9334+ * You should have received a copy of the GNU General Public License
523b37e3 9335+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9336+ */
9337+
9338+/*
9339+ * lookup and dentry operations
9340+ */
9341+
9342+#ifndef __AUFS_DENTRY_H__
9343+#define __AUFS_DENTRY_H__
9344+
9345+#ifdef __KERNEL__
9346+
dece6358 9347+#include <linux/dcache.h>
8b6a4947 9348+#include "dirren.h"
1facf9fc 9349+#include "rwsem.h"
9350+
1facf9fc 9351+struct au_hdentry {
9352+ struct dentry *hd_dentry;
027c5e7a 9353+ aufs_bindex_t hd_id;
1facf9fc 9354+};
9355+
9356+struct au_dinfo {
9357+ atomic_t di_generation;
9358+
dece6358 9359+ struct au_rwsem di_rwsem;
5afbbe0d 9360+ aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq;
38d290e6 9361+ unsigned char di_tmpfile; /* to allow the different name */
1c60b727 9362+ struct au_hdentry *di_hdentry;
9f237c51 9363+ struct rcu_head rcu;
4a4d8108 9364+} ____cacheline_aligned_in_smp;
1facf9fc 9365+
9366+/* ---------------------------------------------------------------------- */
9367+
5afbbe0d
AM
9368+/* flags for au_lkup_dentry() */
9369+#define AuLkup_ALLOW_NEG 1
9370+#define AuLkup_IGNORE_PERM (1 << 1)
8b6a4947 9371+#define AuLkup_DIRREN (1 << 2)
5afbbe0d
AM
9372+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
9373+#define au_fset_lkup(flags, name) \
9374+ do { (flags) |= AuLkup_##name; } while (0)
9375+#define au_fclr_lkup(flags, name) \
9376+ do { (flags) &= ~AuLkup_##name; } while (0)
9377+
8b6a4947
AM
9378+#ifndef CONFIG_AUFS_DIRREN
9379+#undef AuLkup_DIRREN
9380+#define AuLkup_DIRREN 0
9381+#endif
9382+
9383+struct au_do_lookup_args {
9384+ unsigned int flags;
9385+ mode_t type;
9386+ struct qstr whname, *name;
9387+ struct au_dr_lookup dirren;
9388+};
9389+
5afbbe0d
AM
9390+/* ---------------------------------------------------------------------- */
9391+
1facf9fc 9392+/* dentry.c */
79b8bda9 9393+extern const struct dentry_operations aufs_dop, aufs_dop_noreval;
1facf9fc 9394+struct au_branch;
076b876e 9395+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
1facf9fc 9396+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
9397+ struct dentry *h_parent, struct au_branch *br);
9398+
5afbbe0d
AM
9399+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
9400+ unsigned int flags);
86dc4139 9401+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 9402+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 9403+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
79b8bda9 9404+void au_refresh_dop(struct dentry *dentry, int force_reval);
1facf9fc 9405+
9406+/* dinfo.c */
4a4d8108 9407+void au_di_init_once(void *_di);
027c5e7a
AM
9408+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
9409+void au_di_free(struct au_dinfo *dinfo);
9410+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
9411+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
9412+int au_di_init(struct dentry *dentry);
9413+void au_di_fin(struct dentry *dentry);
e2f27e51 9414+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink);
1facf9fc 9415+
9416+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
9417+void di_read_unlock(struct dentry *d, int flags);
9418+void di_downgrade_lock(struct dentry *d, int flags);
9419+void di_write_lock(struct dentry *d, unsigned int lsc);
9420+void di_write_unlock(struct dentry *d);
9421+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
9422+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
9423+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
9424+
9425+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 9426+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 9427+aufs_bindex_t au_dbtail(struct dentry *dentry);
9428+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
9429+
9430+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9431+ struct dentry *h_dentry);
027c5e7a
AM
9432+int au_digen_test(struct dentry *dentry, unsigned int sigen);
9433+int au_dbrange_test(struct dentry *dentry);
1facf9fc 9434+void au_update_digen(struct dentry *dentry);
9435+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
5afbbe0d
AM
9436+void au_update_dbtop(struct dentry *dentry);
9437+void au_update_dbbot(struct dentry *dentry);
1facf9fc 9438+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
9439+
9440+/* ---------------------------------------------------------------------- */
9441+
9442+static inline struct au_dinfo *au_di(struct dentry *dentry)
9443+{
9444+ return dentry->d_fsdata;
9445+}
9446+
9447+/* ---------------------------------------------------------------------- */
9448+
9449+/* lock subclass for dinfo */
9450+enum {
9451+ AuLsc_DI_CHILD, /* child first */
4a4d8108 9452+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 9453+ AuLsc_DI_CHILD3, /* copyup dirs */
9454+ AuLsc_DI_PARENT,
9455+ AuLsc_DI_PARENT2,
027c5e7a
AM
9456+ AuLsc_DI_PARENT3,
9457+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 9458+};
9459+
9460+/*
9461+ * di_read_lock_child, di_write_lock_child,
9462+ * di_read_lock_child2, di_write_lock_child2,
9463+ * di_read_lock_child3, di_write_lock_child3,
9464+ * di_read_lock_parent, di_write_lock_parent,
9465+ * di_read_lock_parent2, di_write_lock_parent2,
9466+ * di_read_lock_parent3, di_write_lock_parent3,
9467+ */
9468+#define AuReadLockFunc(name, lsc) \
9469+static inline void di_read_lock_##name(struct dentry *d, int flags) \
9470+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
9471+
9472+#define AuWriteLockFunc(name, lsc) \
9473+static inline void di_write_lock_##name(struct dentry *d) \
9474+{ di_write_lock(d, AuLsc_DI_##lsc); }
9475+
9476+#define AuRWLockFuncs(name, lsc) \
9477+ AuReadLockFunc(name, lsc) \
9478+ AuWriteLockFunc(name, lsc)
9479+
9480+AuRWLockFuncs(child, CHILD);
9481+AuRWLockFuncs(child2, CHILD2);
9482+AuRWLockFuncs(child3, CHILD3);
9483+AuRWLockFuncs(parent, PARENT);
9484+AuRWLockFuncs(parent2, PARENT2);
9485+AuRWLockFuncs(parent3, PARENT3);
9486+
9487+#undef AuReadLockFunc
9488+#undef AuWriteLockFunc
9489+#undef AuRWLockFuncs
9490+
9491+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
9492+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
9493+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 9494+
9495+/* ---------------------------------------------------------------------- */
9496+
9497+/* todo: memory barrier? */
9498+static inline unsigned int au_digen(struct dentry *d)
9499+{
9500+ return atomic_read(&au_di(d)->di_generation);
9501+}
9502+
9503+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
9504+{
9505+ hdentry->hd_dentry = NULL;
9506+}
9507+
5afbbe0d
AM
9508+static inline struct au_hdentry *au_hdentry(struct au_dinfo *di,
9509+ aufs_bindex_t bindex)
9510+{
9511+ return di->di_hdentry + bindex;
9512+}
9513+
1facf9fc 9514+static inline void au_hdput(struct au_hdentry *hd)
9515+{
4a4d8108
AM
9516+ if (hd)
9517+ dput(hd->hd_dentry);
1facf9fc 9518+}
9519+
5afbbe0d 9520+static inline aufs_bindex_t au_dbtop(struct dentry *dentry)
1facf9fc 9521+{
1308ab2a 9522+ DiMustAnyLock(dentry);
5afbbe0d 9523+ return au_di(dentry)->di_btop;
1facf9fc 9524+}
9525+
5afbbe0d 9526+static inline aufs_bindex_t au_dbbot(struct dentry *dentry)
1facf9fc 9527+{
1308ab2a 9528+ DiMustAnyLock(dentry);
5afbbe0d 9529+ return au_di(dentry)->di_bbot;
1facf9fc 9530+}
9531+
9532+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
9533+{
1308ab2a 9534+ DiMustAnyLock(dentry);
1facf9fc 9535+ return au_di(dentry)->di_bwh;
9536+}
9537+
9538+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
9539+{
1308ab2a 9540+ DiMustAnyLock(dentry);
1facf9fc 9541+ return au_di(dentry)->di_bdiropq;
9542+}
9543+
9544+/* todo: hard/soft set? */
5afbbe0d 9545+static inline void au_set_dbtop(struct dentry *dentry, aufs_bindex_t bindex)
1facf9fc 9546+{
1308ab2a 9547+ DiMustWriteLock(dentry);
5afbbe0d 9548+ au_di(dentry)->di_btop = bindex;
1facf9fc 9549+}
9550+
5afbbe0d 9551+static inline void au_set_dbbot(struct dentry *dentry, aufs_bindex_t bindex)
1facf9fc 9552+{
1308ab2a 9553+ DiMustWriteLock(dentry);
5afbbe0d 9554+ au_di(dentry)->di_bbot = bindex;
1facf9fc 9555+}
9556+
9557+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
9558+{
1308ab2a 9559+ DiMustWriteLock(dentry);
5afbbe0d 9560+ /* dbwh can be outside of btop - bbot range */
1facf9fc 9561+ au_di(dentry)->di_bwh = bindex;
9562+}
9563+
9564+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
9565+{
1308ab2a 9566+ DiMustWriteLock(dentry);
1facf9fc 9567+ au_di(dentry)->di_bdiropq = bindex;
9568+}
9569+
9570+/* ---------------------------------------------------------------------- */
9571+
4a4d8108 9572+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 9573+static inline void au_digen_dec(struct dentry *d)
9574+{
e49829fe 9575+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 9576+}
9577+
4a4d8108 9578+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 9579+{
9580+ dentry->d_fsdata = NULL;
9581+}
9582+#else
4a4d8108
AM
9583+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
9584+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 9585+
9586+#endif /* __KERNEL__ */
9587+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
9588diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
9589--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 9590+++ linux/fs/aufs/dinfo.c 2019-03-05 12:13:00.135890907 +0100
062440b3 9591@@ -0,0 +1,554 @@
cd7a4cd9 9592+// SPDX-License-Identifier: GPL-2.0
1facf9fc 9593+/*
ba1aed25 9594+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 9595+ *
9596+ * This program, aufs is free software; you can redistribute it and/or modify
9597+ * it under the terms of the GNU General Public License as published by
9598+ * the Free Software Foundation; either version 2 of the License, or
9599+ * (at your option) any later version.
dece6358
AM
9600+ *
9601+ * This program is distributed in the hope that it will be useful,
9602+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9603+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9604+ * GNU General Public License for more details.
9605+ *
9606+ * You should have received a copy of the GNU General Public License
523b37e3 9607+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9608+ */
9609+
9610+/*
9611+ * dentry private data
9612+ */
9613+
9614+#include "aufs.h"
9615+
e49829fe 9616+void au_di_init_once(void *_dinfo)
4a4d8108 9617+{
e49829fe 9618+ struct au_dinfo *dinfo = _dinfo;
4a4d8108 9619+
e49829fe 9620+ au_rw_init(&dinfo->di_rwsem);
4a4d8108
AM
9621+}
9622+
027c5e7a 9623+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 9624+{
9625+ struct au_dinfo *dinfo;
027c5e7a 9626+ int nbr, i;
1facf9fc 9627+
9628+ dinfo = au_cache_alloc_dinfo();
9629+ if (unlikely(!dinfo))
9630+ goto out;
9631+
5afbbe0d 9632+ nbr = au_sbbot(sb) + 1;
1facf9fc 9633+ if (nbr <= 0)
9634+ nbr = 1;
9635+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
9636+ if (dinfo->di_hdentry) {
9637+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
5afbbe0d
AM
9638+ dinfo->di_btop = -1;
9639+ dinfo->di_bbot = -1;
027c5e7a
AM
9640+ dinfo->di_bwh = -1;
9641+ dinfo->di_bdiropq = -1;
38d290e6 9642+ dinfo->di_tmpfile = 0;
027c5e7a
AM
9643+ for (i = 0; i < nbr; i++)
9644+ dinfo->di_hdentry[i].hd_id = -1;
9645+ goto out;
9646+ }
1facf9fc 9647+
1c60b727 9648+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
9649+ dinfo = NULL;
9650+
4f0767ce 9651+out:
027c5e7a 9652+ return dinfo;
1facf9fc 9653+}
9654+
027c5e7a 9655+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 9656+{
4a4d8108 9657+ struct au_hdentry *p;
5afbbe0d 9658+ aufs_bindex_t bbot, bindex;
4a4d8108
AM
9659+
9660+ /* dentry may not be revalidated */
5afbbe0d 9661+ bindex = dinfo->di_btop;
4a4d8108 9662+ if (bindex >= 0) {
5afbbe0d
AM
9663+ bbot = dinfo->di_bbot;
9664+ p = au_hdentry(dinfo, bindex);
9665+ while (bindex++ <= bbot)
4a4d8108
AM
9666+ au_hdput(p++);
9667+ }
9f237c51 9668+ au_kfree_try_rcu(dinfo->di_hdentry);
1c60b727 9669+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
9670+}
9671+
9672+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
9673+{
9674+ struct au_hdentry *p;
9675+ aufs_bindex_t bi;
9676+
9677+ AuRwMustWriteLock(&a->di_rwsem);
9678+ AuRwMustWriteLock(&b->di_rwsem);
9679+
9680+#define DiSwap(v, name) \
9681+ do { \
9682+ v = a->di_##name; \
9683+ a->di_##name = b->di_##name; \
9684+ b->di_##name = v; \
9685+ } while (0)
9686+
9687+ DiSwap(p, hdentry);
5afbbe0d
AM
9688+ DiSwap(bi, btop);
9689+ DiSwap(bi, bbot);
027c5e7a
AM
9690+ DiSwap(bi, bwh);
9691+ DiSwap(bi, bdiropq);
9692+ /* smp_mb(); */
9693+
9694+#undef DiSwap
9695+}
9696+
9697+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
9698+{
9699+ AuRwMustWriteLock(&dst->di_rwsem);
9700+ AuRwMustWriteLock(&src->di_rwsem);
9701+
5afbbe0d
AM
9702+ dst->di_btop = src->di_btop;
9703+ dst->di_bbot = src->di_bbot;
027c5e7a
AM
9704+ dst->di_bwh = src->di_bwh;
9705+ dst->di_bdiropq = src->di_bdiropq;
9706+ /* smp_mb(); */
9707+}
9708+
9709+int au_di_init(struct dentry *dentry)
9710+{
9711+ int err;
9712+ struct super_block *sb;
9713+ struct au_dinfo *dinfo;
9714+
9715+ err = 0;
9716+ sb = dentry->d_sb;
9717+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
9718+ if (dinfo) {
9719+ atomic_set(&dinfo->di_generation, au_sigen(sb));
9720+ /* smp_mb(); */ /* atomic_set */
9721+ dentry->d_fsdata = dinfo;
9722+ } else
9723+ err = -ENOMEM;
9724+
9725+ return err;
9726+}
9727+
9728+void au_di_fin(struct dentry *dentry)
9729+{
9730+ struct au_dinfo *dinfo;
9731+
9732+ dinfo = au_di(dentry);
9733+ AuRwDestroy(&dinfo->di_rwsem);
9734+ au_di_free(dinfo);
4a4d8108
AM
9735+}
9736+
e2f27e51 9737+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink)
1facf9fc 9738+{
9739+ int err, sz;
9740+ struct au_hdentry *hdp;
9741+
1308ab2a 9742+ AuRwMustWriteLock(&dinfo->di_rwsem);
9743+
1facf9fc 9744+ err = -ENOMEM;
5afbbe0d 9745+ sz = sizeof(*hdp) * (dinfo->di_bbot + 1);
1facf9fc 9746+ if (!sz)
9747+ sz = sizeof(*hdp);
e2f27e51
AM
9748+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS,
9749+ may_shrink);
1facf9fc 9750+ if (hdp) {
9751+ dinfo->di_hdentry = hdp;
9752+ err = 0;
9753+ }
9754+
9755+ return err;
9756+}
9757+
9758+/* ---------------------------------------------------------------------- */
9759+
9760+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
9761+{
9762+ switch (lsc) {
9763+ case AuLsc_DI_CHILD:
9764+ ii_write_lock_child(inode);
9765+ break;
9766+ case AuLsc_DI_CHILD2:
9767+ ii_write_lock_child2(inode);
9768+ break;
9769+ case AuLsc_DI_CHILD3:
9770+ ii_write_lock_child3(inode);
9771+ break;
9772+ case AuLsc_DI_PARENT:
9773+ ii_write_lock_parent(inode);
9774+ break;
9775+ case AuLsc_DI_PARENT2:
9776+ ii_write_lock_parent2(inode);
9777+ break;
9778+ case AuLsc_DI_PARENT3:
9779+ ii_write_lock_parent3(inode);
9780+ break;
9781+ default:
9782+ BUG();
9783+ }
9784+}
9785+
9786+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
9787+{
9788+ switch (lsc) {
9789+ case AuLsc_DI_CHILD:
9790+ ii_read_lock_child(inode);
9791+ break;
9792+ case AuLsc_DI_CHILD2:
9793+ ii_read_lock_child2(inode);
9794+ break;
9795+ case AuLsc_DI_CHILD3:
9796+ ii_read_lock_child3(inode);
9797+ break;
9798+ case AuLsc_DI_PARENT:
9799+ ii_read_lock_parent(inode);
9800+ break;
9801+ case AuLsc_DI_PARENT2:
9802+ ii_read_lock_parent2(inode);
9803+ break;
9804+ case AuLsc_DI_PARENT3:
9805+ ii_read_lock_parent3(inode);
9806+ break;
9807+ default:
9808+ BUG();
9809+ }
9810+}
9811+
9812+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
9813+{
5527c038
JR
9814+ struct inode *inode;
9815+
dece6358 9816+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
5527c038
JR
9817+ if (d_really_is_positive(d)) {
9818+ inode = d_inode(d);
1facf9fc 9819+ if (au_ftest_lock(flags, IW))
5527c038 9820+ do_ii_write_lock(inode, lsc);
1facf9fc 9821+ else if (au_ftest_lock(flags, IR))
5527c038 9822+ do_ii_read_lock(inode, lsc);
1facf9fc 9823+ }
9824+}
9825+
9826+void di_read_unlock(struct dentry *d, int flags)
9827+{
5527c038
JR
9828+ struct inode *inode;
9829+
9830+ if (d_really_is_positive(d)) {
9831+ inode = d_inode(d);
027c5e7a
AM
9832+ if (au_ftest_lock(flags, IW)) {
9833+ au_dbg_verify_dinode(d);
5527c038 9834+ ii_write_unlock(inode);
027c5e7a
AM
9835+ } else if (au_ftest_lock(flags, IR)) {
9836+ au_dbg_verify_dinode(d);
5527c038 9837+ ii_read_unlock(inode);
027c5e7a 9838+ }
1facf9fc 9839+ }
dece6358 9840+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 9841+}
9842+
9843+void di_downgrade_lock(struct dentry *d, int flags)
9844+{
5527c038
JR
9845+ if (d_really_is_positive(d) && au_ftest_lock(flags, IR))
9846+ ii_downgrade_lock(d_inode(d));
dece6358 9847+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 9848+}
9849+
9850+void di_write_lock(struct dentry *d, unsigned int lsc)
9851+{
dece6358 9852+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
5527c038
JR
9853+ if (d_really_is_positive(d))
9854+ do_ii_write_lock(d_inode(d), lsc);
1facf9fc 9855+}
9856+
9857+void di_write_unlock(struct dentry *d)
9858+{
027c5e7a 9859+ au_dbg_verify_dinode(d);
5527c038
JR
9860+ if (d_really_is_positive(d))
9861+ ii_write_unlock(d_inode(d));
dece6358 9862+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 9863+}
9864+
9865+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
9866+{
9867+ AuDebugOn(d1 == d2
5527c038 9868+ || d_inode(d1) == d_inode(d2)
1facf9fc 9869+ || d1->d_sb != d2->d_sb);
9870+
521ced18
JR
9871+ if ((isdir && au_test_subdir(d1, d2))
9872+ || d1 < d2) {
1facf9fc 9873+ di_write_lock_child(d1);
9874+ di_write_lock_child2(d2);
9875+ } else {
1facf9fc 9876+ di_write_lock_child(d2);
9877+ di_write_lock_child2(d1);
9878+ }
9879+}
9880+
9881+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
9882+{
9883+ AuDebugOn(d1 == d2
5527c038 9884+ || d_inode(d1) == d_inode(d2)
1facf9fc 9885+ || d1->d_sb != d2->d_sb);
9886+
521ced18
JR
9887+ if ((isdir && au_test_subdir(d1, d2))
9888+ || d1 < d2) {
1facf9fc 9889+ di_write_lock_parent(d1);
9890+ di_write_lock_parent2(d2);
9891+ } else {
1facf9fc 9892+ di_write_lock_parent(d2);
9893+ di_write_lock_parent2(d1);
9894+ }
9895+}
9896+
9897+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
9898+{
9899+ di_write_unlock(d1);
5527c038 9900+ if (d_inode(d1) == d_inode(d2))
dece6358 9901+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 9902+ else
9903+ di_write_unlock(d2);
9904+}
9905+
9906+/* ---------------------------------------------------------------------- */
9907+
9908+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
9909+{
9910+ struct dentry *d;
9911+
1308ab2a 9912+ DiMustAnyLock(dentry);
9913+
5afbbe0d 9914+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
1facf9fc 9915+ return NULL;
9916+ AuDebugOn(bindex < 0);
5afbbe0d 9917+ d = au_hdentry(au_di(dentry), bindex)->hd_dentry;
c1595e42 9918+ AuDebugOn(d && au_dcount(d) <= 0);
1facf9fc 9919+ return d;
9920+}
9921+
2cbb1c4b
JR
9922+/*
9923+ * extended version of au_h_dptr().
38d290e6
JR
9924+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
9925+ * error.
2cbb1c4b
JR
9926+ */
9927+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
9928+{
9929+ struct dentry *h_dentry;
9930+ struct inode *inode, *h_inode;
9931+
5527c038 9932+ AuDebugOn(d_really_is_negative(dentry));
2cbb1c4b
JR
9933+
9934+ h_dentry = NULL;
5afbbe0d
AM
9935+ if (au_dbtop(dentry) <= bindex
9936+ && bindex <= au_dbbot(dentry))
2cbb1c4b 9937+ h_dentry = au_h_dptr(dentry, bindex);
38d290e6 9938+ if (h_dentry && !au_d_linkable(h_dentry)) {
2cbb1c4b
JR
9939+ dget(h_dentry);
9940+ goto out; /* success */
9941+ }
9942+
5527c038 9943+ inode = d_inode(dentry);
5afbbe0d
AM
9944+ AuDebugOn(bindex < au_ibtop(inode));
9945+ AuDebugOn(au_ibbot(inode) < bindex);
2cbb1c4b
JR
9946+ h_inode = au_h_iptr(inode, bindex);
9947+ h_dentry = d_find_alias(h_inode);
9948+ if (h_dentry) {
9949+ if (!IS_ERR(h_dentry)) {
38d290e6 9950+ if (!au_d_linkable(h_dentry))
2cbb1c4b
JR
9951+ goto out; /* success */
9952+ dput(h_dentry);
9953+ } else
9954+ goto out;
9955+ }
9956+
9957+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
9958+ h_dentry = au_plink_lkup(inode, bindex);
9959+ AuDebugOn(!h_dentry);
9960+ if (!IS_ERR(h_dentry)) {
9961+ if (!au_d_hashed_positive(h_dentry))
9962+ goto out; /* success */
9963+ dput(h_dentry);
9964+ h_dentry = NULL;
9965+ }
9966+ }
9967+
9968+out:
9969+ AuDbgDentry(h_dentry);
9970+ return h_dentry;
9971+}
9972+
1facf9fc 9973+aufs_bindex_t au_dbtail(struct dentry *dentry)
9974+{
5afbbe0d 9975+ aufs_bindex_t bbot, bwh;
1facf9fc 9976+
5afbbe0d
AM
9977+ bbot = au_dbbot(dentry);
9978+ if (0 <= bbot) {
1facf9fc 9979+ bwh = au_dbwh(dentry);
9980+ if (!bwh)
9981+ return bwh;
5afbbe0d 9982+ if (0 < bwh && bwh < bbot)
1facf9fc 9983+ return bwh - 1;
9984+ }
5afbbe0d 9985+ return bbot;
1facf9fc 9986+}
9987+
9988+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
9989+{
5afbbe0d 9990+ aufs_bindex_t bbot, bopq;
1facf9fc 9991+
5afbbe0d
AM
9992+ bbot = au_dbtail(dentry);
9993+ if (0 <= bbot) {
1facf9fc 9994+ bopq = au_dbdiropq(dentry);
5afbbe0d
AM
9995+ if (0 <= bopq && bopq < bbot)
9996+ bbot = bopq;
1facf9fc 9997+ }
5afbbe0d 9998+ return bbot;
1facf9fc 9999+}
10000+
10001+/* ---------------------------------------------------------------------- */
10002+
10003+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
10004+ struct dentry *h_dentry)
10005+{
5afbbe0d
AM
10006+ struct au_dinfo *dinfo;
10007+ struct au_hdentry *hd;
027c5e7a 10008+ struct au_branch *br;
1facf9fc 10009+
1308ab2a 10010+ DiMustWriteLock(dentry);
10011+
5afbbe0d
AM
10012+ dinfo = au_di(dentry);
10013+ hd = au_hdentry(dinfo, bindex);
4a4d8108 10014+ au_hdput(hd);
1facf9fc 10015+ hd->hd_dentry = h_dentry;
027c5e7a
AM
10016+ if (h_dentry) {
10017+ br = au_sbr(dentry->d_sb, bindex);
10018+ hd->hd_id = br->br_id;
10019+ }
10020+}
10021+
10022+int au_dbrange_test(struct dentry *dentry)
10023+{
10024+ int err;
5afbbe0d 10025+ aufs_bindex_t btop, bbot;
027c5e7a
AM
10026+
10027+ err = 0;
5afbbe0d
AM
10028+ btop = au_dbtop(dentry);
10029+ bbot = au_dbbot(dentry);
10030+ if (btop >= 0)
10031+ AuDebugOn(bbot < 0 && btop > bbot);
027c5e7a
AM
10032+ else {
10033+ err = -EIO;
5afbbe0d 10034+ AuDebugOn(bbot >= 0);
027c5e7a
AM
10035+ }
10036+
10037+ return err;
10038+}
10039+
10040+int au_digen_test(struct dentry *dentry, unsigned int sigen)
10041+{
10042+ int err;
10043+
10044+ err = 0;
10045+ if (unlikely(au_digen(dentry) != sigen
5527c038 10046+ || au_iigen_test(d_inode(dentry), sigen)))
027c5e7a
AM
10047+ err = -EIO;
10048+
10049+ return err;
1facf9fc 10050+}
10051+
10052+void au_update_digen(struct dentry *dentry)
10053+{
10054+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
10055+ /* smp_mb(); */ /* atomic_set */
10056+}
10057+
10058+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
10059+{
10060+ struct au_dinfo *dinfo;
10061+ struct dentry *h_d;
4a4d8108 10062+ struct au_hdentry *hdp;
5afbbe0d 10063+ aufs_bindex_t bindex, bbot;
1facf9fc 10064+
1308ab2a 10065+ DiMustWriteLock(dentry);
10066+
1facf9fc 10067+ dinfo = au_di(dentry);
5afbbe0d 10068+ if (!dinfo || dinfo->di_btop < 0)
1facf9fc 10069+ return;
10070+
10071+ if (do_put_zero) {
5afbbe0d
AM
10072+ bbot = dinfo->di_bbot;
10073+ bindex = dinfo->di_btop;
10074+ hdp = au_hdentry(dinfo, bindex);
10075+ for (; bindex <= bbot; bindex++, hdp++) {
10076+ h_d = hdp->hd_dentry;
5527c038 10077+ if (h_d && d_is_negative(h_d))
1facf9fc 10078+ au_set_h_dptr(dentry, bindex, NULL);
10079+ }
10080+ }
10081+
5afbbe0d
AM
10082+ dinfo->di_btop = 0;
10083+ hdp = au_hdentry(dinfo, dinfo->di_btop);
10084+ for (; dinfo->di_btop <= dinfo->di_bbot; dinfo->di_btop++, hdp++)
10085+ if (hdp->hd_dentry)
1facf9fc 10086+ break;
5afbbe0d
AM
10087+ if (dinfo->di_btop > dinfo->di_bbot) {
10088+ dinfo->di_btop = -1;
10089+ dinfo->di_bbot = -1;
1facf9fc 10090+ return;
10091+ }
10092+
5afbbe0d
AM
10093+ hdp = au_hdentry(dinfo, dinfo->di_bbot);
10094+ for (; dinfo->di_bbot >= 0; dinfo->di_bbot--, hdp--)
10095+ if (hdp->hd_dentry)
1facf9fc 10096+ break;
5afbbe0d 10097+ AuDebugOn(dinfo->di_btop > dinfo->di_bbot || dinfo->di_bbot < 0);
1facf9fc 10098+}
10099+
5afbbe0d 10100+void au_update_dbtop(struct dentry *dentry)
1facf9fc 10101+{
5afbbe0d 10102+ aufs_bindex_t bindex, bbot;
1facf9fc 10103+ struct dentry *h_dentry;
10104+
5afbbe0d
AM
10105+ bbot = au_dbbot(dentry);
10106+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) {
1facf9fc 10107+ h_dentry = au_h_dptr(dentry, bindex);
10108+ if (!h_dentry)
10109+ continue;
5527c038 10110+ if (d_is_positive(h_dentry)) {
5afbbe0d 10111+ au_set_dbtop(dentry, bindex);
1facf9fc 10112+ return;
10113+ }
10114+ au_set_h_dptr(dentry, bindex, NULL);
10115+ }
10116+}
10117+
5afbbe0d 10118+void au_update_dbbot(struct dentry *dentry)
1facf9fc 10119+{
5afbbe0d 10120+ aufs_bindex_t bindex, btop;
1facf9fc 10121+ struct dentry *h_dentry;
10122+
5afbbe0d
AM
10123+ btop = au_dbtop(dentry);
10124+ for (bindex = au_dbbot(dentry); bindex >= btop; bindex--) {
1facf9fc 10125+ h_dentry = au_h_dptr(dentry, bindex);
10126+ if (!h_dentry)
10127+ continue;
5527c038 10128+ if (d_is_positive(h_dentry)) {
5afbbe0d 10129+ au_set_dbbot(dentry, bindex);
1facf9fc 10130+ return;
10131+ }
10132+ au_set_h_dptr(dentry, bindex, NULL);
10133+ }
10134+}
10135+
10136+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
10137+{
5afbbe0d 10138+ aufs_bindex_t bindex, bbot;
1facf9fc 10139+
5afbbe0d
AM
10140+ bbot = au_dbbot(dentry);
10141+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++)
1facf9fc 10142+ if (au_h_dptr(dentry, bindex) == h_dentry)
10143+ return bindex;
10144+ return -1;
10145+}
7f207e10
AM
10146diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
10147--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
10148+++ linux/fs/aufs/dir.c 2019-05-06 09:03:04.816810402 +0200
10149@@ -0,0 +1,763 @@
cd7a4cd9 10150+// SPDX-License-Identifier: GPL-2.0
1facf9fc 10151+/*
ba1aed25 10152+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 10153+ *
10154+ * This program, aufs is free software; you can redistribute it and/or modify
10155+ * it under the terms of the GNU General Public License as published by
10156+ * the Free Software Foundation; either version 2 of the License, or
10157+ * (at your option) any later version.
dece6358
AM
10158+ *
10159+ * This program is distributed in the hope that it will be useful,
10160+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10161+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10162+ * GNU General Public License for more details.
10163+ *
10164+ * You should have received a copy of the GNU General Public License
523b37e3 10165+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10166+ */
10167+
10168+/*
10169+ * directory operations
10170+ */
10171+
10172+#include <linux/fs_stack.h>
eca801bf 10173+#include <linux/iversion.h>
1facf9fc 10174+#include "aufs.h"
10175+
10176+void au_add_nlink(struct inode *dir, struct inode *h_dir)
10177+{
9dbd164d
AM
10178+ unsigned int nlink;
10179+
1facf9fc 10180+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
10181+
9dbd164d
AM
10182+ nlink = dir->i_nlink;
10183+ nlink += h_dir->i_nlink - 2;
1facf9fc 10184+ if (h_dir->i_nlink < 2)
9dbd164d 10185+ nlink += 2;
f6b6e03d 10186+ smp_mb(); /* for i_nlink */
7eafdf33 10187+ /* 0 can happen in revaliding */
92d182d2 10188+ set_nlink(dir, nlink);
1facf9fc 10189+}
10190+
10191+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
10192+{
9dbd164d
AM
10193+ unsigned int nlink;
10194+
1facf9fc 10195+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
10196+
9dbd164d
AM
10197+ nlink = dir->i_nlink;
10198+ nlink -= h_dir->i_nlink - 2;
1facf9fc 10199+ if (h_dir->i_nlink < 2)
9dbd164d 10200+ nlink -= 2;
f6b6e03d 10201+ smp_mb(); /* for i_nlink */
92d182d2 10202+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 10203+ set_nlink(dir, nlink);
1facf9fc 10204+}
10205+
1308ab2a 10206+loff_t au_dir_size(struct file *file, struct dentry *dentry)
10207+{
10208+ loff_t sz;
5afbbe0d 10209+ aufs_bindex_t bindex, bbot;
1308ab2a 10210+ struct file *h_file;
10211+ struct dentry *h_dentry;
10212+
10213+ sz = 0;
10214+ if (file) {
2000de60 10215+ AuDebugOn(!d_is_dir(file->f_path.dentry));
1308ab2a 10216+
5afbbe0d
AM
10217+ bbot = au_fbbot_dir(file);
10218+ for (bindex = au_fbtop(file);
10219+ bindex <= bbot && sz < KMALLOC_MAX_SIZE;
1308ab2a 10220+ bindex++) {
4a4d8108 10221+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
10222+ if (h_file && file_inode(h_file))
10223+ sz += vfsub_f_size_read(h_file);
1308ab2a 10224+ }
10225+ } else {
10226+ AuDebugOn(!dentry);
2000de60 10227+ AuDebugOn(!d_is_dir(dentry));
1308ab2a 10228+
5afbbe0d
AM
10229+ bbot = au_dbtaildir(dentry);
10230+ for (bindex = au_dbtop(dentry);
10231+ bindex <= bbot && sz < KMALLOC_MAX_SIZE;
1308ab2a 10232+ bindex++) {
10233+ h_dentry = au_h_dptr(dentry, bindex);
5527c038
JR
10234+ if (h_dentry && d_is_positive(h_dentry))
10235+ sz += i_size_read(d_inode(h_dentry));
1308ab2a 10236+ }
10237+ }
10238+ if (sz < KMALLOC_MAX_SIZE)
10239+ sz = roundup_pow_of_two(sz);
10240+ if (sz > KMALLOC_MAX_SIZE)
10241+ sz = KMALLOC_MAX_SIZE;
10242+ else if (sz < NAME_MAX) {
10243+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
10244+ sz = AUFS_RDBLK_DEF;
10245+ }
10246+ return sz;
10247+}
10248+
b912730e
AM
10249+struct au_dir_ts_arg {
10250+ struct dentry *dentry;
10251+ aufs_bindex_t brid;
10252+};
10253+
10254+static void au_do_dir_ts(void *arg)
10255+{
10256+ struct au_dir_ts_arg *a = arg;
10257+ struct au_dtime dt;
10258+ struct path h_path;
10259+ struct inode *dir, *h_dir;
10260+ struct super_block *sb;
10261+ struct au_branch *br;
10262+ struct au_hinode *hdir;
10263+ int err;
5afbbe0d 10264+ aufs_bindex_t btop, bindex;
b912730e
AM
10265+
10266+ sb = a->dentry->d_sb;
5527c038 10267+ if (d_really_is_negative(a->dentry))
b912730e 10268+ goto out;
5527c038 10269+ /* no dir->i_mutex lock */
b95c5147
AM
10270+ aufs_read_lock(a->dentry, AuLock_DW); /* noflush */
10271+
5527c038 10272+ dir = d_inode(a->dentry);
5afbbe0d 10273+ btop = au_ibtop(dir);
b912730e 10274+ bindex = au_br_index(sb, a->brid);
5afbbe0d 10275+ if (bindex < btop)
b912730e
AM
10276+ goto out_unlock;
10277+
10278+ br = au_sbr(sb, bindex);
10279+ h_path.dentry = au_h_dptr(a->dentry, bindex);
10280+ if (!h_path.dentry)
10281+ goto out_unlock;
10282+ h_path.mnt = au_br_mnt(br);
10283+ au_dtime_store(&dt, a->dentry, &h_path);
10284+
5afbbe0d 10285+ br = au_sbr(sb, btop);
b912730e
AM
10286+ if (!au_br_writable(br->br_perm))
10287+ goto out_unlock;
5afbbe0d 10288+ h_path.dentry = au_h_dptr(a->dentry, btop);
b912730e
AM
10289+ h_path.mnt = au_br_mnt(br);
10290+ err = vfsub_mnt_want_write(h_path.mnt);
10291+ if (err)
10292+ goto out_unlock;
5afbbe0d
AM
10293+ hdir = au_hi(dir, btop);
10294+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
10295+ h_dir = au_h_iptr(dir, btop);
b912730e 10296+ if (h_dir->i_nlink
cd7a4cd9 10297+ && timespec64_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) {
b912730e
AM
10298+ dt.dt_h_path = h_path;
10299+ au_dtime_revert(&dt);
10300+ }
5afbbe0d 10301+ au_hn_inode_unlock(hdir);
b912730e
AM
10302+ vfsub_mnt_drop_write(h_path.mnt);
10303+ au_cpup_attr_timesizes(dir);
10304+
10305+out_unlock:
10306+ aufs_read_unlock(a->dentry, AuLock_DW);
10307+out:
10308+ dput(a->dentry);
10309+ au_nwt_done(&au_sbi(sb)->si_nowait);
9f237c51 10310+ au_kfree_try_rcu(arg);
b912730e
AM
10311+}
10312+
10313+void au_dir_ts(struct inode *dir, aufs_bindex_t bindex)
10314+{
10315+ int perm, wkq_err;
5afbbe0d 10316+ aufs_bindex_t btop;
b912730e
AM
10317+ struct au_dir_ts_arg *arg;
10318+ struct dentry *dentry;
10319+ struct super_block *sb;
10320+
10321+ IMustLock(dir);
10322+
10323+ dentry = d_find_any_alias(dir);
10324+ AuDebugOn(!dentry);
10325+ sb = dentry->d_sb;
5afbbe0d
AM
10326+ btop = au_ibtop(dir);
10327+ if (btop == bindex) {
b912730e
AM
10328+ au_cpup_attr_timesizes(dir);
10329+ goto out;
10330+ }
10331+
5afbbe0d 10332+ perm = au_sbr_perm(sb, btop);
b912730e
AM
10333+ if (!au_br_writable(perm))
10334+ goto out;
10335+
10336+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
10337+ if (!arg)
10338+ goto out;
10339+
10340+ arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */
10341+ arg->brid = au_sbr_id(sb, bindex);
10342+ wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0);
10343+ if (unlikely(wkq_err)) {
10344+ pr_err("wkq %d\n", wkq_err);
10345+ dput(dentry);
9f237c51 10346+ au_kfree_try_rcu(arg);
b912730e
AM
10347+ }
10348+
10349+out:
10350+ dput(dentry);
10351+}
10352+
1facf9fc 10353+/* ---------------------------------------------------------------------- */
10354+
10355+static int reopen_dir(struct file *file)
10356+{
10357+ int err;
10358+ unsigned int flags;
5afbbe0d 10359+ aufs_bindex_t bindex, btail, btop;
1facf9fc 10360+ struct dentry *dentry, *h_dentry;
10361+ struct file *h_file;
10362+
10363+ /* open all lower dirs */
2000de60 10364+ dentry = file->f_path.dentry;
5afbbe0d
AM
10365+ btop = au_dbtop(dentry);
10366+ for (bindex = au_fbtop(file); bindex < btop; bindex++)
1facf9fc 10367+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d 10368+ au_set_fbtop(file, btop);
1facf9fc 10369+
10370+ btail = au_dbtaildir(dentry);
5afbbe0d 10371+ for (bindex = au_fbbot_dir(file); btail < bindex; bindex--)
1facf9fc 10372+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d 10373+ au_set_fbbot_dir(file, btail);
1facf9fc 10374+
4a4d8108 10375+ flags = vfsub_file_flags(file);
5afbbe0d 10376+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 10377+ h_dentry = au_h_dptr(dentry, bindex);
10378+ if (!h_dentry)
10379+ continue;
4a4d8108 10380+ h_file = au_hf_dir(file, bindex);
1facf9fc 10381+ if (h_file)
10382+ continue;
10383+
392086de 10384+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 10385+ err = PTR_ERR(h_file);
10386+ if (IS_ERR(h_file))
10387+ goto out; /* close all? */
10388+ au_set_h_fptr(file, bindex, h_file);
10389+ }
10390+ au_update_figen(file);
10391+ /* todo: necessary? */
10392+ /* file->f_ra = h_file->f_ra; */
10393+ err = 0;
10394+
4f0767ce 10395+out:
1facf9fc 10396+ return err;
10397+}
10398+
b912730e 10399+static int do_open_dir(struct file *file, int flags, struct file *h_file)
1facf9fc 10400+{
10401+ int err;
10402+ aufs_bindex_t bindex, btail;
10403+ struct dentry *dentry, *h_dentry;
8cdd5066 10404+ struct vfsmount *mnt;
1facf9fc 10405+
1308ab2a 10406+ FiMustWriteLock(file);
b912730e 10407+ AuDebugOn(h_file);
1308ab2a 10408+
523b37e3 10409+ err = 0;
8cdd5066 10410+ mnt = file->f_path.mnt;
2000de60 10411+ dentry = file->f_path.dentry;
be118d29 10412+ file->f_version = inode_query_iversion(d_inode(dentry));
5afbbe0d
AM
10413+ bindex = au_dbtop(dentry);
10414+ au_set_fbtop(file, bindex);
1facf9fc 10415+ btail = au_dbtaildir(dentry);
5afbbe0d 10416+ au_set_fbbot_dir(file, btail);
1facf9fc 10417+ for (; !err && bindex <= btail; bindex++) {
10418+ h_dentry = au_h_dptr(dentry, bindex);
10419+ if (!h_dentry)
10420+ continue;
10421+
8cdd5066
JR
10422+ err = vfsub_test_mntns(mnt, h_dentry->d_sb);
10423+ if (unlikely(err))
10424+ break;
392086de 10425+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 10426+ if (IS_ERR(h_file)) {
10427+ err = PTR_ERR(h_file);
10428+ break;
10429+ }
10430+ au_set_h_fptr(file, bindex, h_file);
10431+ }
10432+ au_update_figen(file);
10433+ /* todo: necessary? */
10434+ /* file->f_ra = h_file->f_ra; */
10435+ if (!err)
10436+ return 0; /* success */
10437+
10438+ /* close all */
5afbbe0d 10439+ for (bindex = au_fbtop(file); bindex <= btail; bindex++)
1facf9fc 10440+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d
AM
10441+ au_set_fbtop(file, -1);
10442+ au_set_fbbot_dir(file, -1);
4a4d8108 10443+
1facf9fc 10444+ return err;
10445+}
10446+
10447+static int aufs_open_dir(struct inode *inode __maybe_unused,
10448+ struct file *file)
10449+{
4a4d8108
AM
10450+ int err;
10451+ struct super_block *sb;
10452+ struct au_fidir *fidir;
10453+
10454+ err = -ENOMEM;
2000de60 10455+ sb = file->f_path.dentry->d_sb;
4a4d8108 10456+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 10457+ fidir = au_fidir_alloc(sb);
4a4d8108 10458+ if (fidir) {
b912730e
AM
10459+ struct au_do_open_args args = {
10460+ .open = do_open_dir,
10461+ .fidir = fidir
10462+ };
10463+ err = au_do_open(file, &args);
4a4d8108 10464+ if (unlikely(err))
9f237c51 10465+ au_kfree_rcu(fidir);
4a4d8108
AM
10466+ }
10467+ si_read_unlock(sb);
10468+ return err;
1facf9fc 10469+}
10470+
10471+static int aufs_release_dir(struct inode *inode __maybe_unused,
10472+ struct file *file)
10473+{
10474+ struct au_vdir *vdir_cache;
4a4d8108
AM
10475+ struct au_finfo *finfo;
10476+ struct au_fidir *fidir;
f0c0a007 10477+ struct au_hfile *hf;
5afbbe0d 10478+ aufs_bindex_t bindex, bbot;
1facf9fc 10479+
4a4d8108
AM
10480+ finfo = au_fi(file);
10481+ fidir = finfo->fi_hdir;
10482+ if (fidir) {
8b6a4947
AM
10483+ au_hbl_del(&finfo->fi_hlist,
10484+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108
AM
10485+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
10486+ if (vdir_cache)
1c60b727 10487+ au_vdir_free(vdir_cache);
4a4d8108
AM
10488+
10489+ bindex = finfo->fi_btop;
10490+ if (bindex >= 0) {
f0c0a007 10491+ hf = fidir->fd_hfile + bindex;
4a4d8108
AM
10492+ /*
10493+ * calls fput() instead of filp_close(),
10494+ * since no dnotify or lock for the lower file.
10495+ */
5afbbe0d 10496+ bbot = fidir->fd_bbot;
f0c0a007
AM
10497+ for (; bindex <= bbot; bindex++, hf++)
10498+ if (hf->hf_file)
1c60b727 10499+ au_hfput(hf, /*execed*/0);
4a4d8108 10500+ }
9f237c51 10501+ au_kfree_rcu(fidir);
4a4d8108 10502+ finfo->fi_hdir = NULL;
1facf9fc 10503+ }
1c60b727 10504+ au_finfo_fin(file);
1facf9fc 10505+ return 0;
10506+}
10507+
10508+/* ---------------------------------------------------------------------- */
10509+
4a4d8108
AM
10510+static int au_do_flush_dir(struct file *file, fl_owner_t id)
10511+{
10512+ int err;
5afbbe0d 10513+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
10514+ struct file *h_file;
10515+
10516+ err = 0;
5afbbe0d
AM
10517+ bbot = au_fbbot_dir(file);
10518+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) {
4a4d8108
AM
10519+ h_file = au_hf_dir(file, bindex);
10520+ if (h_file)
10521+ err = vfsub_flush(h_file, id);
10522+ }
10523+ return err;
10524+}
10525+
10526+static int aufs_flush_dir(struct file *file, fl_owner_t id)
10527+{
10528+ return au_do_flush(file, id, au_do_flush_dir);
10529+}
10530+
10531+/* ---------------------------------------------------------------------- */
10532+
1facf9fc 10533+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
10534+{
10535+ int err;
5afbbe0d 10536+ aufs_bindex_t bbot, bindex;
1facf9fc 10537+ struct inode *inode;
10538+ struct super_block *sb;
10539+
10540+ err = 0;
10541+ sb = dentry->d_sb;
5527c038 10542+ inode = d_inode(dentry);
1facf9fc 10543+ IMustLock(inode);
5afbbe0d
AM
10544+ bbot = au_dbbot(dentry);
10545+ for (bindex = au_dbtop(dentry); !err && bindex <= bbot; bindex++) {
1facf9fc 10546+ struct path h_path;
1facf9fc 10547+
10548+ if (au_test_ro(sb, bindex, inode))
10549+ continue;
10550+ h_path.dentry = au_h_dptr(dentry, bindex);
10551+ if (!h_path.dentry)
10552+ continue;
1facf9fc 10553+
1facf9fc 10554+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 10555+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 10556+ }
10557+
10558+ return err;
10559+}
10560+
10561+static int au_do_fsync_dir(struct file *file, int datasync)
10562+{
10563+ int err;
5afbbe0d 10564+ aufs_bindex_t bbot, bindex;
1facf9fc 10565+ struct file *h_file;
10566+ struct super_block *sb;
10567+ struct inode *inode;
1facf9fc 10568+
521ced18 10569+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0);
1facf9fc 10570+ if (unlikely(err))
10571+ goto out;
10572+
c06a8ce3 10573+ inode = file_inode(file);
b912730e 10574+ sb = inode->i_sb;
5afbbe0d
AM
10575+ bbot = au_fbbot_dir(file);
10576+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) {
4a4d8108 10577+ h_file = au_hf_dir(file, bindex);
1facf9fc 10578+ if (!h_file || au_test_ro(sb, bindex, inode))
10579+ continue;
10580+
53392da6 10581+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 10582+ }
10583+
4f0767ce 10584+out:
1facf9fc 10585+ return err;
10586+}
10587+
10588+/*
10589+ * @file may be NULL
10590+ */
1e00d052
AM
10591+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
10592+ int datasync)
1facf9fc 10593+{
10594+ int err;
b752ccd1 10595+ struct dentry *dentry;
5527c038 10596+ struct inode *inode;
1facf9fc 10597+ struct super_block *sb;
1facf9fc 10598+
10599+ err = 0;
2000de60 10600+ dentry = file->f_path.dentry;
5527c038 10601+ inode = d_inode(dentry);
febd17d6 10602+ inode_lock(inode);
1facf9fc 10603+ sb = dentry->d_sb;
10604+ si_noflush_read_lock(sb);
10605+ if (file)
10606+ err = au_do_fsync_dir(file, datasync);
10607+ else {
10608+ di_write_lock_child(dentry);
10609+ err = au_do_fsync_dir_no_file(dentry, datasync);
10610+ }
5527c038 10611+ au_cpup_attr_timesizes(inode);
1facf9fc 10612+ di_write_unlock(dentry);
10613+ if (file)
10614+ fi_write_unlock(file);
10615+
10616+ si_read_unlock(sb);
febd17d6 10617+ inode_unlock(inode);
1facf9fc 10618+ return err;
10619+}
10620+
10621+/* ---------------------------------------------------------------------- */
10622+
5afbbe0d 10623+static int aufs_iterate_shared(struct file *file, struct dir_context *ctx)
1facf9fc 10624+{
10625+ int err;
10626+ struct dentry *dentry;
9dbd164d 10627+ struct inode *inode, *h_inode;
1facf9fc 10628+ struct super_block *sb;
10629+
062440b3 10630+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos);
392086de 10631+
2000de60 10632+ dentry = file->f_path.dentry;
5527c038 10633+ inode = d_inode(dentry);
1facf9fc 10634+ IMustLock(inode);
10635+
10636+ sb = dentry->d_sb;
10637+ si_read_lock(sb, AuLock_FLUSH);
521ced18 10638+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0);
1facf9fc 10639+ if (unlikely(err))
10640+ goto out;
027c5e7a
AM
10641+ err = au_alive_dir(dentry);
10642+ if (!err)
10643+ err = au_vdir_init(file);
1facf9fc 10644+ di_downgrade_lock(dentry, AuLock_IR);
10645+ if (unlikely(err))
10646+ goto out_unlock;
10647+
5afbbe0d 10648+ h_inode = au_h_iptr(inode, au_ibtop(inode));
b752ccd1 10649+ if (!au_test_nfsd()) {
392086de 10650+ err = au_vdir_fill_de(file, ctx);
9dbd164d 10651+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 10652+ } else {
10653+ /*
10654+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
10655+ * encode_fh() and others.
10656+ */
9dbd164d 10657+ atomic_inc(&h_inode->i_count);
1facf9fc 10658+ di_read_unlock(dentry, AuLock_IR);
10659+ si_read_unlock(sb);
392086de 10660+ err = au_vdir_fill_de(file, ctx);
1facf9fc 10661+ fsstack_copy_attr_atime(inode, h_inode);
10662+ fi_write_unlock(file);
9dbd164d 10663+ iput(h_inode);
1facf9fc 10664+
10665+ AuTraceErr(err);
10666+ return err;
10667+ }
10668+
4f0767ce 10669+out_unlock:
1facf9fc 10670+ di_read_unlock(dentry, AuLock_IR);
10671+ fi_write_unlock(file);
4f0767ce 10672+out:
1facf9fc 10673+ si_read_unlock(sb);
10674+ return err;
10675+}
10676+
10677+/* ---------------------------------------------------------------------- */
10678+
10679+#define AuTestEmpty_WHONLY 1
dece6358
AM
10680+#define AuTestEmpty_CALLED (1 << 1)
10681+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 10682+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
10683+#define au_fset_testempty(flags, name) \
10684+ do { (flags) |= AuTestEmpty_##name; } while (0)
10685+#define au_fclr_testempty(flags, name) \
10686+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 10687+
dece6358
AM
10688+#ifndef CONFIG_AUFS_SHWH
10689+#undef AuTestEmpty_SHWH
10690+#define AuTestEmpty_SHWH 0
10691+#endif
10692+
1facf9fc 10693+struct test_empty_arg {
392086de 10694+ struct dir_context ctx;
1308ab2a 10695+ struct au_nhash *whlist;
1facf9fc 10696+ unsigned int flags;
10697+ int err;
10698+ aufs_bindex_t bindex;
10699+};
10700+
392086de
AM
10701+static int test_empty_cb(struct dir_context *ctx, const char *__name,
10702+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 10703+ unsigned int d_type)
1facf9fc 10704+{
392086de
AM
10705+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
10706+ ctx);
1facf9fc 10707+ char *name = (void *)__name;
10708+
10709+ arg->err = 0;
10710+ au_fset_testempty(arg->flags, CALLED);
10711+ /* smp_mb(); */
10712+ if (name[0] == '.'
10713+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
10714+ goto out; /* success */
10715+
10716+ if (namelen <= AUFS_WH_PFX_LEN
10717+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
10718+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 10719+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 10720+ arg->err = -ENOTEMPTY;
10721+ goto out;
10722+ }
10723+
10724+ name += AUFS_WH_PFX_LEN;
10725+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 10726+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 10727+ arg->err = au_nhash_append_wh
1308ab2a 10728+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 10729+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 10730+
4f0767ce 10731+out:
1facf9fc 10732+ /* smp_mb(); */
10733+ AuTraceErr(arg->err);
10734+ return arg->err;
10735+}
10736+
10737+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
10738+{
10739+ int err;
10740+ struct file *h_file;
acd2b654 10741+ struct au_branch *br;
1facf9fc 10742+
10743+ h_file = au_h_open(dentry, arg->bindex,
10744+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 10745+ /*file*/NULL, /*force_wr*/0);
1facf9fc 10746+ err = PTR_ERR(h_file);
10747+ if (IS_ERR(h_file))
10748+ goto out;
10749+
10750+ err = 0;
10751+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 10752+ && !file_inode(h_file)->i_nlink)
1facf9fc 10753+ goto out_put;
10754+
10755+ do {
10756+ arg->err = 0;
10757+ au_fclr_testempty(arg->flags, CALLED);
10758+ /* smp_mb(); */
392086de 10759+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 10760+ if (err >= 0)
10761+ err = arg->err;
10762+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
10763+
4f0767ce 10764+out_put:
1facf9fc 10765+ fput(h_file);
acd2b654
AM
10766+ br = au_sbr(dentry->d_sb, arg->bindex);
10767+ au_lcnt_dec(&br->br_nfiles);
4f0767ce 10768+out:
1facf9fc 10769+ return err;
10770+}
10771+
10772+struct do_test_empty_args {
10773+ int *errp;
10774+ struct dentry *dentry;
10775+ struct test_empty_arg *arg;
10776+};
10777+
10778+static void call_do_test_empty(void *args)
10779+{
10780+ struct do_test_empty_args *a = args;
10781+ *a->errp = do_test_empty(a->dentry, a->arg);
10782+}
10783+
10784+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
10785+{
10786+ int err, wkq_err;
10787+ struct dentry *h_dentry;
10788+ struct inode *h_inode;
10789+
10790+ h_dentry = au_h_dptr(dentry, arg->bindex);
5527c038 10791+ h_inode = d_inode(h_dentry);
53392da6 10792+ /* todo: i_mode changes anytime? */
be118d29 10793+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD);
1facf9fc 10794+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
3c1bdaff 10795+ inode_unlock_shared(h_inode);
1facf9fc 10796+ if (!err)
10797+ err = do_test_empty(dentry, arg);
10798+ else {
10799+ struct do_test_empty_args args = {
10800+ .errp = &err,
10801+ .dentry = dentry,
10802+ .arg = arg
10803+ };
10804+ unsigned int flags = arg->flags;
10805+
10806+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
10807+ if (unlikely(wkq_err))
10808+ err = wkq_err;
10809+ arg->flags = flags;
10810+ }
10811+
10812+ return err;
10813+}
10814+
10815+int au_test_empty_lower(struct dentry *dentry)
10816+{
10817+ int err;
1308ab2a 10818+ unsigned int rdhash;
5afbbe0d 10819+ aufs_bindex_t bindex, btop, btail;
1308ab2a 10820+ struct au_nhash whlist;
392086de
AM
10821+ struct test_empty_arg arg = {
10822+ .ctx = {
2000de60 10823+ .actor = test_empty_cb
392086de
AM
10824+ }
10825+ };
076b876e 10826+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
1facf9fc 10827+
dece6358
AM
10828+ SiMustAnyLock(dentry->d_sb);
10829+
1308ab2a 10830+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
10831+ if (!rdhash)
10832+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
10833+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 10834+ if (unlikely(err))
1facf9fc 10835+ goto out;
10836+
1facf9fc 10837+ arg.flags = 0;
1308ab2a 10838+ arg.whlist = &whlist;
5afbbe0d 10839+ btop = au_dbtop(dentry);
dece6358
AM
10840+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10841+ au_fset_testempty(arg.flags, SHWH);
076b876e
AM
10842+ test_empty = do_test_empty;
10843+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
10844+ test_empty = sio_test_empty;
5afbbe0d 10845+ arg.bindex = btop;
076b876e 10846+ err = test_empty(dentry, &arg);
1facf9fc 10847+ if (unlikely(err))
10848+ goto out_whlist;
10849+
10850+ au_fset_testempty(arg.flags, WHONLY);
10851+ btail = au_dbtaildir(dentry);
5afbbe0d 10852+ for (bindex = btop + 1; !err && bindex <= btail; bindex++) {
1facf9fc 10853+ struct dentry *h_dentry;
10854+
10855+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 10856+ if (h_dentry && d_is_positive(h_dentry)) {
1facf9fc 10857+ arg.bindex = bindex;
076b876e 10858+ err = test_empty(dentry, &arg);
1facf9fc 10859+ }
10860+ }
10861+
4f0767ce 10862+out_whlist:
1308ab2a 10863+ au_nhash_wh_free(&whlist);
4f0767ce 10864+out:
1facf9fc 10865+ return err;
10866+}
10867+
10868+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
10869+{
10870+ int err;
392086de
AM
10871+ struct test_empty_arg arg = {
10872+ .ctx = {
2000de60 10873+ .actor = test_empty_cb
392086de
AM
10874+ }
10875+ };
1facf9fc 10876+ aufs_bindex_t bindex, btail;
10877+
10878+ err = 0;
1308ab2a 10879+ arg.whlist = whlist;
1facf9fc 10880+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
10881+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10882+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 10883+ btail = au_dbtaildir(dentry);
5afbbe0d 10884+ for (bindex = au_dbtop(dentry); !err && bindex <= btail; bindex++) {
1facf9fc 10885+ struct dentry *h_dentry;
10886+
10887+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 10888+ if (h_dentry && d_is_positive(h_dentry)) {
1facf9fc 10889+ arg.bindex = bindex;
10890+ err = sio_test_empty(dentry, &arg);
10891+ }
10892+ }
10893+
10894+ return err;
10895+}
10896+
10897+/* ---------------------------------------------------------------------- */
10898+
10899+const struct file_operations aufs_dir_fop = {
4a4d8108 10900+ .owner = THIS_MODULE,
027c5e7a 10901+ .llseek = default_llseek,
1facf9fc 10902+ .read = generic_read_dir,
5afbbe0d 10903+ .iterate_shared = aufs_iterate_shared,
1facf9fc 10904+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
10905+#ifdef CONFIG_COMPAT
10906+ .compat_ioctl = aufs_compat_ioctl_dir,
10907+#endif
1facf9fc 10908+ .open = aufs_open_dir,
10909+ .release = aufs_release_dir,
4a4d8108 10910+ .flush = aufs_flush_dir,
1facf9fc 10911+ .fsync = aufs_fsync_dir
10912+};
7f207e10
AM
10913diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
10914--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 10915+++ linux/fs/aufs/dir.h 2019-03-05 12:13:00.139224339 +0100
9f237c51 10916@@ -0,0 +1,134 @@
062440b3 10917+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 10918+/*
ba1aed25 10919+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 10920+ *
10921+ * This program, aufs is free software; you can redistribute it and/or modify
10922+ * it under the terms of the GNU General Public License as published by
10923+ * the Free Software Foundation; either version 2 of the License, or
10924+ * (at your option) any later version.
dece6358
AM
10925+ *
10926+ * This program is distributed in the hope that it will be useful,
10927+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10928+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10929+ * GNU General Public License for more details.
10930+ *
10931+ * You should have received a copy of the GNU General Public License
523b37e3 10932+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10933+ */
10934+
10935+/*
10936+ * directory operations
10937+ */
10938+
10939+#ifndef __AUFS_DIR_H__
10940+#define __AUFS_DIR_H__
10941+
10942+#ifdef __KERNEL__
10943+
10944+#include <linux/fs.h>
1facf9fc 10945+
10946+/* ---------------------------------------------------------------------- */
10947+
10948+/* need to be faster and smaller */
10949+
10950+struct au_nhash {
dece6358
AM
10951+ unsigned int nh_num;
10952+ struct hlist_head *nh_head;
1facf9fc 10953+};
10954+
10955+struct au_vdir_destr {
10956+ unsigned char len;
10957+ unsigned char name[0];
10958+} __packed;
10959+
10960+struct au_vdir_dehstr {
10961+ struct hlist_node hash;
1c60b727 10962+ struct au_vdir_destr *str;
9f237c51 10963+ struct rcu_head rcu;
4a4d8108 10964+} ____cacheline_aligned_in_smp;
1facf9fc 10965+
10966+struct au_vdir_de {
10967+ ino_t de_ino;
10968+ unsigned char de_type;
10969+ /* caution: packed */
10970+ struct au_vdir_destr de_str;
10971+} __packed;
10972+
10973+struct au_vdir_wh {
10974+ struct hlist_node wh_hash;
dece6358
AM
10975+#ifdef CONFIG_AUFS_SHWH
10976+ ino_t wh_ino;
1facf9fc 10977+ aufs_bindex_t wh_bindex;
dece6358
AM
10978+ unsigned char wh_type;
10979+#else
10980+ aufs_bindex_t wh_bindex;
10981+#endif
10982+ /* caution: packed */
1facf9fc 10983+ struct au_vdir_destr wh_str;
10984+} __packed;
10985+
10986+union au_vdir_deblk_p {
10987+ unsigned char *deblk;
10988+ struct au_vdir_de *de;
10989+};
10990+
10991+struct au_vdir {
10992+ unsigned char **vd_deblk;
10993+ unsigned long vd_nblk;
1facf9fc 10994+ struct {
10995+ unsigned long ul;
10996+ union au_vdir_deblk_p p;
10997+ } vd_last;
10998+
be118d29 10999+ u64 vd_version;
dece6358 11000+ unsigned int vd_deblk_sz;
9f237c51
AM
11001+ unsigned long vd_jiffy;
11002+ struct rcu_head rcu;
4a4d8108 11003+} ____cacheline_aligned_in_smp;
1facf9fc 11004+
11005+/* ---------------------------------------------------------------------- */
11006+
11007+/* dir.c */
11008+extern const struct file_operations aufs_dir_fop;
11009+void au_add_nlink(struct inode *dir, struct inode *h_dir);
11010+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 11011+loff_t au_dir_size(struct file *file, struct dentry *dentry);
b912730e 11012+void au_dir_ts(struct inode *dir, aufs_bindex_t bsrc);
1facf9fc 11013+int au_test_empty_lower(struct dentry *dentry);
11014+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
11015+
11016+/* vdir.c */
1308ab2a 11017+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
11018+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
11019+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 11020+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
11021+ int limit);
dece6358
AM
11022+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
11023+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
11024+ unsigned int d_type, aufs_bindex_t bindex,
11025+ unsigned char shwh);
1c60b727 11026+void au_vdir_free(struct au_vdir *vdir);
1facf9fc 11027+int au_vdir_init(struct file *file);
392086de 11028+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 11029+
11030+/* ioctl.c */
11031+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
11032+
1308ab2a 11033+#ifdef CONFIG_AUFS_RDU
11034+/* rdu.c */
11035+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
11036+#ifdef CONFIG_COMPAT
11037+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
11038+ unsigned long arg);
11039+#endif
1308ab2a 11040+#else
c1595e42
JR
11041+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file,
11042+ unsigned int cmd, unsigned long arg)
b752ccd1 11043+#ifdef CONFIG_COMPAT
c1595e42
JR
11044+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file,
11045+ unsigned int cmd, unsigned long arg)
b752ccd1 11046+#endif
1308ab2a 11047+#endif
11048+
1facf9fc 11049+#endif /* __KERNEL__ */
11050+#endif /* __AUFS_DIR_H__ */
8b6a4947
AM
11051diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c
11052--- /usr/share/empty/fs/aufs/dirren.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 11053+++ linux/fs/aufs/dirren.c 2019-03-05 12:13:00.139224339 +0100
062440b3 11054@@ -0,0 +1,1316 @@
cd7a4cd9 11055+// SPDX-License-Identifier: GPL-2.0
8b6a4947 11056+/*
ba1aed25 11057+ * Copyright (C) 2017-2019 Junjiro R. Okajima
8b6a4947
AM
11058+ *
11059+ * This program, aufs is free software; you can redistribute it and/or modify
11060+ * it under the terms of the GNU General Public License as published by
11061+ * the Free Software Foundation; either version 2 of the License, or
11062+ * (at your option) any later version.
11063+ *
11064+ * This program is distributed in the hope that it will be useful,
11065+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11066+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11067+ * GNU General Public License for more details.
11068+ *
11069+ * You should have received a copy of the GNU General Public License
11070+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
11071+ */
11072+
11073+/*
acd2b654 11074+ * special handling in renaming a directory
8b6a4947
AM
11075+ * in order to support looking-up the before-renamed name on the lower readonly
11076+ * branches
11077+ */
11078+
11079+#include <linux/byteorder/generic.h>
11080+#include "aufs.h"
11081+
11082+static void au_dr_hino_del(struct au_dr_br *dr, struct au_dr_hino *ent)
11083+{
11084+ int idx;
11085+
11086+ idx = au_dr_ihash(ent->dr_h_ino);
11087+ au_hbl_del(&ent->dr_hnode, dr->dr_h_ino + idx);
11088+}
11089+
11090+static int au_dr_hino_test_empty(struct au_dr_br *dr)
11091+{
11092+ int ret, i;
11093+ struct hlist_bl_head *hbl;
11094+
11095+ ret = 1;
11096+ for (i = 0; ret && i < AuDirren_NHASH; i++) {
11097+ hbl = dr->dr_h_ino + i;
11098+ hlist_bl_lock(hbl);
11099+ ret &= hlist_bl_empty(hbl);
11100+ hlist_bl_unlock(hbl);
11101+ }
11102+
11103+ return ret;
11104+}
11105+
11106+static struct au_dr_hino *au_dr_hino_find(struct au_dr_br *dr, ino_t ino)
11107+{
11108+ struct au_dr_hino *found, *ent;
11109+ struct hlist_bl_head *hbl;
11110+ struct hlist_bl_node *pos;
11111+ int idx;
11112+
11113+ found = NULL;
11114+ idx = au_dr_ihash(ino);
11115+ hbl = dr->dr_h_ino + idx;
11116+ hlist_bl_lock(hbl);
11117+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode)
11118+ if (ent->dr_h_ino == ino) {
11119+ found = ent;
11120+ break;
11121+ }
11122+ hlist_bl_unlock(hbl);
11123+
11124+ return found;
11125+}
11126+
11127+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t ino,
11128+ struct au_dr_hino *add_ent)
11129+{
11130+ int found, idx;
11131+ struct hlist_bl_head *hbl;
11132+ struct hlist_bl_node *pos;
11133+ struct au_dr_hino *ent;
11134+
11135+ found = 0;
11136+ idx = au_dr_ihash(ino);
11137+ hbl = dr->dr_h_ino + idx;
11138+#if 0
11139+ {
11140+ struct hlist_bl_node *tmp;
11141+
11142+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode)
11143+ AuDbg("hi%llu\n", (unsigned long long)ent->dr_h_ino);
11144+ }
11145+#endif
11146+ hlist_bl_lock(hbl);
11147+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode)
11148+ if (ent->dr_h_ino == ino) {
11149+ found = 1;
11150+ break;
11151+ }
11152+ if (!found && add_ent)
11153+ hlist_bl_add_head(&add_ent->dr_hnode, hbl);
11154+ hlist_bl_unlock(hbl);
11155+
11156+ if (!found && add_ent)
11157+ AuDbg("i%llu added\n", (unsigned long long)add_ent->dr_h_ino);
11158+
11159+ return found;
11160+}
11161+
11162+void au_dr_hino_free(struct au_dr_br *dr)
11163+{
11164+ int i;
11165+ struct hlist_bl_head *hbl;
11166+ struct hlist_bl_node *pos, *tmp;
11167+ struct au_dr_hino *ent;
11168+
11169+ /* SiMustWriteLock(sb); */
11170+
11171+ for (i = 0; i < AuDirren_NHASH; i++) {
11172+ hbl = dr->dr_h_ino + i;
11173+ /* no spinlock since sbinfo must be write-locked */
11174+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode)
9f237c51 11175+ au_kfree_rcu(ent);
8b6a4947
AM
11176+ INIT_HLIST_BL_HEAD(hbl);
11177+ }
11178+}
11179+
11180+/* returns the number of inodes or an error */
11181+static int au_dr_hino_store(struct super_block *sb, struct au_branch *br,
11182+ struct file *hinofile)
11183+{
11184+ int err, i;
11185+ ssize_t ssz;
11186+ loff_t pos, oldsize;
11187+ __be64 u64;
11188+ struct inode *hinoinode;
11189+ struct hlist_bl_head *hbl;
11190+ struct hlist_bl_node *n1, *n2;
11191+ struct au_dr_hino *ent;
11192+
11193+ SiMustWriteLock(sb);
11194+ AuDebugOn(!au_br_writable(br->br_perm));
11195+
11196+ hinoinode = file_inode(hinofile);
11197+ oldsize = i_size_read(hinoinode);
11198+
11199+ err = 0;
11200+ pos = 0;
11201+ hbl = br->br_dirren.dr_h_ino;
11202+ for (i = 0; !err && i < AuDirren_NHASH; i++, hbl++) {
11203+ /* no bit-lock since sbinfo must be write-locked */
11204+ hlist_bl_for_each_entry_safe(ent, n1, n2, hbl, dr_hnode) {
11205+ AuDbg("hi%llu, %pD2\n",
11206+ (unsigned long long)ent->dr_h_ino, hinofile);
11207+ u64 = cpu_to_be64(ent->dr_h_ino);
11208+ ssz = vfsub_write_k(hinofile, &u64, sizeof(u64), &pos);
11209+ if (ssz == sizeof(u64))
11210+ continue;
11211+
11212+ /* write error */
11213+ pr_err("ssz %zd, %pD2\n", ssz, hinofile);
11214+ err = -ENOSPC;
11215+ if (ssz < 0)
11216+ err = ssz;
11217+ break;
11218+ }
11219+ }
11220+ /* regardless the error */
11221+ if (pos < oldsize) {
11222+ err = vfsub_trunc(&hinofile->f_path, pos, /*attr*/0, hinofile);
11223+ AuTraceErr(err);
11224+ }
11225+
11226+ AuTraceErr(err);
11227+ return err;
11228+}
11229+
11230+static int au_dr_hino_load(struct au_dr_br *dr, struct file *hinofile)
11231+{
11232+ int err, hidx;
11233+ ssize_t ssz;
11234+ size_t sz, n;
11235+ loff_t pos;
11236+ uint64_t u64;
11237+ struct au_dr_hino *ent;
11238+ struct inode *hinoinode;
11239+ struct hlist_bl_head *hbl;
11240+
11241+ err = 0;
11242+ pos = 0;
11243+ hbl = dr->dr_h_ino;
11244+ hinoinode = file_inode(hinofile);
11245+ sz = i_size_read(hinoinode);
11246+ AuDebugOn(sz % sizeof(u64));
11247+ n = sz / sizeof(u64);
11248+ while (n--) {
11249+ ssz = vfsub_read_k(hinofile, &u64, sizeof(u64), &pos);
11250+ if (unlikely(ssz != sizeof(u64))) {
11251+ pr_err("ssz %zd, %pD2\n", ssz, hinofile);
11252+ err = -EINVAL;
11253+ if (ssz < 0)
11254+ err = ssz;
11255+ goto out_free;
11256+ }
11257+
11258+ ent = kmalloc(sizeof(*ent), GFP_NOFS);
11259+ if (!ent) {
11260+ err = -ENOMEM;
11261+ AuTraceErr(err);
11262+ goto out_free;
11263+ }
11264+ ent->dr_h_ino = be64_to_cpu((__force __be64)u64);
11265+ AuDbg("hi%llu, %pD2\n",
11266+ (unsigned long long)ent->dr_h_ino, hinofile);
11267+ hidx = au_dr_ihash(ent->dr_h_ino);
11268+ au_hbl_add(&ent->dr_hnode, hbl + hidx);
11269+ }
11270+ goto out; /* success */
11271+
11272+out_free:
11273+ au_dr_hino_free(dr);
11274+out:
11275+ AuTraceErr(err);
11276+ return err;
11277+}
11278+
11279+/*
11280+ * @bindex/@br is a switch to distinguish whether suspending hnotify or not.
11281+ * @path is a switch to distinguish load and store.
11282+ */
11283+static int au_dr_hino(struct super_block *sb, aufs_bindex_t bindex,
11284+ struct au_branch *br, const struct path *path)
11285+{
11286+ int err, flags;
11287+ unsigned char load, suspend;
11288+ struct file *hinofile;
11289+ struct au_hinode *hdir;
11290+ struct inode *dir, *delegated;
11291+ struct path hinopath;
11292+ struct qstr hinoname = QSTR_INIT(AUFS_WH_DR_BRHINO,
11293+ sizeof(AUFS_WH_DR_BRHINO) - 1);
11294+
11295+ AuDebugOn(bindex < 0 && !br);
11296+ AuDebugOn(bindex >= 0 && br);
11297+
11298+ err = -EINVAL;
11299+ suspend = !br;
11300+ if (suspend)
11301+ br = au_sbr(sb, bindex);
11302+ load = !!path;
11303+ if (!load) {
11304+ path = &br->br_path;
11305+ AuDebugOn(!au_br_writable(br->br_perm));
11306+ if (unlikely(!au_br_writable(br->br_perm)))
11307+ goto out;
11308+ }
11309+
11310+ hdir = NULL;
11311+ if (suspend) {
11312+ dir = d_inode(sb->s_root);
11313+ hdir = au_hinode(au_ii(dir), bindex);
11314+ dir = hdir->hi_inode;
11315+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD);
11316+ } else {
11317+ dir = d_inode(path->dentry);
11318+ inode_lock_nested(dir, AuLsc_I_CHILD);
11319+ }
11320+ hinopath.dentry = vfsub_lkup_one(&hinoname, path->dentry);
11321+ err = PTR_ERR(hinopath.dentry);
11322+ if (IS_ERR(hinopath.dentry))
11323+ goto out_unlock;
11324+
11325+ err = 0;
11326+ flags = O_RDONLY;
11327+ if (load) {
11328+ if (d_is_negative(hinopath.dentry))
11329+ goto out_dput; /* success */
11330+ } else {
11331+ if (au_dr_hino_test_empty(&br->br_dirren)) {
11332+ if (d_is_positive(hinopath.dentry)) {
11333+ delegated = NULL;
11334+ err = vfsub_unlink(dir, &hinopath, &delegated,
11335+ /*force*/0);
11336+ AuTraceErr(err);
11337+ if (unlikely(err))
11338+ pr_err("ignored err %d, %pd2\n",
11339+ err, hinopath.dentry);
11340+ if (unlikely(err == -EWOULDBLOCK))
11341+ iput(delegated);
11342+ err = 0;
11343+ }
11344+ goto out_dput;
11345+ } else if (!d_is_positive(hinopath.dentry)) {
11346+ err = vfsub_create(dir, &hinopath, 0600,
11347+ /*want_excl*/false);
11348+ AuTraceErr(err);
11349+ if (unlikely(err))
11350+ goto out_dput;
11351+ }
11352+ flags = O_WRONLY;
11353+ }
11354+ hinopath.mnt = path->mnt;
11355+ hinofile = vfsub_dentry_open(&hinopath, flags);
11356+ if (suspend)
11357+ au_hn_inode_unlock(hdir);
11358+ else
11359+ inode_unlock(dir);
11360+ dput(hinopath.dentry);
11361+ AuTraceErrPtr(hinofile);
11362+ if (IS_ERR(hinofile)) {
11363+ err = PTR_ERR(hinofile);
11364+ goto out;
11365+ }
11366+
11367+ if (load)
11368+ err = au_dr_hino_load(&br->br_dirren, hinofile);
11369+ else
11370+ err = au_dr_hino_store(sb, br, hinofile);
11371+ fput(hinofile);
11372+ goto out;
11373+
11374+out_dput:
11375+ dput(hinopath.dentry);
11376+out_unlock:
11377+ if (suspend)
11378+ au_hn_inode_unlock(hdir);
11379+ else
11380+ inode_unlock(dir);
11381+out:
11382+ AuTraceErr(err);
11383+ return err;
11384+}
11385+
11386+/* ---------------------------------------------------------------------- */
11387+
11388+static int au_dr_brid_init(struct au_dr_brid *brid, const struct path *path)
11389+{
11390+ int err;
11391+ struct kstatfs kstfs;
11392+ dev_t dev;
11393+ struct dentry *dentry;
11394+ struct super_block *sb;
11395+
11396+ err = vfs_statfs((void *)path, &kstfs);
11397+ AuTraceErr(err);
11398+ if (unlikely(err))
11399+ goto out;
11400+
11401+ /* todo: support for UUID */
11402+
11403+ if (kstfs.f_fsid.val[0] || kstfs.f_fsid.val[1]) {
11404+ brid->type = AuBrid_FSID;
11405+ brid->fsid = kstfs.f_fsid;
11406+ } else {
11407+ dentry = path->dentry;
11408+ sb = dentry->d_sb;
11409+ dev = sb->s_dev;
11410+ if (dev) {
11411+ brid->type = AuBrid_DEV;
11412+ brid->dev = dev;
11413+ }
11414+ }
11415+
11416+out:
11417+ return err;
11418+}
11419+
11420+int au_dr_br_init(struct super_block *sb, struct au_branch *br,
11421+ const struct path *path)
11422+{
11423+ int err, i;
11424+ struct au_dr_br *dr;
11425+ struct hlist_bl_head *hbl;
11426+
11427+ dr = &br->br_dirren;
11428+ hbl = dr->dr_h_ino;
11429+ for (i = 0; i < AuDirren_NHASH; i++, hbl++)
11430+ INIT_HLIST_BL_HEAD(hbl);
11431+
11432+ err = au_dr_brid_init(&dr->dr_brid, path);
11433+ if (unlikely(err))
11434+ goto out;
11435+
11436+ if (au_opt_test(au_mntflags(sb), DIRREN))
11437+ err = au_dr_hino(sb, /*bindex*/-1, br, path);
11438+
11439+out:
11440+ AuTraceErr(err);
11441+ return err;
11442+}
11443+
11444+int au_dr_br_fin(struct super_block *sb, struct au_branch *br)
11445+{
11446+ int err;
11447+
11448+ err = 0;
11449+ if (au_br_writable(br->br_perm))
11450+ err = au_dr_hino(sb, /*bindex*/-1, br, /*path*/NULL);
11451+ if (!err)
11452+ au_dr_hino_free(&br->br_dirren);
11453+
11454+ return err;
11455+}
11456+
11457+/* ---------------------------------------------------------------------- */
11458+
11459+static int au_brid_str(struct au_dr_brid *brid, struct inode *h_inode,
11460+ char *buf, size_t sz)
11461+{
11462+ int err;
11463+ unsigned int major, minor;
11464+ char *p;
11465+
11466+ p = buf;
11467+ err = snprintf(p, sz, "%d_", brid->type);
11468+ AuDebugOn(err > sz);
11469+ p += err;
11470+ sz -= err;
11471+ switch (brid->type) {
11472+ case AuBrid_Unset:
11473+ return -EINVAL;
11474+ case AuBrid_UUID:
11475+ err = snprintf(p, sz, "%pU", brid->uuid.b);
11476+ break;
11477+ case AuBrid_FSID:
11478+ err = snprintf(p, sz, "%08x-%08x",
11479+ brid->fsid.val[0], brid->fsid.val[1]);
11480+ break;
11481+ case AuBrid_DEV:
11482+ major = MAJOR(brid->dev);
11483+ minor = MINOR(brid->dev);
11484+ if (major <= 0xff && minor <= 0xff)
11485+ err = snprintf(p, sz, "%02x%02x", major, minor);
11486+ else
11487+ err = snprintf(p, sz, "%03x:%05x", major, minor);
11488+ break;
11489+ }
11490+ AuDebugOn(err > sz);
11491+ p += err;
11492+ sz -= err;
11493+ err = snprintf(p, sz, "_%llu", (unsigned long long)h_inode->i_ino);
11494+ AuDebugOn(err > sz);
11495+ p += err;
11496+ sz -= err;
11497+
11498+ return p - buf;
11499+}
11500+
11501+static int au_drinfo_name(struct au_branch *br, char *name, int len)
11502+{
11503+ int rlen;
11504+ struct dentry *br_dentry;
11505+ struct inode *br_inode;
11506+
11507+ br_dentry = au_br_dentry(br);
11508+ br_inode = d_inode(br_dentry);
11509+ rlen = au_brid_str(&br->br_dirren.dr_brid, br_inode, name, len);
11510+ AuDebugOn(rlen >= AUFS_DIRREN_ENV_VAL_SZ);
11511+ AuDebugOn(rlen > len);
11512+
11513+ return rlen;
11514+}
11515+
11516+/* ---------------------------------------------------------------------- */
11517+
11518+/*
11519+ * from the given @h_dentry, construct drinfo at @*fdata.
11520+ * when the size of @*fdata is not enough, reallocate and return new @fdata and
11521+ * @allocated.
11522+ */
11523+static int au_drinfo_construct(struct au_drinfo_fdata **fdata,
11524+ struct dentry *h_dentry,
11525+ unsigned char *allocated)
11526+{
11527+ int err, v;
11528+ struct au_drinfo_fdata *f, *p;
11529+ struct au_drinfo *drinfo;
11530+ struct inode *h_inode;
11531+ struct qstr *qname;
11532+
11533+ err = 0;
11534+ f = *fdata;
11535+ h_inode = d_inode(h_dentry);
11536+ qname = &h_dentry->d_name;
11537+ drinfo = &f->drinfo;
11538+ drinfo->ino = (__force uint64_t)cpu_to_be64(h_inode->i_ino);
11539+ drinfo->oldnamelen = qname->len;
11540+ if (*allocated < sizeof(*f) + qname->len) {
11541+ v = roundup_pow_of_two(*allocated + qname->len);
11542+ p = au_krealloc(f, v, GFP_NOFS, /*may_shrink*/0);
11543+ if (unlikely(!p)) {
11544+ err = -ENOMEM;
11545+ AuTraceErr(err);
11546+ goto out;
11547+ }
11548+ f = p;
11549+ *fdata = f;
11550+ *allocated = v;
11551+ drinfo = &f->drinfo;
11552+ }
11553+ memcpy(drinfo->oldname, qname->name, qname->len);
11554+ AuDbg("i%llu, %.*s\n",
11555+ be64_to_cpu((__force __be64)drinfo->ino), drinfo->oldnamelen,
11556+ drinfo->oldname);
11557+
11558+out:
11559+ AuTraceErr(err);
11560+ return err;
11561+}
11562+
11563+/* callers have to free the return value */
11564+static struct au_drinfo *au_drinfo_read_k(struct file *file, ino_t h_ino)
11565+{
11566+ struct au_drinfo *ret, *drinfo;
11567+ struct au_drinfo_fdata fdata;
11568+ int len;
11569+ loff_t pos;
11570+ ssize_t ssz;
11571+
11572+ ret = ERR_PTR(-EIO);
11573+ pos = 0;
11574+ ssz = vfsub_read_k(file, &fdata, sizeof(fdata), &pos);
11575+ if (unlikely(ssz != sizeof(fdata))) {
11576+ AuIOErr("ssz %zd, %u, %pD2\n",
11577+ ssz, (unsigned int)sizeof(fdata), file);
11578+ goto out;
11579+ }
11580+
11581+ fdata.magic = ntohl((__force __be32)fdata.magic);
11582+ switch (fdata.magic) {
11583+ case AUFS_DRINFO_MAGIC_V1:
11584+ break;
11585+ default:
11586+ AuIOErr("magic-num 0x%x, 0x%x, %pD2\n",
11587+ fdata.magic, AUFS_DRINFO_MAGIC_V1, file);
11588+ goto out;
11589+ }
11590+
11591+ drinfo = &fdata.drinfo;
11592+ len = drinfo->oldnamelen;
11593+ if (!len) {
11594+ AuIOErr("broken drinfo %pD2\n", file);
11595+ goto out;
11596+ }
11597+
11598+ ret = NULL;
11599+ drinfo->ino = be64_to_cpu((__force __be64)drinfo->ino);
11600+ if (unlikely(h_ino && drinfo->ino != h_ino)) {
11601+ AuDbg("ignored i%llu, i%llu, %pD2\n",
11602+ (unsigned long long)drinfo->ino,
11603+ (unsigned long long)h_ino, file);
11604+ goto out; /* success */
11605+ }
11606+
11607+ ret = kmalloc(sizeof(*ret) + len, GFP_NOFS);
11608+ if (unlikely(!ret)) {
11609+ ret = ERR_PTR(-ENOMEM);
11610+ AuTraceErrPtr(ret);
11611+ goto out;
11612+ }
11613+
11614+ *ret = *drinfo;
11615+ ssz = vfsub_read_k(file, (void *)ret->oldname, len, &pos);
11616+ if (unlikely(ssz != len)) {
9f237c51 11617+ au_kfree_rcu(ret);
8b6a4947
AM
11618+ ret = ERR_PTR(-EIO);
11619+ AuIOErr("ssz %zd, %u, %pD2\n", ssz, len, file);
11620+ goto out;
11621+ }
11622+
11623+ AuDbg("oldname %.*s\n", ret->oldnamelen, ret->oldname);
11624+
11625+out:
11626+ return ret;
11627+}
11628+
11629+/* ---------------------------------------------------------------------- */
11630+
11631+/* in order to be revertible */
11632+struct au_drinfo_rev_elm {
11633+ int created;
11634+ struct dentry *info_dentry;
11635+ struct au_drinfo *info_last;
11636+};
11637+
11638+struct au_drinfo_rev {
11639+ unsigned char already;
11640+ aufs_bindex_t nelm;
11641+ struct au_drinfo_rev_elm elm[0];
11642+};
11643+
11644+/* todo: isn't it too large? */
11645+struct au_drinfo_store {
11646+ struct path h_ppath;
11647+ struct dentry *h_dentry;
11648+ struct au_drinfo_fdata *fdata;
11649+ char *infoname; /* inside of whname, just after PFX */
11650+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ];
11651+ aufs_bindex_t btgt, btail;
11652+ unsigned char no_sio,
11653+ allocated, /* current size of *fdata */
11654+ infonamelen, /* room size for p */
acd2b654 11655+ whnamelen, /* length of the generated name */
8b6a4947
AM
11656+ renameback; /* renamed back */
11657+};
11658+
11659+/* on rename(2) error, the caller should revert it using @elm */
11660+static int au_drinfo_do_store(struct au_drinfo_store *w,
11661+ struct au_drinfo_rev_elm *elm)
11662+{
11663+ int err, len;
11664+ ssize_t ssz;
11665+ loff_t pos;
11666+ struct path infopath = {
11667+ .mnt = w->h_ppath.mnt
11668+ };
11669+ struct inode *h_dir, *h_inode, *delegated;
11670+ struct file *infofile;
11671+ struct qstr *qname;
11672+
11673+ AuDebugOn(elm
11674+ && memcmp(elm, page_address(ZERO_PAGE(0)), sizeof(*elm)));
11675+
11676+ infopath.dentry = vfsub_lookup_one_len(w->whname, w->h_ppath.dentry,
11677+ w->whnamelen);
11678+ AuTraceErrPtr(infopath.dentry);
11679+ if (IS_ERR(infopath.dentry)) {
11680+ err = PTR_ERR(infopath.dentry);
11681+ goto out;
11682+ }
11683+
11684+ err = 0;
11685+ h_dir = d_inode(w->h_ppath.dentry);
11686+ if (elm && d_is_negative(infopath.dentry)) {
11687+ err = vfsub_create(h_dir, &infopath, 0600, /*want_excl*/true);
11688+ AuTraceErr(err);
11689+ if (unlikely(err))
11690+ goto out_dput;
11691+ elm->created = 1;
11692+ elm->info_dentry = dget(infopath.dentry);
11693+ }
11694+
11695+ infofile = vfsub_dentry_open(&infopath, O_RDWR);
11696+ AuTraceErrPtr(infofile);
11697+ if (IS_ERR(infofile)) {
11698+ err = PTR_ERR(infofile);
11699+ goto out_dput;
11700+ }
11701+
11702+ h_inode = d_inode(infopath.dentry);
11703+ if (elm && i_size_read(h_inode)) {
11704+ h_inode = d_inode(w->h_dentry);
11705+ elm->info_last = au_drinfo_read_k(infofile, h_inode->i_ino);
11706+ AuTraceErrPtr(elm->info_last);
11707+ if (IS_ERR(elm->info_last)) {
11708+ err = PTR_ERR(elm->info_last);
11709+ elm->info_last = NULL;
11710+ AuDebugOn(elm->info_dentry);
11711+ goto out_fput;
11712+ }
11713+ }
11714+
11715+ if (elm && w->renameback) {
11716+ delegated = NULL;
11717+ err = vfsub_unlink(h_dir, &infopath, &delegated, /*force*/0);
11718+ AuTraceErr(err);
11719+ if (unlikely(err == -EWOULDBLOCK))
11720+ iput(delegated);
11721+ goto out_fput;
11722+ }
11723+
11724+ pos = 0;
11725+ qname = &w->h_dentry->d_name;
11726+ len = sizeof(*w->fdata) + qname->len;
11727+ if (!elm)
11728+ len = sizeof(*w->fdata) + w->fdata->drinfo.oldnamelen;
11729+ ssz = vfsub_write_k(infofile, w->fdata, len, &pos);
11730+ if (ssz == len) {
11731+ AuDbg("hi%llu, %.*s\n", w->fdata->drinfo.ino,
11732+ w->fdata->drinfo.oldnamelen, w->fdata->drinfo.oldname);
11733+ goto out_fput; /* success */
11734+ } else {
11735+ err = -EIO;
11736+ if (ssz < 0)
11737+ err = ssz;
11738+ /* the caller should revert it using @elm */
11739+ }
11740+
11741+out_fput:
11742+ fput(infofile);
11743+out_dput:
11744+ dput(infopath.dentry);
11745+out:
11746+ AuTraceErr(err);
11747+ return err;
11748+}
11749+
11750+struct au_call_drinfo_do_store_args {
11751+ int *errp;
11752+ struct au_drinfo_store *w;
11753+ struct au_drinfo_rev_elm *elm;
11754+};
11755+
11756+static void au_call_drinfo_do_store(void *args)
11757+{
11758+ struct au_call_drinfo_do_store_args *a = args;
11759+
11760+ *a->errp = au_drinfo_do_store(a->w, a->elm);
11761+}
11762+
11763+static int au_drinfo_store_sio(struct au_drinfo_store *w,
11764+ struct au_drinfo_rev_elm *elm)
11765+{
11766+ int err, wkq_err;
11767+
11768+ if (w->no_sio)
11769+ err = au_drinfo_do_store(w, elm);
11770+ else {
11771+ struct au_call_drinfo_do_store_args a = {
11772+ .errp = &err,
11773+ .w = w,
11774+ .elm = elm
11775+ };
11776+ wkq_err = au_wkq_wait(au_call_drinfo_do_store, &a);
11777+ if (unlikely(wkq_err))
11778+ err = wkq_err;
11779+ }
11780+ AuTraceErr(err);
11781+
11782+ return err;
11783+}
11784+
11785+static int au_drinfo_store_work_init(struct au_drinfo_store *w,
11786+ aufs_bindex_t btgt)
11787+{
11788+ int err;
11789+
11790+ memset(w, 0, sizeof(*w));
11791+ w->allocated = roundup_pow_of_two(sizeof(*w->fdata) + 40);
11792+ strcpy(w->whname, AUFS_WH_DR_INFO_PFX);
11793+ w->infoname = w->whname + sizeof(AUFS_WH_DR_INFO_PFX) - 1;
11794+ w->infonamelen = sizeof(w->whname) - sizeof(AUFS_WH_DR_INFO_PFX);
11795+ w->btgt = btgt;
11796+ w->no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID);
11797+
11798+ err = -ENOMEM;
11799+ w->fdata = kcalloc(1, w->allocated, GFP_NOFS);
11800+ if (unlikely(!w->fdata)) {
11801+ AuTraceErr(err);
11802+ goto out;
11803+ }
11804+ w->fdata->magic = (__force uint32_t)htonl(AUFS_DRINFO_MAGIC_V1);
11805+ err = 0;
11806+
11807+out:
11808+ return err;
11809+}
11810+
11811+static void au_drinfo_store_work_fin(struct au_drinfo_store *w)
11812+{
9f237c51 11813+ au_kfree_rcu(w->fdata);
8b6a4947
AM
11814+}
11815+
11816+static void au_drinfo_store_rev(struct au_drinfo_rev *rev,
11817+ struct au_drinfo_store *w)
11818+{
11819+ struct au_drinfo_rev_elm *elm;
11820+ struct inode *h_dir, *delegated;
11821+ int err, nelm;
11822+ struct path infopath = {
11823+ .mnt = w->h_ppath.mnt
11824+ };
11825+
11826+ h_dir = d_inode(w->h_ppath.dentry);
11827+ IMustLock(h_dir);
11828+
11829+ err = 0;
11830+ elm = rev->elm;
11831+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) {
11832+ AuDebugOn(elm->created && elm->info_last);
11833+ if (elm->created) {
11834+ AuDbg("here\n");
11835+ delegated = NULL;
11836+ infopath.dentry = elm->info_dentry;
11837+ err = vfsub_unlink(h_dir, &infopath, &delegated,
11838+ !w->no_sio);
11839+ AuTraceErr(err);
11840+ if (unlikely(err == -EWOULDBLOCK))
11841+ iput(delegated);
11842+ dput(elm->info_dentry);
11843+ } else if (elm->info_last) {
11844+ AuDbg("here\n");
11845+ w->fdata->drinfo = *elm->info_last;
11846+ memcpy(w->fdata->drinfo.oldname,
11847+ elm->info_last->oldname,
11848+ elm->info_last->oldnamelen);
11849+ err = au_drinfo_store_sio(w, /*elm*/NULL);
9f237c51 11850+ au_kfree_rcu(elm->info_last);
8b6a4947
AM
11851+ }
11852+ if (unlikely(err))
11853+ AuIOErr("%d, %s\n", err, w->whname);
11854+ /* go on even if err */
11855+ }
11856+}
11857+
11858+/* caller has to call au_dr_rename_fin() later */
11859+static int au_drinfo_store(struct dentry *dentry, aufs_bindex_t btgt,
11860+ struct qstr *dst_name, void *_rev)
11861+{
11862+ int err, sz, nelm;
11863+ aufs_bindex_t bindex, btail;
11864+ struct au_drinfo_store work;
11865+ struct au_drinfo_rev *rev, **p;
11866+ struct au_drinfo_rev_elm *elm;
11867+ struct super_block *sb;
11868+ struct au_branch *br;
11869+ struct au_hinode *hdir;
11870+
11871+ err = au_drinfo_store_work_init(&work, btgt);
11872+ AuTraceErr(err);
11873+ if (unlikely(err))
11874+ goto out;
11875+
11876+ err = -ENOMEM;
11877+ btail = au_dbtaildir(dentry);
11878+ nelm = btail - btgt;
11879+ sz = sizeof(*rev) + sizeof(*elm) * nelm;
11880+ rev = kcalloc(1, sz, GFP_NOFS);
11881+ if (unlikely(!rev)) {
11882+ AuTraceErr(err);
11883+ goto out_args;
11884+ }
11885+ rev->nelm = nelm;
11886+ elm = rev->elm;
11887+ p = _rev;
11888+ *p = rev;
11889+
11890+ err = 0;
11891+ sb = dentry->d_sb;
11892+ work.h_ppath.dentry = au_h_dptr(dentry, btgt);
11893+ work.h_ppath.mnt = au_sbr_mnt(sb, btgt);
11894+ hdir = au_hi(d_inode(dentry), btgt);
11895+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD);
11896+ for (bindex = btgt + 1; bindex <= btail; bindex++, elm++) {
11897+ work.h_dentry = au_h_dptr(dentry, bindex);
11898+ if (!work.h_dentry)
11899+ continue;
11900+
11901+ err = au_drinfo_construct(&work.fdata, work.h_dentry,
11902+ &work.allocated);
11903+ AuTraceErr(err);
11904+ if (unlikely(err))
11905+ break;
11906+
11907+ work.renameback = au_qstreq(&work.h_dentry->d_name, dst_name);
11908+ br = au_sbr(sb, bindex);
11909+ work.whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1;
11910+ work.whnamelen += au_drinfo_name(br, work.infoname,
11911+ work.infonamelen);
11912+ AuDbg("whname %.*s, i%llu, %.*s\n",
11913+ work.whnamelen, work.whname,
11914+ be64_to_cpu((__force __be64)work.fdata->drinfo.ino),
11915+ work.fdata->drinfo.oldnamelen,
11916+ work.fdata->drinfo.oldname);
11917+
11918+ err = au_drinfo_store_sio(&work, elm);
11919+ AuTraceErr(err);
11920+ if (unlikely(err))
11921+ break;
11922+ }
11923+ if (unlikely(err)) {
11924+ /* revert all drinfo */
11925+ au_drinfo_store_rev(rev, &work);
9f237c51 11926+ au_kfree_try_rcu(rev);
8b6a4947
AM
11927+ *p = NULL;
11928+ }
11929+ au_hn_inode_unlock(hdir);
11930+
11931+out_args:
11932+ au_drinfo_store_work_fin(&work);
11933+out:
11934+ return err;
11935+}
11936+
11937+/* ---------------------------------------------------------------------- */
11938+
11939+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
11940+ struct qstr *dst_name, void *_rev)
11941+{
11942+ int err, already;
11943+ ino_t ino;
11944+ struct super_block *sb;
11945+ struct au_branch *br;
11946+ struct au_dr_br *dr;
11947+ struct dentry *h_dentry;
11948+ struct inode *h_inode;
11949+ struct au_dr_hino *ent;
11950+ struct au_drinfo_rev *rev, **p;
11951+
11952+ AuDbg("bindex %d\n", bindex);
11953+
11954+ err = -ENOMEM;
11955+ ent = kmalloc(sizeof(*ent), GFP_NOFS);
11956+ if (unlikely(!ent))
11957+ goto out;
11958+
11959+ sb = src->d_sb;
11960+ br = au_sbr(sb, bindex);
11961+ dr = &br->br_dirren;
11962+ h_dentry = au_h_dptr(src, bindex);
11963+ h_inode = d_inode(h_dentry);
11964+ ino = h_inode->i_ino;
11965+ ent->dr_h_ino = ino;
11966+ already = au_dr_hino_test_add(dr, ino, ent);
11967+ AuDbg("b%d, hi%llu, already %d\n",
11968+ bindex, (unsigned long long)ino, already);
11969+
11970+ err = au_drinfo_store(src, bindex, dst_name, _rev);
11971+ AuTraceErr(err);
11972+ if (!err) {
11973+ p = _rev;
11974+ rev = *p;
11975+ rev->already = already;
11976+ goto out; /* success */
11977+ }
11978+
11979+ /* revert */
11980+ if (!already)
11981+ au_dr_hino_del(dr, ent);
9f237c51 11982+ au_kfree_rcu(ent);
8b6a4947
AM
11983+
11984+out:
11985+ AuTraceErr(err);
11986+ return err;
11987+}
11988+
11989+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *_rev)
11990+{
11991+ struct au_drinfo_rev *rev;
11992+ struct au_drinfo_rev_elm *elm;
11993+ int nelm;
11994+
11995+ rev = _rev;
11996+ elm = rev->elm;
11997+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) {
11998+ dput(elm->info_dentry);
9f237c51 11999+ au_kfree_rcu(elm->info_last);
8b6a4947 12000+ }
9f237c51 12001+ au_kfree_try_rcu(rev);
8b6a4947
AM
12002+}
12003+
12004+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t btgt, void *_rev)
12005+{
12006+ int err;
12007+ struct au_drinfo_store work;
12008+ struct au_drinfo_rev *rev = _rev;
12009+ struct super_block *sb;
12010+ struct au_branch *br;
12011+ struct inode *h_inode;
12012+ struct au_dr_br *dr;
12013+ struct au_dr_hino *ent;
12014+
12015+ err = au_drinfo_store_work_init(&work, btgt);
12016+ if (unlikely(err))
12017+ goto out;
12018+
12019+ sb = src->d_sb;
12020+ br = au_sbr(sb, btgt);
12021+ work.h_ppath.dentry = au_h_dptr(src, btgt);
12022+ work.h_ppath.mnt = au_br_mnt(br);
12023+ au_drinfo_store_rev(rev, &work);
12024+ au_drinfo_store_work_fin(&work);
12025+ if (rev->already)
12026+ goto out;
12027+
12028+ dr = &br->br_dirren;
12029+ h_inode = d_inode(work.h_ppath.dentry);
12030+ ent = au_dr_hino_find(dr, h_inode->i_ino);
12031+ BUG_ON(!ent);
12032+ au_dr_hino_del(dr, ent);
9f237c51 12033+ au_kfree_rcu(ent);
8b6a4947
AM
12034+
12035+out:
9f237c51 12036+ au_kfree_try_rcu(rev);
8b6a4947
AM
12037+ if (unlikely(err))
12038+ pr_err("failed to remove dirren info\n");
12039+}
12040+
12041+/* ---------------------------------------------------------------------- */
12042+
12043+static struct au_drinfo *au_drinfo_do_load(struct path *h_ppath,
12044+ char *whname, int whnamelen,
12045+ struct dentry **info_dentry)
12046+{
12047+ struct au_drinfo *drinfo;
12048+ struct file *f;
12049+ struct inode *h_dir;
12050+ struct path infopath;
12051+ int unlocked;
12052+
12053+ AuDbg("%pd/%.*s\n", h_ppath->dentry, whnamelen, whname);
12054+
12055+ *info_dentry = NULL;
12056+ drinfo = NULL;
12057+ unlocked = 0;
12058+ h_dir = d_inode(h_ppath->dentry);
be118d29 12059+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
8b6a4947
AM
12060+ infopath.dentry = vfsub_lookup_one_len(whname, h_ppath->dentry,
12061+ whnamelen);
12062+ if (IS_ERR(infopath.dentry)) {
12063+ drinfo = (void *)infopath.dentry;
12064+ goto out;
12065+ }
12066+
12067+ if (d_is_negative(infopath.dentry))
12068+ goto out_dput; /* success */
12069+
12070+ infopath.mnt = h_ppath->mnt;
12071+ f = vfsub_dentry_open(&infopath, O_RDONLY);
12072+ inode_unlock_shared(h_dir);
12073+ unlocked = 1;
12074+ if (IS_ERR(f)) {
12075+ drinfo = (void *)f;
12076+ goto out_dput;
12077+ }
12078+
12079+ drinfo = au_drinfo_read_k(f, /*h_ino*/0);
12080+ if (IS_ERR_OR_NULL(drinfo))
12081+ goto out_fput;
12082+
12083+ AuDbg("oldname %.*s\n", drinfo->oldnamelen, drinfo->oldname);
12084+ *info_dentry = dget(infopath.dentry); /* keep it alive */
12085+
12086+out_fput:
12087+ fput(f);
12088+out_dput:
12089+ dput(infopath.dentry);
12090+out:
12091+ if (!unlocked)
12092+ inode_unlock_shared(h_dir);
12093+ AuTraceErrPtr(drinfo);
12094+ return drinfo;
12095+}
12096+
12097+struct au_drinfo_do_load_args {
12098+ struct au_drinfo **drinfop;
12099+ struct path *h_ppath;
12100+ char *whname;
12101+ int whnamelen;
12102+ struct dentry **info_dentry;
12103+};
12104+
12105+static void au_call_drinfo_do_load(void *args)
12106+{
12107+ struct au_drinfo_do_load_args *a = args;
12108+
12109+ *a->drinfop = au_drinfo_do_load(a->h_ppath, a->whname, a->whnamelen,
12110+ a->info_dentry);
12111+}
12112+
12113+struct au_drinfo_load {
12114+ struct path h_ppath;
12115+ struct qstr *qname;
12116+ unsigned char no_sio;
12117+
12118+ aufs_bindex_t ninfo;
12119+ struct au_drinfo **drinfo;
12120+};
12121+
12122+static int au_drinfo_load(struct au_drinfo_load *w, aufs_bindex_t bindex,
12123+ struct au_branch *br)
12124+{
12125+ int err, wkq_err, whnamelen, e;
12126+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ]
12127+ = AUFS_WH_DR_INFO_PFX;
12128+ struct au_drinfo *drinfo;
12129+ struct qstr oldname;
12130+ struct inode *h_dir, *delegated;
12131+ struct dentry *info_dentry;
12132+ struct path infopath;
12133+
12134+ whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1;
12135+ whnamelen += au_drinfo_name(br, whname + whnamelen,
12136+ sizeof(whname) - whnamelen);
12137+ if (w->no_sio)
12138+ drinfo = au_drinfo_do_load(&w->h_ppath, whname, whnamelen,
12139+ &info_dentry);
12140+ else {
12141+ struct au_drinfo_do_load_args args = {
12142+ .drinfop = &drinfo,
12143+ .h_ppath = &w->h_ppath,
12144+ .whname = whname,
12145+ .whnamelen = whnamelen,
12146+ .info_dentry = &info_dentry
12147+ };
12148+ wkq_err = au_wkq_wait(au_call_drinfo_do_load, &args);
12149+ if (unlikely(wkq_err))
12150+ drinfo = ERR_PTR(wkq_err);
12151+ }
12152+ err = PTR_ERR(drinfo);
12153+ if (IS_ERR_OR_NULL(drinfo))
12154+ goto out;
12155+
12156+ err = 0;
12157+ oldname.len = drinfo->oldnamelen;
12158+ oldname.name = drinfo->oldname;
12159+ if (au_qstreq(w->qname, &oldname)) {
12160+ /* the name is renamed back */
9f237c51 12161+ au_kfree_rcu(drinfo);
8b6a4947
AM
12162+ drinfo = NULL;
12163+
12164+ infopath.dentry = info_dentry;
12165+ infopath.mnt = w->h_ppath.mnt;
12166+ h_dir = d_inode(w->h_ppath.dentry);
12167+ delegated = NULL;
12168+ inode_lock_nested(h_dir, AuLsc_I_PARENT);
12169+ e = vfsub_unlink(h_dir, &infopath, &delegated, !w->no_sio);
12170+ inode_unlock(h_dir);
12171+ if (unlikely(e))
12172+ AuIOErr("ignored %d, %pd2\n", e, &infopath.dentry);
12173+ if (unlikely(e == -EWOULDBLOCK))
12174+ iput(delegated);
12175+ }
9f237c51 12176+ au_kfree_rcu(w->drinfo[bindex]);
8b6a4947
AM
12177+ w->drinfo[bindex] = drinfo;
12178+ dput(info_dentry);
12179+
12180+out:
12181+ AuTraceErr(err);
12182+ return err;
12183+}
12184+
12185+/* ---------------------------------------------------------------------- */
12186+
12187+static void au_dr_lkup_free(struct au_drinfo **drinfo, int n)
12188+{
12189+ struct au_drinfo **p = drinfo;
12190+
12191+ while (n-- > 0)
9f237c51
AM
12192+ au_kfree_rcu(*drinfo++);
12193+ au_kfree_try_rcu(p);
8b6a4947
AM
12194+}
12195+
12196+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
12197+ aufs_bindex_t btgt)
12198+{
12199+ int err, ninfo;
12200+ struct au_drinfo_load w;
12201+ aufs_bindex_t bindex, bbot;
12202+ struct au_branch *br;
12203+ struct inode *h_dir;
12204+ struct au_dr_hino *ent;
12205+ struct super_block *sb;
12206+
12207+ AuDbg("%.*s, name %.*s, whname %.*s, b%d\n",
12208+ AuLNPair(&dentry->d_name), AuLNPair(&lkup->dirren.dr_name),
12209+ AuLNPair(&lkup->whname), btgt);
12210+
12211+ sb = dentry->d_sb;
12212+ bbot = au_sbbot(sb);
12213+ w.ninfo = bbot + 1;
12214+ if (!lkup->dirren.drinfo) {
12215+ lkup->dirren.drinfo = kcalloc(w.ninfo,
12216+ sizeof(*lkup->dirren.drinfo),
12217+ GFP_NOFS);
12218+ if (unlikely(!lkup->dirren.drinfo)) {
12219+ err = -ENOMEM;
12220+ goto out;
12221+ }
12222+ lkup->dirren.ninfo = w.ninfo;
12223+ }
12224+ w.drinfo = lkup->dirren.drinfo;
12225+ w.no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID);
12226+ w.h_ppath.dentry = au_h_dptr(dentry, btgt);
12227+ AuDebugOn(!w.h_ppath.dentry);
12228+ w.h_ppath.mnt = au_sbr_mnt(sb, btgt);
12229+ w.qname = &dentry->d_name;
12230+
12231+ ninfo = 0;
12232+ for (bindex = btgt + 1; bindex <= bbot; bindex++) {
12233+ br = au_sbr(sb, bindex);
12234+ err = au_drinfo_load(&w, bindex, br);
12235+ if (unlikely(err))
12236+ goto out_free;
12237+ if (w.drinfo[bindex])
12238+ ninfo++;
12239+ }
12240+ if (!ninfo) {
12241+ br = au_sbr(sb, btgt);
12242+ h_dir = d_inode(w.h_ppath.dentry);
12243+ ent = au_dr_hino_find(&br->br_dirren, h_dir->i_ino);
12244+ AuDebugOn(!ent);
12245+ au_dr_hino_del(&br->br_dirren, ent);
9f237c51 12246+ au_kfree_rcu(ent);
8b6a4947
AM
12247+ }
12248+ goto out; /* success */
12249+
12250+out_free:
12251+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo);
12252+ lkup->dirren.ninfo = 0;
12253+ lkup->dirren.drinfo = NULL;
12254+out:
12255+ AuTraceErr(err);
12256+ return err;
12257+}
12258+
12259+void au_dr_lkup_fin(struct au_do_lookup_args *lkup)
12260+{
12261+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo);
12262+}
12263+
12264+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt)
12265+{
12266+ int err;
12267+ struct au_drinfo *drinfo;
12268+
12269+ err = 0;
12270+ if (!lkup->dirren.drinfo)
12271+ goto out;
12272+ AuDebugOn(lkup->dirren.ninfo < btgt + 1);
12273+ drinfo = lkup->dirren.drinfo[btgt + 1];
12274+ if (!drinfo)
12275+ goto out;
12276+
9f237c51 12277+ au_kfree_try_rcu(lkup->whname.name);
8b6a4947
AM
12278+ lkup->whname.name = NULL;
12279+ lkup->dirren.dr_name.len = drinfo->oldnamelen;
12280+ lkup->dirren.dr_name.name = drinfo->oldname;
12281+ lkup->name = &lkup->dirren.dr_name;
12282+ err = au_wh_name_alloc(&lkup->whname, lkup->name);
12283+ if (!err)
12284+ AuDbg("name %.*s, whname %.*s, b%d\n",
12285+ AuLNPair(lkup->name), AuLNPair(&lkup->whname),
12286+ btgt);
12287+
12288+out:
12289+ AuTraceErr(err);
12290+ return err;
12291+}
12292+
12293+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
12294+ ino_t h_ino)
12295+{
12296+ int match;
12297+ struct au_drinfo *drinfo;
12298+
12299+ match = 1;
12300+ if (!lkup->dirren.drinfo)
12301+ goto out;
12302+ AuDebugOn(lkup->dirren.ninfo < bindex + 1);
12303+ drinfo = lkup->dirren.drinfo[bindex + 1];
12304+ if (!drinfo)
12305+ goto out;
12306+
12307+ match = (drinfo->ino == h_ino);
12308+ AuDbg("match %d\n", match);
12309+
12310+out:
12311+ return match;
12312+}
12313+
12314+/* ---------------------------------------------------------------------- */
12315+
12316+int au_dr_opt_set(struct super_block *sb)
12317+{
12318+ int err;
12319+ aufs_bindex_t bindex, bbot;
12320+ struct au_branch *br;
12321+
12322+ err = 0;
12323+ bbot = au_sbbot(sb);
12324+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
12325+ br = au_sbr(sb, bindex);
12326+ err = au_dr_hino(sb, bindex, /*br*/NULL, &br->br_path);
12327+ }
12328+
12329+ return err;
12330+}
12331+
12332+int au_dr_opt_flush(struct super_block *sb)
12333+{
12334+ int err;
12335+ aufs_bindex_t bindex, bbot;
12336+ struct au_branch *br;
12337+
12338+ err = 0;
12339+ bbot = au_sbbot(sb);
12340+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
12341+ br = au_sbr(sb, bindex);
12342+ if (au_br_writable(br->br_perm))
12343+ err = au_dr_hino(sb, bindex, /*br*/NULL, /*path*/NULL);
12344+ }
12345+
12346+ return err;
12347+}
12348+
12349+int au_dr_opt_clr(struct super_block *sb, int no_flush)
12350+{
12351+ int err;
12352+ aufs_bindex_t bindex, bbot;
12353+ struct au_branch *br;
12354+
12355+ err = 0;
12356+ if (!no_flush) {
12357+ err = au_dr_opt_flush(sb);
12358+ if (unlikely(err))
12359+ goto out;
12360+ }
12361+
12362+ bbot = au_sbbot(sb);
12363+ for (bindex = 0; bindex <= bbot; bindex++) {
12364+ br = au_sbr(sb, bindex);
12365+ au_dr_hino_free(&br->br_dirren);
12366+ }
12367+
12368+out:
12369+ return err;
12370+}
12371diff -urN /usr/share/empty/fs/aufs/dirren.h linux/fs/aufs/dirren.h
12372--- /usr/share/empty/fs/aufs/dirren.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 12373+++ linux/fs/aufs/dirren.h 2019-03-05 12:13:00.139224339 +0100
062440b3
AM
12374@@ -0,0 +1,140 @@
12375+/* SPDX-License-Identifier: GPL-2.0 */
8b6a4947 12376+/*
ba1aed25 12377+ * Copyright (C) 2017-2019 Junjiro R. Okajima
8b6a4947
AM
12378+ *
12379+ * This program, aufs is free software; you can redistribute it and/or modify
12380+ * it under the terms of the GNU General Public License as published by
12381+ * the Free Software Foundation; either version 2 of the License, or
12382+ * (at your option) any later version.
12383+ *
12384+ * This program is distributed in the hope that it will be useful,
12385+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12386+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12387+ * GNU General Public License for more details.
12388+ *
12389+ * You should have received a copy of the GNU General Public License
12390+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
12391+ */
12392+
12393+/*
12394+ * renamed dir info
12395+ */
12396+
12397+#ifndef __AUFS_DIRREN_H__
12398+#define __AUFS_DIRREN_H__
12399+
12400+#ifdef __KERNEL__
12401+
12402+#include <linux/dcache.h>
12403+#include <linux/statfs.h>
12404+#include <linux/uuid.h>
12405+#include "hbl.h"
12406+
12407+#define AuDirren_NHASH 100
12408+
12409+#ifdef CONFIG_AUFS_DIRREN
12410+enum au_brid_type {
12411+ AuBrid_Unset,
12412+ AuBrid_UUID,
12413+ AuBrid_FSID,
12414+ AuBrid_DEV
12415+};
12416+
12417+struct au_dr_brid {
12418+ enum au_brid_type type;
12419+ union {
12420+ uuid_t uuid; /* unimplemented yet */
12421+ fsid_t fsid;
12422+ dev_t dev;
12423+ };
12424+};
12425+
12426+/* 20 is the max digits length of ulong 64 */
12427+/* brid-type "_" uuid "_" inum */
12428+#define AUFS_DIRREN_FNAME_SZ (1 + 1 + UUID_STRING_LEN + 20)
12429+#define AUFS_DIRREN_ENV_VAL_SZ (AUFS_DIRREN_FNAME_SZ + 1 + 20)
12430+
12431+struct au_dr_hino {
12432+ struct hlist_bl_node dr_hnode;
12433+ ino_t dr_h_ino;
12434+};
12435+
12436+struct au_dr_br {
12437+ struct hlist_bl_head dr_h_ino[AuDirren_NHASH];
12438+ struct au_dr_brid dr_brid;
12439+};
12440+
12441+struct au_dr_lookup {
12442+ /* dr_name is pointed by struct au_do_lookup_args.name */
12443+ struct qstr dr_name; /* subset of dr_info */
12444+ aufs_bindex_t ninfo;
12445+ struct au_drinfo **drinfo;
12446+};
12447+#else
12448+struct au_dr_hino;
12449+/* empty */
12450+struct au_dr_br { };
12451+struct au_dr_lookup { };
12452+#endif
12453+
12454+/* ---------------------------------------------------------------------- */
12455+
12456+struct au_branch;
12457+struct au_do_lookup_args;
12458+struct au_hinode;
12459+#ifdef CONFIG_AUFS_DIRREN
12460+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t h_ino,
12461+ struct au_dr_hino *add_ent);
12462+void au_dr_hino_free(struct au_dr_br *dr);
12463+int au_dr_br_init(struct super_block *sb, struct au_branch *br,
12464+ const struct path *path);
12465+int au_dr_br_fin(struct super_block *sb, struct au_branch *br);
12466+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
12467+ struct qstr *dst_name, void *_rev);
12468+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *rev);
12469+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t bindex, void *rev);
12470+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
12471+ aufs_bindex_t bindex);
12472+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
12473+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
12474+ ino_t h_ino);
12475+void au_dr_lkup_fin(struct au_do_lookup_args *lkup);
12476+int au_dr_opt_set(struct super_block *sb);
12477+int au_dr_opt_flush(struct super_block *sb);
12478+int au_dr_opt_clr(struct super_block *sb, int no_flush);
12479+#else
12480+AuStubInt0(au_dr_hino_test_add, struct au_dr_br *dr, ino_t h_ino,
12481+ struct au_dr_hino *add_ent);
12482+AuStubVoid(au_dr_hino_free, struct au_dr_br *dr);
12483+AuStubInt0(au_dr_br_init, struct super_block *sb, struct au_branch *br,
12484+ const struct path *path);
12485+AuStubInt0(au_dr_br_fin, struct super_block *sb, struct au_branch *br);
12486+AuStubInt0(au_dr_rename, struct dentry *src, aufs_bindex_t bindex,
12487+ struct qstr *dst_name, void *_rev);
12488+AuStubVoid(au_dr_rename_fin, struct dentry *src, aufs_bindex_t btgt, void *rev);
12489+AuStubVoid(au_dr_rename_rev, struct dentry *src, aufs_bindex_t bindex,
12490+ void *rev);
12491+AuStubInt0(au_dr_lkup, struct au_do_lookup_args *lkup, struct dentry *dentry,
12492+ aufs_bindex_t bindex);
12493+AuStubInt0(au_dr_lkup_name, struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
12494+AuStubInt0(au_dr_lkup_h_ino, struct au_do_lookup_args *lkup,
12495+ aufs_bindex_t bindex, ino_t h_ino);
12496+AuStubVoid(au_dr_lkup_fin, struct au_do_lookup_args *lkup);
12497+AuStubInt0(au_dr_opt_set, struct super_block *sb);
12498+AuStubInt0(au_dr_opt_flush, struct super_block *sb);
12499+AuStubInt0(au_dr_opt_clr, struct super_block *sb, int no_flush);
12500+#endif
12501+
12502+/* ---------------------------------------------------------------------- */
12503+
12504+#ifdef CONFIG_AUFS_DIRREN
12505+static inline int au_dr_ihash(ino_t h_ino)
12506+{
12507+ return h_ino % AuDirren_NHASH;
12508+}
12509+#else
12510+AuStubInt0(au_dr_ihash, ino_t h_ino);
12511+#endif
12512+
12513+#endif /* __KERNEL__ */
12514+#endif /* __AUFS_DIRREN_H__ */
7f207e10
AM
12515diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
12516--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 12517+++ linux/fs/aufs/dynop.c 2019-03-05 12:13:00.139224339 +0100
062440b3 12518@@ -0,0 +1,370 @@
cd7a4cd9 12519+// SPDX-License-Identifier: GPL-2.0
1facf9fc 12520+/*
ba1aed25 12521+ * Copyright (C) 2010-2019 Junjiro R. Okajima
1facf9fc 12522+ *
12523+ * This program, aufs is free software; you can redistribute it and/or modify
12524+ * it under the terms of the GNU General Public License as published by
12525+ * the Free Software Foundation; either version 2 of the License, or
12526+ * (at your option) any later version.
dece6358
AM
12527+ *
12528+ * This program is distributed in the hope that it will be useful,
12529+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12530+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12531+ * GNU General Public License for more details.
12532+ *
12533+ * You should have received a copy of the GNU General Public License
523b37e3 12534+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 12535+ */
12536+
12537+/*
4a4d8108 12538+ * dynamically customizable operations for regular files
1facf9fc 12539+ */
12540+
1facf9fc 12541+#include "aufs.h"
12542+
4a4d8108 12543+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 12544+
4a4d8108
AM
12545+/*
12546+ * How large will these lists be?
12547+ * Usually just a few elements, 20-30 at most for each, I guess.
12548+ */
8b6a4947 12549+static struct hlist_bl_head dynop[AuDyLast];
4a4d8108 12550+
8b6a4947
AM
12551+static struct au_dykey *dy_gfind_get(struct hlist_bl_head *hbl,
12552+ const void *h_op)
1facf9fc 12553+{
4a4d8108 12554+ struct au_dykey *key, *tmp;
8b6a4947 12555+ struct hlist_bl_node *pos;
1facf9fc 12556+
4a4d8108 12557+ key = NULL;
8b6a4947
AM
12558+ hlist_bl_lock(hbl);
12559+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode)
4a4d8108
AM
12560+ if (tmp->dk_op.dy_hop == h_op) {
12561+ key = tmp;
12562+ kref_get(&key->dk_kref);
12563+ break;
12564+ }
8b6a4947 12565+ hlist_bl_unlock(hbl);
4a4d8108
AM
12566+
12567+ return key;
1facf9fc 12568+}
12569+
4a4d8108 12570+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 12571+{
4a4d8108
AM
12572+ struct au_dykey **k, *found;
12573+ const void *h_op = key->dk_op.dy_hop;
12574+ int i;
1facf9fc 12575+
4a4d8108
AM
12576+ found = NULL;
12577+ k = br->br_dykey;
12578+ for (i = 0; i < AuBrDynOp; i++)
12579+ if (k[i]) {
12580+ if (k[i]->dk_op.dy_hop == h_op) {
12581+ found = k[i];
12582+ break;
12583+ }
12584+ } else
12585+ break;
12586+ if (!found) {
12587+ spin_lock(&br->br_dykey_lock);
12588+ for (; i < AuBrDynOp; i++)
12589+ if (k[i]) {
12590+ if (k[i]->dk_op.dy_hop == h_op) {
12591+ found = k[i];
12592+ break;
12593+ }
12594+ } else {
12595+ k[i] = key;
12596+ break;
12597+ }
12598+ spin_unlock(&br->br_dykey_lock);
12599+ BUG_ON(i == AuBrDynOp); /* expand the array */
12600+ }
12601+
12602+ return found;
1facf9fc 12603+}
12604+
4a4d8108 12605+/* kref_get() if @key is already added */
8b6a4947 12606+static struct au_dykey *dy_gadd(struct hlist_bl_head *hbl, struct au_dykey *key)
4a4d8108
AM
12607+{
12608+ struct au_dykey *tmp, *found;
8b6a4947 12609+ struct hlist_bl_node *pos;
4a4d8108 12610+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 12611+
4a4d8108 12612+ found = NULL;
8b6a4947
AM
12613+ hlist_bl_lock(hbl);
12614+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode)
4a4d8108
AM
12615+ if (tmp->dk_op.dy_hop == h_op) {
12616+ kref_get(&tmp->dk_kref);
12617+ found = tmp;
12618+ break;
12619+ }
12620+ if (!found)
8b6a4947
AM
12621+ hlist_bl_add_head(&key->dk_hnode, hbl);
12622+ hlist_bl_unlock(hbl);
1facf9fc 12623+
4a4d8108
AM
12624+ if (!found)
12625+ DyPrSym(key);
12626+ return found;
12627+}
12628+
12629+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 12630+{
4a4d8108
AM
12631+ struct au_dykey *key;
12632+
12633+ key = container_of(rcu, struct au_dykey, dk_rcu);
12634+ DyPrSym(key);
9f237c51 12635+ au_kfree_rcu(key);
1facf9fc 12636+}
12637+
4a4d8108
AM
12638+static void dy_free(struct kref *kref)
12639+{
12640+ struct au_dykey *key;
8b6a4947 12641+ struct hlist_bl_head *hbl;
1facf9fc 12642+
4a4d8108 12643+ key = container_of(kref, struct au_dykey, dk_kref);
8b6a4947
AM
12644+ hbl = dynop + key->dk_op.dy_type;
12645+ au_hbl_del(&key->dk_hnode, hbl);
4a4d8108
AM
12646+ call_rcu(&key->dk_rcu, dy_free_rcu);
12647+}
12648+
12649+void au_dy_put(struct au_dykey *key)
1facf9fc 12650+{
4a4d8108
AM
12651+ kref_put(&key->dk_kref, dy_free);
12652+}
1facf9fc 12653+
4a4d8108
AM
12654+/* ---------------------------------------------------------------------- */
12655+
12656+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
12657+
12658+#ifdef CONFIG_AUFS_DEBUG
12659+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 12660+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
12661+#else
12662+#define DyDbgDeclare(cnt) do {} while (0)
12663+#define DyDbgInc(cnt) do {} while (0)
12664+#endif
12665+
12666+#define DySet(func, dst, src, h_op, h_sb) do { \
12667+ DyDbgInc(cnt); \
12668+ if (h_op->func) { \
12669+ if (src.func) \
12670+ dst.func = src.func; \
12671+ else \
12672+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
12673+ } \
12674+} while (0)
12675+
12676+#define DySetForce(func, dst, src) do { \
12677+ AuDebugOn(!src.func); \
12678+ DyDbgInc(cnt); \
12679+ dst.func = src.func; \
12680+} while (0)
12681+
12682+#define DySetAop(func) \
12683+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
12684+#define DySetAopForce(func) \
12685+ DySetForce(func, dyaop->da_op, aufs_aop)
12686+
12687+static void dy_aop(struct au_dykey *key, const void *h_op,
12688+ struct super_block *h_sb __maybe_unused)
12689+{
12690+ struct au_dyaop *dyaop = (void *)key;
12691+ const struct address_space_operations *h_aop = h_op;
12692+ DyDbgDeclare(cnt);
12693+
12694+ AuDbg("%s\n", au_sbtype(h_sb));
12695+
12696+ DySetAop(writepage);
12697+ DySetAopForce(readpage); /* force */
4a4d8108
AM
12698+ DySetAop(writepages);
12699+ DySetAop(set_page_dirty);
12700+ DySetAop(readpages);
12701+ DySetAop(write_begin);
12702+ DySetAop(write_end);
12703+ DySetAop(bmap);
12704+ DySetAop(invalidatepage);
12705+ DySetAop(releasepage);
027c5e7a 12706+ DySetAop(freepage);
7e9cd9fe 12707+ /* this one will be changed according to an aufs mount option */
4a4d8108 12708+ DySetAop(direct_IO);
4a4d8108 12709+ DySetAop(migratepage);
e2f27e51
AM
12710+ DySetAop(isolate_page);
12711+ DySetAop(putback_page);
4a4d8108
AM
12712+ DySetAop(launder_page);
12713+ DySetAop(is_partially_uptodate);
392086de 12714+ DySetAop(is_dirty_writeback);
4a4d8108 12715+ DySetAop(error_remove_page);
b4510431
AM
12716+ DySetAop(swap_activate);
12717+ DySetAop(swap_deactivate);
4a4d8108
AM
12718+
12719+ DyDbgSize(cnt, *h_aop);
4a4d8108
AM
12720+}
12721+
4a4d8108
AM
12722+/* ---------------------------------------------------------------------- */
12723+
12724+static void dy_bug(struct kref *kref)
12725+{
12726+ BUG();
12727+}
12728+
12729+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
12730+{
12731+ struct au_dykey *key, *old;
8b6a4947 12732+ struct hlist_bl_head *hbl;
b752ccd1 12733+ struct op {
4a4d8108 12734+ unsigned int sz;
b752ccd1
AM
12735+ void (*set)(struct au_dykey *key, const void *h_op,
12736+ struct super_block *h_sb __maybe_unused);
12737+ };
12738+ static const struct op a[] = {
4a4d8108
AM
12739+ [AuDy_AOP] = {
12740+ .sz = sizeof(struct au_dyaop),
b752ccd1 12741+ .set = dy_aop
4a4d8108 12742+ }
b752ccd1
AM
12743+ };
12744+ const struct op *p;
4a4d8108 12745+
8b6a4947
AM
12746+ hbl = dynop + op->dy_type;
12747+ key = dy_gfind_get(hbl, op->dy_hop);
4a4d8108
AM
12748+ if (key)
12749+ goto out_add; /* success */
12750+
12751+ p = a + op->dy_type;
12752+ key = kzalloc(p->sz, GFP_NOFS);
12753+ if (unlikely(!key)) {
12754+ key = ERR_PTR(-ENOMEM);
12755+ goto out;
12756+ }
12757+
12758+ key->dk_op.dy_hop = op->dy_hop;
12759+ kref_init(&key->dk_kref);
86dc4139 12760+ p->set(key, op->dy_hop, au_br_sb(br));
8b6a4947 12761+ old = dy_gadd(hbl, key);
4a4d8108 12762+ if (old) {
9f237c51 12763+ au_kfree_rcu(key);
4a4d8108
AM
12764+ key = old;
12765+ }
12766+
12767+out_add:
12768+ old = dy_bradd(br, key);
12769+ if (old)
12770+ /* its ref-count should never be zero here */
12771+ kref_put(&key->dk_kref, dy_bug);
12772+out:
12773+ return key;
12774+}
12775+
12776+/* ---------------------------------------------------------------------- */
12777+/*
acd2b654 12778+ * Aufs prohibits O_DIRECT by default even if the branch supports it.
c1595e42 12779+ * This behaviour is necessary to return an error from open(O_DIRECT) instead
4a4d8108
AM
12780+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
12781+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
12782+ * See the aufs manual in detail.
4a4d8108
AM
12783+ */
12784+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
12785+{
7e9cd9fe 12786+ if (!do_dx)
4a4d8108 12787+ dyaop->da_op.direct_IO = NULL;
7e9cd9fe 12788+ else
4a4d8108 12789+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
4a4d8108
AM
12790+}
12791+
12792+static struct au_dyaop *dy_aget(struct au_branch *br,
12793+ const struct address_space_operations *h_aop,
12794+ int do_dx)
12795+{
12796+ struct au_dyaop *dyaop;
12797+ struct au_dynop op;
12798+
12799+ op.dy_type = AuDy_AOP;
12800+ op.dy_haop = h_aop;
12801+ dyaop = (void *)dy_get(&op, br);
12802+ if (IS_ERR(dyaop))
12803+ goto out;
12804+ dy_adx(dyaop, do_dx);
12805+
12806+out:
12807+ return dyaop;
12808+}
12809+
12810+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
12811+ struct inode *h_inode)
12812+{
12813+ int err, do_dx;
12814+ struct super_block *sb;
12815+ struct au_branch *br;
12816+ struct au_dyaop *dyaop;
12817+
12818+ AuDebugOn(!S_ISREG(h_inode->i_mode));
12819+ IiMustWriteLock(inode);
12820+
12821+ sb = inode->i_sb;
12822+ br = au_sbr(sb, bindex);
12823+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
12824+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
12825+ err = PTR_ERR(dyaop);
12826+ if (IS_ERR(dyaop))
12827+ /* unnecessary to call dy_fput() */
12828+ goto out;
12829+
12830+ err = 0;
12831+ inode->i_mapping->a_ops = &dyaop->da_op;
12832+
12833+out:
12834+ return err;
12835+}
12836+
b752ccd1
AM
12837+/*
12838+ * Is it safe to replace a_ops during the inode/file is in operation?
12839+ * Yes, I hope so.
12840+ */
12841+int au_dy_irefresh(struct inode *inode)
12842+{
12843+ int err;
5afbbe0d 12844+ aufs_bindex_t btop;
b752ccd1
AM
12845+ struct inode *h_inode;
12846+
12847+ err = 0;
12848+ if (S_ISREG(inode->i_mode)) {
5afbbe0d
AM
12849+ btop = au_ibtop(inode);
12850+ h_inode = au_h_iptr(inode, btop);
12851+ err = au_dy_iaop(inode, btop, h_inode);
b752ccd1
AM
12852+ }
12853+ return err;
12854+}
12855+
4a4d8108
AM
12856+void au_dy_arefresh(int do_dx)
12857+{
8b6a4947
AM
12858+ struct hlist_bl_head *hbl;
12859+ struct hlist_bl_node *pos;
4a4d8108
AM
12860+ struct au_dykey *key;
12861+
8b6a4947
AM
12862+ hbl = dynop + AuDy_AOP;
12863+ hlist_bl_lock(hbl);
12864+ hlist_bl_for_each_entry(key, pos, hbl, dk_hnode)
4a4d8108 12865+ dy_adx((void *)key, do_dx);
8b6a4947 12866+ hlist_bl_unlock(hbl);
4a4d8108
AM
12867+}
12868+
4a4d8108
AM
12869+/* ---------------------------------------------------------------------- */
12870+
12871+void __init au_dy_init(void)
12872+{
12873+ int i;
12874+
12875+ /* make sure that 'struct au_dykey *' can be any type */
12876+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
12877+
12878+ for (i = 0; i < AuDyLast; i++)
8b6a4947 12879+ INIT_HLIST_BL_HEAD(dynop + i);
4a4d8108
AM
12880+}
12881+
12882+void au_dy_fin(void)
12883+{
12884+ int i;
12885+
12886+ for (i = 0; i < AuDyLast; i++)
8b6a4947 12887+ WARN_ON(!hlist_bl_empty(dynop + i));
4a4d8108 12888+}
7f207e10
AM
12889diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
12890--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 12891+++ linux/fs/aufs/dynop.h 2019-03-05 12:13:00.139224339 +0100
062440b3
AM
12892@@ -0,0 +1,75 @@
12893+/* SPDX-License-Identifier: GPL-2.0 */
4a4d8108 12894+/*
ba1aed25 12895+ * Copyright (C) 2010-2019 Junjiro R. Okajima
4a4d8108
AM
12896+ *
12897+ * This program, aufs is free software; you can redistribute it and/or modify
12898+ * it under the terms of the GNU General Public License as published by
12899+ * the Free Software Foundation; either version 2 of the License, or
12900+ * (at your option) any later version.
12901+ *
12902+ * This program is distributed in the hope that it will be useful,
12903+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12904+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12905+ * GNU General Public License for more details.
12906+ *
12907+ * You should have received a copy of the GNU General Public License
523b37e3 12908+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
12909+ */
12910+
12911+/*
12912+ * dynamically customizable operations (for regular files only)
12913+ */
12914+
12915+#ifndef __AUFS_DYNOP_H__
12916+#define __AUFS_DYNOP_H__
12917+
12918+#ifdef __KERNEL__
12919+
7e9cd9fe
AM
12920+#include <linux/fs.h>
12921+#include <linux/kref.h>
4a4d8108 12922+
2cbb1c4b 12923+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
12924+
12925+struct au_dynop {
12926+ int dy_type;
12927+ union {
12928+ const void *dy_hop;
12929+ const struct address_space_operations *dy_haop;
4a4d8108
AM
12930+ };
12931+};
12932+
12933+struct au_dykey {
12934+ union {
8b6a4947 12935+ struct hlist_bl_node dk_hnode;
4a4d8108
AM
12936+ struct rcu_head dk_rcu;
12937+ };
12938+ struct au_dynop dk_op;
12939+
12940+ /*
12941+ * during I am in the branch local array, kref is gotten. when the
12942+ * branch is removed, kref is put.
12943+ */
12944+ struct kref dk_kref;
12945+};
12946+
12947+/* stop unioning since their sizes are very different from each other */
12948+struct au_dyaop {
12949+ struct au_dykey da_key;
12950+ struct address_space_operations da_op; /* not const */
4a4d8108
AM
12951+};
12952+
4a4d8108
AM
12953+/* ---------------------------------------------------------------------- */
12954+
12955+/* dynop.c */
12956+struct au_branch;
12957+void au_dy_put(struct au_dykey *key);
12958+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
12959+ struct inode *h_inode);
b752ccd1 12960+int au_dy_irefresh(struct inode *inode);
4a4d8108 12961+void au_dy_arefresh(int do_dio);
4a4d8108
AM
12962+
12963+void __init au_dy_init(void);
12964+void au_dy_fin(void);
12965+
4a4d8108
AM
12966+#endif /* __KERNEL__ */
12967+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
12968diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
12969--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 12970+++ linux/fs/aufs/export.c 2019-03-05 12:13:00.139224339 +0100
062440b3 12971@@ -0,0 +1,838 @@
cd7a4cd9 12972+// SPDX-License-Identifier: GPL-2.0
4a4d8108 12973+/*
ba1aed25 12974+ * Copyright (C) 2005-2019 Junjiro R. Okajima
4a4d8108
AM
12975+ *
12976+ * This program, aufs is free software; you can redistribute it and/or modify
12977+ * it under the terms of the GNU General Public License as published by
12978+ * the Free Software Foundation; either version 2 of the License, or
12979+ * (at your option) any later version.
12980+ *
12981+ * This program is distributed in the hope that it will be useful,
12982+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12983+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12984+ * GNU General Public License for more details.
12985+ *
12986+ * You should have received a copy of the GNU General Public License
523b37e3 12987+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
12988+ */
12989+
12990+/*
12991+ * export via nfs
12992+ */
12993+
12994+#include <linux/exportfs.h>
7eafdf33 12995+#include <linux/fs_struct.h>
4a4d8108
AM
12996+#include <linux/namei.h>
12997+#include <linux/nsproxy.h>
12998+#include <linux/random.h>
12999+#include <linux/writeback.h>
13000+#include "aufs.h"
13001+
13002+union conv {
13003+#ifdef CONFIG_AUFS_INO_T_64
13004+ __u32 a[2];
13005+#else
13006+ __u32 a[1];
13007+#endif
13008+ ino_t ino;
13009+};
13010+
13011+static ino_t decode_ino(__u32 *a)
13012+{
13013+ union conv u;
13014+
13015+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
13016+ u.a[0] = a[0];
13017+#ifdef CONFIG_AUFS_INO_T_64
13018+ u.a[1] = a[1];
13019+#endif
13020+ return u.ino;
13021+}
13022+
13023+static void encode_ino(__u32 *a, ino_t ino)
13024+{
13025+ union conv u;
13026+
13027+ u.ino = ino;
13028+ a[0] = u.a[0];
13029+#ifdef CONFIG_AUFS_INO_T_64
13030+ a[1] = u.a[1];
13031+#endif
13032+}
13033+
13034+/* NFS file handle */
13035+enum {
13036+ Fh_br_id,
13037+ Fh_sigen,
13038+#ifdef CONFIG_AUFS_INO_T_64
13039+ /* support 64bit inode number */
13040+ Fh_ino1,
13041+ Fh_ino2,
13042+ Fh_dir_ino1,
13043+ Fh_dir_ino2,
13044+#else
13045+ Fh_ino1,
13046+ Fh_dir_ino1,
13047+#endif
13048+ Fh_igen,
13049+ Fh_h_type,
13050+ Fh_tail,
13051+
13052+ Fh_ino = Fh_ino1,
13053+ Fh_dir_ino = Fh_dir_ino1
13054+};
13055+
13056+static int au_test_anon(struct dentry *dentry)
13057+{
027c5e7a 13058+ /* note: read d_flags without d_lock */
4a4d8108
AM
13059+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
13060+}
13061+
a2a7ad62
AM
13062+int au_test_nfsd(void)
13063+{
13064+ int ret;
13065+ struct task_struct *tsk = current;
13066+ char comm[sizeof(tsk->comm)];
13067+
13068+ ret = 0;
13069+ if (tsk->flags & PF_KTHREAD) {
13070+ get_task_comm(comm, tsk);
13071+ ret = !strcmp(comm, "nfsd");
13072+ }
13073+
13074+ return ret;
13075+}
13076+
4a4d8108
AM
13077+/* ---------------------------------------------------------------------- */
13078+/* inode generation external table */
13079+
b752ccd1 13080+void au_xigen_inc(struct inode *inode)
4a4d8108 13081+{
4a4d8108
AM
13082+ loff_t pos;
13083+ ssize_t sz;
13084+ __u32 igen;
13085+ struct super_block *sb;
13086+ struct au_sbinfo *sbinfo;
13087+
4a4d8108 13088+ sb = inode->i_sb;
b752ccd1 13089+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 13090+
b752ccd1 13091+ sbinfo = au_sbi(sb);
1facf9fc 13092+ pos = inode->i_ino;
13093+ pos *= sizeof(igen);
13094+ igen = inode->i_generation + 1;
1facf9fc 13095+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
13096+ sizeof(igen), &pos);
13097+ if (sz == sizeof(igen))
b752ccd1 13098+ return; /* success */
1facf9fc 13099+
b752ccd1 13100+ if (unlikely(sz >= 0))
1facf9fc 13101+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 13102+}
13103+
13104+int au_xigen_new(struct inode *inode)
13105+{
13106+ int err;
13107+ loff_t pos;
13108+ ssize_t sz;
13109+ struct super_block *sb;
13110+ struct au_sbinfo *sbinfo;
13111+ struct file *file;
13112+
13113+ err = 0;
13114+ /* todo: dirty, at mount time */
13115+ if (inode->i_ino == AUFS_ROOT_INO)
13116+ goto out;
13117+ sb = inode->i_sb;
dece6358 13118+ SiMustAnyLock(sb);
1facf9fc 13119+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
13120+ goto out;
13121+
13122+ err = -EFBIG;
13123+ pos = inode->i_ino;
13124+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
13125+ AuIOErr1("too large i%lld\n", pos);
13126+ goto out;
13127+ }
13128+ pos *= sizeof(inode->i_generation);
13129+
13130+ err = 0;
13131+ sbinfo = au_sbi(sb);
13132+ file = sbinfo->si_xigen;
13133+ BUG_ON(!file);
13134+
c06a8ce3 13135+ if (vfsub_f_size_read(file)
1facf9fc 13136+ < pos + sizeof(inode->i_generation)) {
13137+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
13138+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
13139+ sizeof(inode->i_generation), &pos);
13140+ } else
13141+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
13142+ sizeof(inode->i_generation), &pos);
13143+ if (sz == sizeof(inode->i_generation))
13144+ goto out; /* success */
13145+
13146+ err = sz;
13147+ if (unlikely(sz >= 0)) {
13148+ err = -EIO;
13149+ AuIOErr("xigen error (%zd)\n", sz);
13150+ }
13151+
4f0767ce 13152+out:
1facf9fc 13153+ return err;
13154+}
13155+
062440b3 13156+int au_xigen_set(struct super_block *sb, struct path *path)
1facf9fc 13157+{
13158+ int err;
13159+ struct au_sbinfo *sbinfo;
13160+ struct file *file;
13161+
dece6358
AM
13162+ SiMustWriteLock(sb);
13163+
1facf9fc 13164+ sbinfo = au_sbi(sb);
062440b3 13165+ file = au_xino_create2(sb, path, sbinfo->si_xigen);
1facf9fc 13166+ err = PTR_ERR(file);
13167+ if (IS_ERR(file))
13168+ goto out;
13169+ err = 0;
13170+ if (sbinfo->si_xigen)
13171+ fput(sbinfo->si_xigen);
13172+ sbinfo->si_xigen = file;
13173+
4f0767ce 13174+out:
062440b3 13175+ AuTraceErr(err);
1facf9fc 13176+ return err;
13177+}
13178+
13179+void au_xigen_clr(struct super_block *sb)
13180+{
13181+ struct au_sbinfo *sbinfo;
13182+
dece6358
AM
13183+ SiMustWriteLock(sb);
13184+
1facf9fc 13185+ sbinfo = au_sbi(sb);
13186+ if (sbinfo->si_xigen) {
13187+ fput(sbinfo->si_xigen);
13188+ sbinfo->si_xigen = NULL;
13189+ }
13190+}
13191+
13192+/* ---------------------------------------------------------------------- */
13193+
13194+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
13195+ ino_t dir_ino)
13196+{
13197+ struct dentry *dentry, *d;
13198+ struct inode *inode;
13199+ unsigned int sigen;
13200+
13201+ dentry = NULL;
13202+ inode = ilookup(sb, ino);
13203+ if (!inode)
13204+ goto out;
13205+
13206+ dentry = ERR_PTR(-ESTALE);
13207+ sigen = au_sigen(sb);
5afbbe0d 13208+ if (unlikely(au_is_bad_inode(inode)
1facf9fc 13209+ || IS_DEADDIR(inode)
537831f9 13210+ || sigen != au_iigen(inode, NULL)))
1facf9fc 13211+ goto out_iput;
13212+
13213+ dentry = NULL;
13214+ if (!dir_ino || S_ISDIR(inode->i_mode))
13215+ dentry = d_find_alias(inode);
13216+ else {
027c5e7a 13217+ spin_lock(&inode->i_lock);
c1595e42 13218+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 13219+ spin_lock(&d->d_lock);
1facf9fc 13220+ if (!au_test_anon(d)
5527c038 13221+ && d_inode(d->d_parent)->i_ino == dir_ino) {
027c5e7a
AM
13222+ dentry = dget_dlock(d);
13223+ spin_unlock(&d->d_lock);
1facf9fc 13224+ break;
13225+ }
027c5e7a
AM
13226+ spin_unlock(&d->d_lock);
13227+ }
13228+ spin_unlock(&inode->i_lock);
1facf9fc 13229+ }
027c5e7a 13230+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 13231+ /* need to refresh */
1facf9fc 13232+ dput(dentry);
2cbb1c4b 13233+ dentry = NULL;
1facf9fc 13234+ }
13235+
4f0767ce 13236+out_iput:
1facf9fc 13237+ iput(inode);
4f0767ce 13238+out:
2cbb1c4b 13239+ AuTraceErrPtr(dentry);
1facf9fc 13240+ return dentry;
13241+}
13242+
13243+/* ---------------------------------------------------------------------- */
13244+
13245+/* todo: dirty? */
13246+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
13247+
13248+struct au_compare_mnt_args {
13249+ /* input */
13250+ struct super_block *sb;
13251+
13252+ /* output */
13253+ struct vfsmount *mnt;
13254+};
13255+
13256+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
13257+{
13258+ struct au_compare_mnt_args *a = arg;
13259+
13260+ if (mnt->mnt_sb != a->sb)
13261+ return 0;
13262+ a->mnt = mntget(mnt);
13263+ return 1;
13264+}
13265+
1facf9fc 13266+static struct vfsmount *au_mnt_get(struct super_block *sb)
13267+{
4a4d8108 13268+ int err;
7eafdf33 13269+ struct path root;
4a4d8108
AM
13270+ struct au_compare_mnt_args args = {
13271+ .sb = sb
13272+ };
1facf9fc 13273+
7eafdf33 13274+ get_fs_root(current->fs, &root);
523b37e3 13275+ rcu_read_lock();
7eafdf33 13276+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 13277+ rcu_read_unlock();
7eafdf33 13278+ path_put(&root);
4a4d8108
AM
13279+ AuDebugOn(!err);
13280+ AuDebugOn(!args.mnt);
13281+ return args.mnt;
1facf9fc 13282+}
13283+
13284+struct au_nfsd_si_lock {
4a4d8108 13285+ unsigned int sigen;
027c5e7a 13286+ aufs_bindex_t bindex, br_id;
1facf9fc 13287+ unsigned char force_lock;
13288+};
13289+
027c5e7a
AM
13290+static int si_nfsd_read_lock(struct super_block *sb,
13291+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 13292+{
027c5e7a 13293+ int err;
1facf9fc 13294+ aufs_bindex_t bindex;
13295+
13296+ si_read_lock(sb, AuLock_FLUSH);
13297+
13298+ /* branch id may be wrapped around */
027c5e7a 13299+ err = 0;
1facf9fc 13300+ bindex = au_br_index(sb, nsi_lock->br_id);
13301+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
13302+ goto out; /* success */
13303+
027c5e7a
AM
13304+ err = -ESTALE;
13305+ bindex = -1;
1facf9fc 13306+ if (!nsi_lock->force_lock)
13307+ si_read_unlock(sb);
1facf9fc 13308+
4f0767ce 13309+out:
027c5e7a
AM
13310+ nsi_lock->bindex = bindex;
13311+ return err;
1facf9fc 13312+}
13313+
13314+struct find_name_by_ino {
392086de 13315+ struct dir_context ctx;
1facf9fc 13316+ int called, found;
13317+ ino_t ino;
13318+ char *name;
13319+ int namelen;
13320+};
13321+
13322+static int
392086de
AM
13323+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
13324+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 13325+{
392086de
AM
13326+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
13327+ ctx);
1facf9fc 13328+
13329+ a->called++;
13330+ if (a->ino != ino)
13331+ return 0;
13332+
13333+ memcpy(a->name, name, namelen);
13334+ a->namelen = namelen;
13335+ a->found = 1;
13336+ return 1;
13337+}
13338+
13339+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
13340+ struct au_nfsd_si_lock *nsi_lock)
13341+{
13342+ struct dentry *dentry, *parent;
13343+ struct file *file;
13344+ struct inode *dir;
392086de
AM
13345+ struct find_name_by_ino arg = {
13346+ .ctx = {
2000de60 13347+ .actor = find_name_by_ino
392086de
AM
13348+ }
13349+ };
1facf9fc 13350+ int err;
13351+
13352+ parent = path->dentry;
13353+ if (nsi_lock)
13354+ si_read_unlock(parent->d_sb);
4a4d8108 13355+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 13356+ dentry = (void *)file;
13357+ if (IS_ERR(file))
13358+ goto out;
13359+
13360+ dentry = ERR_PTR(-ENOMEM);
537831f9 13361+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 13362+ if (unlikely(!arg.name))
13363+ goto out_file;
13364+ arg.ino = ino;
13365+ arg.found = 0;
13366+ do {
13367+ arg.called = 0;
13368+ /* smp_mb(); */
392086de 13369+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 13370+ } while (!err && !arg.found && arg.called);
13371+ dentry = ERR_PTR(err);
13372+ if (unlikely(err))
13373+ goto out_name;
1716fcea
AM
13374+ /* instead of ENOENT */
13375+ dentry = ERR_PTR(-ESTALE);
1facf9fc 13376+ if (!arg.found)
13377+ goto out_name;
13378+
b4510431 13379+ /* do not call vfsub_lkup_one() */
5527c038 13380+ dir = d_inode(parent);
febd17d6 13381+ dentry = vfsub_lookup_one_len_unlocked(arg.name, parent, arg.namelen);
1facf9fc 13382+ AuTraceErrPtr(dentry);
13383+ if (IS_ERR(dentry))
13384+ goto out_name;
13385+ AuDebugOn(au_test_anon(dentry));
5527c038 13386+ if (unlikely(d_really_is_negative(dentry))) {
1facf9fc 13387+ dput(dentry);
13388+ dentry = ERR_PTR(-ENOENT);
13389+ }
13390+
4f0767ce 13391+out_name:
1c60b727 13392+ free_page((unsigned long)arg.name);
4f0767ce 13393+out_file:
1facf9fc 13394+ fput(file);
4f0767ce 13395+out:
1facf9fc 13396+ if (unlikely(nsi_lock
13397+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
13398+ if (!IS_ERR(dentry)) {
13399+ dput(dentry);
13400+ dentry = ERR_PTR(-ESTALE);
13401+ }
13402+ AuTraceErrPtr(dentry);
13403+ return dentry;
13404+}
13405+
13406+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
13407+ ino_t dir_ino,
13408+ struct au_nfsd_si_lock *nsi_lock)
13409+{
13410+ struct dentry *dentry;
13411+ struct path path;
13412+
13413+ if (dir_ino != AUFS_ROOT_INO) {
13414+ path.dentry = decode_by_ino(sb, dir_ino, 0);
13415+ dentry = path.dentry;
13416+ if (!path.dentry || IS_ERR(path.dentry))
13417+ goto out;
13418+ AuDebugOn(au_test_anon(path.dentry));
13419+ } else
13420+ path.dentry = dget(sb->s_root);
13421+
13422+ path.mnt = au_mnt_get(sb);
13423+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
13424+ path_put(&path);
13425+
4f0767ce 13426+out:
1facf9fc 13427+ AuTraceErrPtr(dentry);
13428+ return dentry;
13429+}
13430+
13431+/* ---------------------------------------------------------------------- */
13432+
13433+static int h_acceptable(void *expv, struct dentry *dentry)
13434+{
13435+ return 1;
13436+}
13437+
13438+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
13439+ char *buf, int len, struct super_block *sb)
13440+{
13441+ char *p;
13442+ int n;
13443+ struct path path;
13444+
13445+ p = d_path(h_rootpath, buf, len);
13446+ if (IS_ERR(p))
13447+ goto out;
13448+ n = strlen(p);
13449+
13450+ path.mnt = h_rootpath->mnt;
13451+ path.dentry = h_parent;
13452+ p = d_path(&path, buf, len);
13453+ if (IS_ERR(p))
13454+ goto out;
13455+ if (n != 1)
13456+ p += n;
13457+
13458+ path.mnt = au_mnt_get(sb);
13459+ path.dentry = sb->s_root;
13460+ p = d_path(&path, buf, len - strlen(p));
13461+ mntput(path.mnt);
13462+ if (IS_ERR(p))
13463+ goto out;
13464+ if (n != 1)
13465+ p[strlen(p)] = '/';
13466+
4f0767ce 13467+out:
1facf9fc 13468+ AuTraceErrPtr(p);
13469+ return p;
13470+}
13471+
13472+static
027c5e7a
AM
13473+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
13474+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 13475+{
13476+ struct dentry *dentry, *h_parent, *root;
13477+ struct super_block *h_sb;
13478+ char *pathname, *p;
13479+ struct vfsmount *h_mnt;
13480+ struct au_branch *br;
13481+ int err;
13482+ struct path path;
13483+
027c5e7a 13484+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 13485+ h_mnt = au_br_mnt(br);
1facf9fc 13486+ h_sb = h_mnt->mnt_sb;
13487+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
5afbbe0d 13488+ lockdep_off();
1facf9fc 13489+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
13490+ fh_len - Fh_tail, fh[Fh_h_type],
13491+ h_acceptable, /*context*/NULL);
5afbbe0d 13492+ lockdep_on();
1facf9fc 13493+ dentry = h_parent;
13494+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
13495+ AuWarn1("%s decode_fh failed, %ld\n",
13496+ au_sbtype(h_sb), PTR_ERR(h_parent));
13497+ goto out;
13498+ }
13499+ dentry = NULL;
13500+ if (unlikely(au_test_anon(h_parent))) {
13501+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
13502+ au_sbtype(h_sb));
13503+ goto out_h_parent;
13504+ }
13505+
13506+ dentry = ERR_PTR(-ENOMEM);
13507+ pathname = (void *)__get_free_page(GFP_NOFS);
13508+ if (unlikely(!pathname))
13509+ goto out_h_parent;
13510+
13511+ root = sb->s_root;
13512+ path.mnt = h_mnt;
13513+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 13514+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 13515+ di_read_unlock(root, !AuLock_IR);
13516+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
13517+ dentry = (void *)p;
13518+ if (IS_ERR(p))
13519+ goto out_pathname;
13520+
13521+ si_read_unlock(sb);
13522+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
13523+ dentry = ERR_PTR(err);
13524+ if (unlikely(err))
13525+ goto out_relock;
13526+
13527+ dentry = ERR_PTR(-ENOENT);
13528+ AuDebugOn(au_test_anon(path.dentry));
5527c038 13529+ if (unlikely(d_really_is_negative(path.dentry)))
1facf9fc 13530+ goto out_path;
13531+
5527c038 13532+ if (ino != d_inode(path.dentry)->i_ino)
1facf9fc 13533+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
13534+ else
13535+ dentry = dget(path.dentry);
13536+
4f0767ce 13537+out_path:
1facf9fc 13538+ path_put(&path);
4f0767ce 13539+out_relock:
1facf9fc 13540+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
13541+ if (!IS_ERR(dentry)) {
13542+ dput(dentry);
13543+ dentry = ERR_PTR(-ESTALE);
13544+ }
4f0767ce 13545+out_pathname:
1c60b727 13546+ free_page((unsigned long)pathname);
4f0767ce 13547+out_h_parent:
1facf9fc 13548+ dput(h_parent);
4f0767ce 13549+out:
1facf9fc 13550+ AuTraceErrPtr(dentry);
13551+ return dentry;
13552+}
13553+
13554+/* ---------------------------------------------------------------------- */
13555+
13556+static struct dentry *
13557+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
13558+ int fh_type)
13559+{
13560+ struct dentry *dentry;
13561+ __u32 *fh = fid->raw;
027c5e7a 13562+ struct au_branch *br;
1facf9fc 13563+ ino_t ino, dir_ino;
1facf9fc 13564+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 13565+ .force_lock = 0
13566+ };
13567+
1facf9fc 13568+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
13569+ /* it should never happen, but the file handle is unreliable */
13570+ if (unlikely(fh_len < Fh_tail))
13571+ goto out;
13572+ nsi_lock.sigen = fh[Fh_sigen];
13573+ nsi_lock.br_id = fh[Fh_br_id];
13574+
1facf9fc 13575+ /* branch id may be wrapped around */
027c5e7a
AM
13576+ br = NULL;
13577+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 13578+ goto out;
13579+ nsi_lock.force_lock = 1;
13580+
13581+ /* is this inode still cached? */
13582+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
13583+ /* it should never happen */
13584+ if (unlikely(ino == AUFS_ROOT_INO))
8cdd5066 13585+ goto out_unlock;
4a4d8108 13586+
1facf9fc 13587+ dir_ino = decode_ino(fh + Fh_dir_ino);
13588+ dentry = decode_by_ino(sb, ino, dir_ino);
13589+ if (IS_ERR(dentry))
13590+ goto out_unlock;
13591+ if (dentry)
13592+ goto accept;
13593+
13594+ /* is the parent dir cached? */
027c5e7a 13595+ br = au_sbr(sb, nsi_lock.bindex);
acd2b654 13596+ au_lcnt_inc(&br->br_nfiles);
1facf9fc 13597+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
13598+ if (IS_ERR(dentry))
13599+ goto out_unlock;
13600+ if (dentry)
13601+ goto accept;
13602+
13603+ /* lookup path */
027c5e7a 13604+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 13605+ if (IS_ERR(dentry))
13606+ goto out_unlock;
13607+ if (unlikely(!dentry))
13608+ /* todo?: make it ESTALE */
13609+ goto out_unlock;
13610+
4f0767ce 13611+accept:
027c5e7a 13612+ if (!au_digen_test(dentry, au_sigen(sb))
5527c038 13613+ && d_inode(dentry)->i_generation == fh[Fh_igen])
1facf9fc 13614+ goto out_unlock; /* success */
13615+
13616+ dput(dentry);
13617+ dentry = ERR_PTR(-ESTALE);
4f0767ce 13618+out_unlock:
027c5e7a 13619+ if (br)
acd2b654 13620+ au_lcnt_dec(&br->br_nfiles);
1facf9fc 13621+ si_read_unlock(sb);
4f0767ce 13622+out:
1facf9fc 13623+ AuTraceErrPtr(dentry);
13624+ return dentry;
13625+}
13626+
13627+#if 0 /* reserved for future use */
13628+/* support subtreecheck option */
13629+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
13630+ int fh_len, int fh_type)
13631+{
13632+ struct dentry *parent;
13633+ __u32 *fh = fid->raw;
13634+ ino_t dir_ino;
13635+
13636+ dir_ino = decode_ino(fh + Fh_dir_ino);
13637+ parent = decode_by_ino(sb, dir_ino, 0);
13638+ if (IS_ERR(parent))
13639+ goto out;
13640+ if (!parent)
13641+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
13642+ dir_ino, fh, fh_len);
13643+
4f0767ce 13644+out:
1facf9fc 13645+ AuTraceErrPtr(parent);
13646+ return parent;
13647+}
13648+#endif
13649+
13650+/* ---------------------------------------------------------------------- */
13651+
0c3ec466
AM
13652+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
13653+ struct inode *dir)
1facf9fc 13654+{
13655+ int err;
0c3ec466 13656+ aufs_bindex_t bindex;
1facf9fc 13657+ struct super_block *sb, *h_sb;
0c3ec466
AM
13658+ struct dentry *dentry, *parent, *h_parent;
13659+ struct inode *h_dir;
1facf9fc 13660+ struct au_branch *br;
13661+
1facf9fc 13662+ err = -ENOSPC;
13663+ if (unlikely(*max_len <= Fh_tail)) {
13664+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
13665+ goto out;
13666+ }
13667+
13668+ err = FILEID_ROOT;
0c3ec466
AM
13669+ if (inode->i_ino == AUFS_ROOT_INO) {
13670+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 13671+ goto out;
13672+ }
13673+
1facf9fc 13674+ h_parent = NULL;
0c3ec466
AM
13675+ sb = inode->i_sb;
13676+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
13677+ if (unlikely(err))
13678+ goto out;
13679+
1facf9fc 13680+#ifdef CONFIG_AUFS_DEBUG
13681+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
13682+ AuWarn1("NFS-exporting requires xino\n");
13683+#endif
027c5e7a 13684+ err = -EIO;
0c3ec466
AM
13685+ parent = NULL;
13686+ ii_read_lock_child(inode);
5afbbe0d 13687+ bindex = au_ibtop(inode);
0c3ec466 13688+ if (!dir) {
c1595e42 13689+ dentry = d_find_any_alias(inode);
0c3ec466
AM
13690+ if (unlikely(!dentry))
13691+ goto out_unlock;
13692+ AuDebugOn(au_test_anon(dentry));
13693+ parent = dget_parent(dentry);
13694+ dput(dentry);
13695+ if (unlikely(!parent))
13696+ goto out_unlock;
5527c038
JR
13697+ if (d_really_is_positive(parent))
13698+ dir = d_inode(parent);
1facf9fc 13699+ }
0c3ec466
AM
13700+
13701+ ii_read_lock_parent(dir);
13702+ h_dir = au_h_iptr(dir, bindex);
13703+ ii_read_unlock(dir);
13704+ if (unlikely(!h_dir))
13705+ goto out_parent;
c1595e42 13706+ h_parent = d_find_any_alias(h_dir);
1facf9fc 13707+ if (unlikely(!h_parent))
0c3ec466 13708+ goto out_hparent;
1facf9fc 13709+
13710+ err = -EPERM;
13711+ br = au_sbr(sb, bindex);
86dc4139 13712+ h_sb = au_br_sb(br);
1facf9fc 13713+ if (unlikely(!h_sb->s_export_op)) {
13714+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 13715+ goto out_hparent;
1facf9fc 13716+ }
13717+
13718+ fh[Fh_br_id] = br->br_id;
13719+ fh[Fh_sigen] = au_sigen(sb);
13720+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 13721+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 13722+ fh[Fh_igen] = inode->i_generation;
13723+
13724+ *max_len -= Fh_tail;
13725+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
13726+ max_len,
13727+ /*connectable or subtreecheck*/0);
13728+ err = fh[Fh_h_type];
13729+ *max_len += Fh_tail;
13730+ /* todo: macros? */
1716fcea 13731+ if (err != FILEID_INVALID)
1facf9fc 13732+ err = 99;
13733+ else
13734+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
13735+
0c3ec466 13736+out_hparent:
1facf9fc 13737+ dput(h_parent);
0c3ec466 13738+out_parent:
1facf9fc 13739+ dput(parent);
0c3ec466
AM
13740+out_unlock:
13741+ ii_read_unlock(inode);
13742+ si_read_unlock(sb);
4f0767ce 13743+out:
1facf9fc 13744+ if (unlikely(err < 0))
1716fcea 13745+ err = FILEID_INVALID;
1facf9fc 13746+ return err;
13747+}
13748+
13749+/* ---------------------------------------------------------------------- */
13750+
4a4d8108
AM
13751+static int aufs_commit_metadata(struct inode *inode)
13752+{
13753+ int err;
13754+ aufs_bindex_t bindex;
13755+ struct super_block *sb;
13756+ struct inode *h_inode;
13757+ int (*f)(struct inode *inode);
13758+
13759+ sb = inode->i_sb;
e49829fe 13760+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 13761+ ii_write_lock_child(inode);
5afbbe0d 13762+ bindex = au_ibtop(inode);
4a4d8108
AM
13763+ AuDebugOn(bindex < 0);
13764+ h_inode = au_h_iptr(inode, bindex);
13765+
13766+ f = h_inode->i_sb->s_export_op->commit_metadata;
13767+ if (f)
13768+ err = f(h_inode);
13769+ else {
13770+ struct writeback_control wbc = {
13771+ .sync_mode = WB_SYNC_ALL,
13772+ .nr_to_write = 0 /* metadata only */
13773+ };
13774+
13775+ err = sync_inode(h_inode, &wbc);
13776+ }
13777+
13778+ au_cpup_attr_timesizes(inode);
13779+ ii_write_unlock(inode);
13780+ si_read_unlock(sb);
13781+ return err;
13782+}
13783+
13784+/* ---------------------------------------------------------------------- */
13785+
1facf9fc 13786+static struct export_operations aufs_export_op = {
4a4d8108 13787+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 13788+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
13789+ .encode_fh = aufs_encode_fh,
13790+ .commit_metadata = aufs_commit_metadata
1facf9fc 13791+};
13792+
13793+void au_export_init(struct super_block *sb)
13794+{
13795+ struct au_sbinfo *sbinfo;
13796+ __u32 u;
13797+
5afbbe0d
AM
13798+ BUILD_BUG_ON_MSG(IS_BUILTIN(CONFIG_AUFS_FS)
13799+ && IS_MODULE(CONFIG_EXPORTFS),
13800+ AUFS_NAME ": unsupported configuration "
13801+ "CONFIG_EXPORTFS=m and CONFIG_AUFS_FS=y");
13802+
1facf9fc 13803+ sb->s_export_op = &aufs_export_op;
13804+ sbinfo = au_sbi(sb);
13805+ sbinfo->si_xigen = NULL;
13806+ get_random_bytes(&u, sizeof(u));
13807+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
13808+ atomic_set(&sbinfo->si_xigen_next, u);
13809+}
076b876e
AM
13810diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
13811--- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 13812+++ linux/fs/aufs/fhsm.c 2019-03-05 12:13:00.139224339 +0100
062440b3 13813@@ -0,0 +1,427 @@
cd7a4cd9 13814+// SPDX-License-Identifier: GPL-2.0
076b876e 13815+/*
ba1aed25 13816+ * Copyright (C) 2011-2019 Junjiro R. Okajima
076b876e
AM
13817+ *
13818+ * This program, aufs is free software; you can redistribute it and/or modify
13819+ * it under the terms of the GNU General Public License as published by
13820+ * the Free Software Foundation; either version 2 of the License, or
13821+ * (at your option) any later version.
13822+ *
13823+ * This program is distributed in the hope that it will be useful,
13824+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13825+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13826+ * GNU General Public License for more details.
13827+ *
13828+ * You should have received a copy of the GNU General Public License
13829+ * along with this program; if not, write to the Free Software
13830+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13831+ */
13832+
13833+/*
13834+ * File-based Hierarchy Storage Management
13835+ */
13836+
13837+#include <linux/anon_inodes.h>
13838+#include <linux/poll.h>
13839+#include <linux/seq_file.h>
13840+#include <linux/statfs.h>
13841+#include "aufs.h"
13842+
c1595e42
JR
13843+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb)
13844+{
13845+ struct au_sbinfo *sbinfo;
13846+ struct au_fhsm *fhsm;
13847+
13848+ SiMustAnyLock(sb);
13849+
13850+ sbinfo = au_sbi(sb);
13851+ fhsm = &sbinfo->si_fhsm;
13852+ AuDebugOn(!fhsm);
13853+ return fhsm->fhsm_bottom;
13854+}
13855+
13856+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex)
13857+{
13858+ struct au_sbinfo *sbinfo;
13859+ struct au_fhsm *fhsm;
13860+
13861+ SiMustWriteLock(sb);
13862+
13863+ sbinfo = au_sbi(sb);
13864+ fhsm = &sbinfo->si_fhsm;
13865+ AuDebugOn(!fhsm);
13866+ fhsm->fhsm_bottom = bindex;
13867+}
13868+
13869+/* ---------------------------------------------------------------------- */
13870+
076b876e
AM
13871+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
13872+{
13873+ struct au_br_fhsm *bf;
13874+
13875+ bf = br->br_fhsm;
13876+ MtxMustLock(&bf->bf_lock);
13877+
13878+ return !bf->bf_readable
13879+ || time_after(jiffies,
13880+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
13881+}
13882+
13883+/* ---------------------------------------------------------------------- */
13884+
13885+static void au_fhsm_notify(struct super_block *sb, int val)
13886+{
13887+ struct au_sbinfo *sbinfo;
13888+ struct au_fhsm *fhsm;
13889+
13890+ SiMustAnyLock(sb);
13891+
13892+ sbinfo = au_sbi(sb);
13893+ fhsm = &sbinfo->si_fhsm;
13894+ if (au_fhsm_pid(fhsm)
13895+ && atomic_read(&fhsm->fhsm_readable) != -1) {
13896+ atomic_set(&fhsm->fhsm_readable, val);
13897+ if (val)
13898+ wake_up(&fhsm->fhsm_wqh);
13899+ }
13900+}
13901+
13902+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
13903+ struct aufs_stfs *rstfs, int do_lock, int do_notify)
13904+{
13905+ int err;
13906+ struct au_branch *br;
13907+ struct au_br_fhsm *bf;
13908+
13909+ br = au_sbr(sb, bindex);
13910+ AuDebugOn(au_br_rdonly(br));
13911+ bf = br->br_fhsm;
13912+ AuDebugOn(!bf);
13913+
13914+ if (do_lock)
13915+ mutex_lock(&bf->bf_lock);
13916+ else
13917+ MtxMustLock(&bf->bf_lock);
13918+
13919+ /* sb->s_root for NFS is unreliable */
13920+ err = au_br_stfs(br, &bf->bf_stfs);
13921+ if (unlikely(err)) {
13922+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
13923+ goto out;
13924+ }
13925+
13926+ bf->bf_jiffy = jiffies;
13927+ bf->bf_readable = 1;
13928+ if (do_notify)
13929+ au_fhsm_notify(sb, /*val*/1);
13930+ if (rstfs)
13931+ *rstfs = bf->bf_stfs;
13932+
13933+out:
13934+ if (do_lock)
13935+ mutex_unlock(&bf->bf_lock);
13936+ au_fhsm_notify(sb, /*val*/1);
13937+
13938+ return err;
13939+}
13940+
13941+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
13942+{
13943+ int err;
076b876e
AM
13944+ struct au_sbinfo *sbinfo;
13945+ struct au_fhsm *fhsm;
13946+ struct au_branch *br;
13947+ struct au_br_fhsm *bf;
13948+
13949+ AuDbg("b%d, force %d\n", bindex, force);
13950+ SiMustAnyLock(sb);
13951+
13952+ sbinfo = au_sbi(sb);
13953+ fhsm = &sbinfo->si_fhsm;
c1595e42
JR
13954+ if (!au_ftest_si(sbinfo, FHSM)
13955+ || fhsm->fhsm_bottom == bindex)
076b876e
AM
13956+ return;
13957+
13958+ br = au_sbr(sb, bindex);
13959+ bf = br->br_fhsm;
13960+ AuDebugOn(!bf);
13961+ mutex_lock(&bf->bf_lock);
13962+ if (force
13963+ || au_fhsm_pid(fhsm)
13964+ || au_fhsm_test_jiffy(sbinfo, br))
13965+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
13966+ /*do_notify*/1);
13967+ mutex_unlock(&bf->bf_lock);
13968+}
13969+
13970+void au_fhsm_wrote_all(struct super_block *sb, int force)
13971+{
5afbbe0d 13972+ aufs_bindex_t bindex, bbot;
076b876e
AM
13973+ struct au_branch *br;
13974+
13975+ /* exclude the bottom */
5afbbe0d
AM
13976+ bbot = au_fhsm_bottom(sb);
13977+ for (bindex = 0; bindex < bbot; bindex++) {
076b876e
AM
13978+ br = au_sbr(sb, bindex);
13979+ if (au_br_fhsm(br->br_perm))
13980+ au_fhsm_wrote(sb, bindex, force);
13981+ }
13982+}
13983+
13984+/* ---------------------------------------------------------------------- */
13985+
be118d29 13986+static __poll_t au_fhsm_poll(struct file *file, struct poll_table_struct *wait)
076b876e 13987+{
be118d29 13988+ __poll_t mask;
076b876e
AM
13989+ struct au_sbinfo *sbinfo;
13990+ struct au_fhsm *fhsm;
13991+
13992+ mask = 0;
13993+ sbinfo = file->private_data;
13994+ fhsm = &sbinfo->si_fhsm;
13995+ poll_wait(file, &fhsm->fhsm_wqh, wait);
13996+ if (atomic_read(&fhsm->fhsm_readable))
be118d29 13997+ mask = EPOLLIN /* | EPOLLRDNORM */;
076b876e 13998+
b00004a5
AM
13999+ if (!mask)
14000+ AuDbg("mask 0x%x\n", mask);
076b876e
AM
14001+ return mask;
14002+}
14003+
14004+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
14005+ struct aufs_stfs *stfs, __s16 brid)
14006+{
14007+ int err;
14008+
14009+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
14010+ if (!err)
14011+ err = __put_user(brid, &stbr->brid);
14012+ if (unlikely(err))
14013+ err = -EFAULT;
14014+
14015+ return err;
14016+}
14017+
14018+static ssize_t au_fhsm_do_read(struct super_block *sb,
14019+ struct aufs_stbr __user *stbr, size_t count)
14020+{
14021+ ssize_t err;
14022+ int nstbr;
5afbbe0d 14023+ aufs_bindex_t bindex, bbot;
076b876e
AM
14024+ struct au_branch *br;
14025+ struct au_br_fhsm *bf;
14026+
14027+ /* except the bottom branch */
14028+ err = 0;
14029+ nstbr = 0;
5afbbe0d
AM
14030+ bbot = au_fhsm_bottom(sb);
14031+ for (bindex = 0; !err && bindex < bbot; bindex++) {
076b876e
AM
14032+ br = au_sbr(sb, bindex);
14033+ if (!au_br_fhsm(br->br_perm))
14034+ continue;
14035+
14036+ bf = br->br_fhsm;
14037+ mutex_lock(&bf->bf_lock);
14038+ if (bf->bf_readable) {
14039+ err = -EFAULT;
14040+ if (count >= sizeof(*stbr))
14041+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
14042+ br->br_id);
14043+ if (!err) {
14044+ bf->bf_readable = 0;
14045+ count -= sizeof(*stbr);
14046+ nstbr++;
14047+ }
14048+ }
14049+ mutex_unlock(&bf->bf_lock);
14050+ }
14051+ if (!err)
14052+ err = sizeof(*stbr) * nstbr;
14053+
14054+ return err;
14055+}
14056+
14057+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
14058+ loff_t *pos)
14059+{
14060+ ssize_t err;
14061+ int readable;
5afbbe0d 14062+ aufs_bindex_t nfhsm, bindex, bbot;
076b876e
AM
14063+ struct au_sbinfo *sbinfo;
14064+ struct au_fhsm *fhsm;
14065+ struct au_branch *br;
14066+ struct super_block *sb;
14067+
14068+ err = 0;
14069+ sbinfo = file->private_data;
14070+ fhsm = &sbinfo->si_fhsm;
14071+need_data:
14072+ spin_lock_irq(&fhsm->fhsm_wqh.lock);
14073+ if (!atomic_read(&fhsm->fhsm_readable)) {
14074+ if (vfsub_file_flags(file) & O_NONBLOCK)
14075+ err = -EAGAIN;
14076+ else
14077+ err = wait_event_interruptible_locked_irq
14078+ (fhsm->fhsm_wqh,
14079+ atomic_read(&fhsm->fhsm_readable));
14080+ }
14081+ spin_unlock_irq(&fhsm->fhsm_wqh.lock);
14082+ if (unlikely(err))
14083+ goto out;
14084+
14085+ /* sb may already be dead */
14086+ au_rw_read_lock(&sbinfo->si_rwsem);
14087+ readable = atomic_read(&fhsm->fhsm_readable);
14088+ if (readable > 0) {
14089+ sb = sbinfo->si_sb;
14090+ AuDebugOn(!sb);
14091+ /* exclude the bottom branch */
14092+ nfhsm = 0;
5afbbe0d
AM
14093+ bbot = au_fhsm_bottom(sb);
14094+ for (bindex = 0; bindex < bbot; bindex++) {
076b876e
AM
14095+ br = au_sbr(sb, bindex);
14096+ if (au_br_fhsm(br->br_perm))
14097+ nfhsm++;
14098+ }
14099+ err = -EMSGSIZE;
14100+ if (nfhsm * sizeof(struct aufs_stbr) <= count) {
14101+ atomic_set(&fhsm->fhsm_readable, 0);
14102+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
14103+ count);
14104+ }
14105+ }
14106+ au_rw_read_unlock(&sbinfo->si_rwsem);
14107+ if (!readable)
14108+ goto need_data;
14109+
14110+out:
14111+ return err;
14112+}
14113+
14114+static int au_fhsm_release(struct inode *inode, struct file *file)
14115+{
14116+ struct au_sbinfo *sbinfo;
14117+ struct au_fhsm *fhsm;
14118+
14119+ /* sb may already be dead */
14120+ sbinfo = file->private_data;
14121+ fhsm = &sbinfo->si_fhsm;
14122+ spin_lock(&fhsm->fhsm_spin);
14123+ fhsm->fhsm_pid = 0;
14124+ spin_unlock(&fhsm->fhsm_spin);
14125+ kobject_put(&sbinfo->si_kobj);
14126+
14127+ return 0;
14128+}
14129+
14130+static const struct file_operations au_fhsm_fops = {
14131+ .owner = THIS_MODULE,
14132+ .llseek = noop_llseek,
14133+ .read = au_fhsm_read,
14134+ .poll = au_fhsm_poll,
14135+ .release = au_fhsm_release
14136+};
14137+
14138+int au_fhsm_fd(struct super_block *sb, int oflags)
14139+{
14140+ int err, fd;
14141+ struct au_sbinfo *sbinfo;
14142+ struct au_fhsm *fhsm;
14143+
14144+ err = -EPERM;
14145+ if (unlikely(!capable(CAP_SYS_ADMIN)))
14146+ goto out;
14147+
14148+ err = -EINVAL;
14149+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
14150+ goto out;
14151+
14152+ err = 0;
14153+ sbinfo = au_sbi(sb);
14154+ fhsm = &sbinfo->si_fhsm;
14155+ spin_lock(&fhsm->fhsm_spin);
14156+ if (!fhsm->fhsm_pid)
14157+ fhsm->fhsm_pid = current->pid;
14158+ else
14159+ err = -EBUSY;
14160+ spin_unlock(&fhsm->fhsm_spin);
14161+ if (unlikely(err))
14162+ goto out;
14163+
14164+ oflags |= O_RDONLY;
14165+ /* oflags |= FMODE_NONOTIFY; */
14166+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
14167+ err = fd;
14168+ if (unlikely(fd < 0))
14169+ goto out_pid;
14170+
acd2b654 14171+ /* succeed regardless 'fhsm' status */
076b876e
AM
14172+ kobject_get(&sbinfo->si_kobj);
14173+ si_noflush_read_lock(sb);
14174+ if (au_ftest_si(sbinfo, FHSM))
14175+ au_fhsm_wrote_all(sb, /*force*/0);
14176+ si_read_unlock(sb);
14177+ goto out; /* success */
14178+
14179+out_pid:
14180+ spin_lock(&fhsm->fhsm_spin);
14181+ fhsm->fhsm_pid = 0;
14182+ spin_unlock(&fhsm->fhsm_spin);
14183+out:
14184+ AuTraceErr(err);
14185+ return err;
14186+}
14187+
14188+/* ---------------------------------------------------------------------- */
14189+
14190+int au_fhsm_br_alloc(struct au_branch *br)
14191+{
14192+ int err;
14193+
14194+ err = 0;
14195+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
14196+ if (br->br_fhsm)
14197+ au_br_fhsm_init(br->br_fhsm);
14198+ else
14199+ err = -ENOMEM;
14200+
14201+ return err;
14202+}
14203+
14204+/* ---------------------------------------------------------------------- */
14205+
14206+void au_fhsm_fin(struct super_block *sb)
14207+{
14208+ au_fhsm_notify(sb, /*val*/-1);
14209+}
14210+
14211+void au_fhsm_init(struct au_sbinfo *sbinfo)
14212+{
14213+ struct au_fhsm *fhsm;
14214+
14215+ fhsm = &sbinfo->si_fhsm;
14216+ spin_lock_init(&fhsm->fhsm_spin);
14217+ init_waitqueue_head(&fhsm->fhsm_wqh);
14218+ atomic_set(&fhsm->fhsm_readable, 0);
14219+ fhsm->fhsm_expire
14220+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
c1595e42 14221+ fhsm->fhsm_bottom = -1;
076b876e
AM
14222+}
14223+
14224+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
14225+{
14226+ sbinfo->si_fhsm.fhsm_expire
14227+ = msecs_to_jiffies(sec * MSEC_PER_SEC);
14228+}
14229+
14230+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
14231+{
14232+ unsigned int u;
14233+
14234+ if (!au_ftest_si(sbinfo, FHSM))
14235+ return;
14236+
14237+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
14238+ if (u != AUFS_FHSM_CACHE_DEF_SEC)
14239+ seq_printf(seq, ",fhsm_sec=%u", u);
14240+}
7f207e10
AM
14241diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
14242--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 14243+++ linux/fs/aufs/file.c 2019-03-05 12:13:00.139224339 +0100
acd2b654 14244@@ -0,0 +1,863 @@
cd7a4cd9 14245+// SPDX-License-Identifier: GPL-2.0
1facf9fc 14246+/*
ba1aed25 14247+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 14248+ *
14249+ * This program, aufs is free software; you can redistribute it and/or modify
14250+ * it under the terms of the GNU General Public License as published by
14251+ * the Free Software Foundation; either version 2 of the License, or
14252+ * (at your option) any later version.
dece6358
AM
14253+ *
14254+ * This program is distributed in the hope that it will be useful,
14255+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14256+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14257+ * GNU General Public License for more details.
14258+ *
14259+ * You should have received a copy of the GNU General Public License
523b37e3 14260+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 14261+ */
14262+
14263+/*
4a4d8108 14264+ * handling file/dir, and address_space operation
1facf9fc 14265+ */
14266+
7eafdf33
AM
14267+#ifdef CONFIG_AUFS_DEBUG
14268+#include <linux/migrate.h>
14269+#endif
4a4d8108 14270+#include <linux/pagemap.h>
1facf9fc 14271+#include "aufs.h"
14272+
4a4d8108
AM
14273+/* drop flags for writing */
14274+unsigned int au_file_roflags(unsigned int flags)
14275+{
14276+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
14277+ flags |= O_RDONLY | O_NOATIME;
14278+ return flags;
14279+}
14280+
14281+/* common functions to regular file and dir */
14282+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 14283+ struct file *file, int force_wr)
1facf9fc 14284+{
1308ab2a 14285+ struct file *h_file;
4a4d8108
AM
14286+ struct dentry *h_dentry;
14287+ struct inode *h_inode;
14288+ struct super_block *sb;
14289+ struct au_branch *br;
14290+ struct path h_path;
b912730e 14291+ int err;
1facf9fc 14292+
4a4d8108
AM
14293+ /* a race condition can happen between open and unlink/rmdir */
14294+ h_file = ERR_PTR(-ENOENT);
14295+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 14296+ if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry)))
4a4d8108 14297+ goto out;
5527c038 14298+ h_inode = d_inode(h_dentry);
027c5e7a
AM
14299+ spin_lock(&h_dentry->d_lock);
14300+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
5527c038 14301+ /* || !d_inode(dentry)->i_nlink */
027c5e7a
AM
14302+ ;
14303+ spin_unlock(&h_dentry->d_lock);
14304+ if (unlikely(err))
4a4d8108 14305+ goto out;
1facf9fc 14306+
4a4d8108
AM
14307+ sb = dentry->d_sb;
14308+ br = au_sbr(sb, bindex);
b912730e
AM
14309+ err = au_br_test_oflag(flags, br);
14310+ h_file = ERR_PTR(err);
14311+ if (unlikely(err))
027c5e7a 14312+ goto out;
1facf9fc 14313+
4a4d8108 14314+ /* drop flags for writing */
5527c038 14315+ if (au_test_ro(sb, bindex, d_inode(dentry))) {
392086de
AM
14316+ if (force_wr && !(flags & O_WRONLY))
14317+ force_wr = 0;
4a4d8108 14318+ flags = au_file_roflags(flags);
392086de
AM
14319+ if (force_wr) {
14320+ h_file = ERR_PTR(-EROFS);
14321+ flags = au_file_roflags(flags);
14322+ if (unlikely(vfsub_native_ro(h_inode)
14323+ || IS_APPEND(h_inode)))
14324+ goto out;
14325+ flags &= ~O_ACCMODE;
14326+ flags |= O_WRONLY;
14327+ }
14328+ }
4a4d8108 14329+ flags &= ~O_CREAT;
acd2b654 14330+ au_lcnt_inc(&br->br_nfiles);
4a4d8108 14331+ h_path.dentry = h_dentry;
86dc4139 14332+ h_path.mnt = au_br_mnt(br);
38d290e6 14333+ h_file = vfsub_dentry_open(&h_path, flags);
4a4d8108
AM
14334+ if (IS_ERR(h_file))
14335+ goto out_br;
dece6358 14336+
b912730e 14337+ if (flags & __FMODE_EXEC) {
4a4d8108
AM
14338+ err = deny_write_access(h_file);
14339+ if (unlikely(err)) {
14340+ fput(h_file);
14341+ h_file = ERR_PTR(err);
14342+ goto out_br;
14343+ }
14344+ }
953406b4 14345+ fsnotify_open(h_file);
4a4d8108 14346+ goto out; /* success */
1facf9fc 14347+
4f0767ce 14348+out_br:
acd2b654 14349+ au_lcnt_dec(&br->br_nfiles);
4f0767ce 14350+out:
4a4d8108
AM
14351+ return h_file;
14352+}
1308ab2a 14353+
076b876e
AM
14354+static int au_cmoo(struct dentry *dentry)
14355+{
8b6a4947 14356+ int err, cmoo, matched;
076b876e
AM
14357+ unsigned int udba;
14358+ struct path h_path;
14359+ struct au_pin pin;
14360+ struct au_cp_generic cpg = {
14361+ .dentry = dentry,
14362+ .bdst = -1,
14363+ .bsrc = -1,
14364+ .len = -1,
14365+ .pin = &pin,
14366+ .flags = AuCpup_DTIME | AuCpup_HOPEN
14367+ };
7e9cd9fe 14368+ struct inode *delegated;
076b876e
AM
14369+ struct super_block *sb;
14370+ struct au_sbinfo *sbinfo;
14371+ struct au_fhsm *fhsm;
14372+ pid_t pid;
14373+ struct au_branch *br;
14374+ struct dentry *parent;
14375+ struct au_hinode *hdir;
14376+
14377+ DiMustWriteLock(dentry);
5527c038 14378+ IiMustWriteLock(d_inode(dentry));
076b876e
AM
14379+
14380+ err = 0;
14381+ if (IS_ROOT(dentry))
14382+ goto out;
5afbbe0d 14383+ cpg.bsrc = au_dbtop(dentry);
076b876e
AM
14384+ if (!cpg.bsrc)
14385+ goto out;
14386+
14387+ sb = dentry->d_sb;
14388+ sbinfo = au_sbi(sb);
14389+ fhsm = &sbinfo->si_fhsm;
14390+ pid = au_fhsm_pid(fhsm);
8b6a4947
AM
14391+ rcu_read_lock();
14392+ matched = (pid
14393+ && (current->pid == pid
14394+ || rcu_dereference(current->real_parent)->pid == pid));
14395+ rcu_read_unlock();
14396+ if (matched)
076b876e
AM
14397+ goto out;
14398+
14399+ br = au_sbr(sb, cpg.bsrc);
14400+ cmoo = au_br_cmoo(br->br_perm);
14401+ if (!cmoo)
14402+ goto out;
7e9cd9fe 14403+ if (!d_is_reg(dentry))
076b876e
AM
14404+ cmoo &= AuBrAttr_COO_ALL;
14405+ if (!cmoo)
14406+ goto out;
14407+
14408+ parent = dget_parent(dentry);
14409+ di_write_lock_parent(parent);
14410+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
14411+ cpg.bdst = err;
14412+ if (unlikely(err < 0)) {
14413+ err = 0; /* there is no upper writable branch */
14414+ goto out_dgrade;
14415+ }
14416+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
14417+
14418+ /* do not respect the coo attrib for the target branch */
14419+ err = au_cpup_dirs(dentry, cpg.bdst);
14420+ if (unlikely(err))
14421+ goto out_dgrade;
14422+
14423+ di_downgrade_lock(parent, AuLock_IR);
14424+ udba = au_opt_udba(sb);
14425+ err = au_pin(&pin, dentry, cpg.bdst, udba,
14426+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14427+ if (unlikely(err))
14428+ goto out_parent;
14429+
14430+ err = au_sio_cpup_simple(&cpg);
14431+ au_unpin(&pin);
14432+ if (unlikely(err))
14433+ goto out_parent;
14434+ if (!(cmoo & AuBrWAttr_MOO))
14435+ goto out_parent; /* success */
14436+
14437+ err = au_pin(&pin, dentry, cpg.bsrc, udba,
14438+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14439+ if (unlikely(err))
14440+ goto out_parent;
14441+
14442+ h_path.mnt = au_br_mnt(br);
14443+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
5527c038 14444+ hdir = au_hi(d_inode(parent), cpg.bsrc);
076b876e
AM
14445+ delegated = NULL;
14446+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
14447+ au_unpin(&pin);
14448+ /* todo: keep h_dentry or not? */
14449+ if (unlikely(err == -EWOULDBLOCK)) {
14450+ pr_warn("cannot retry for NFSv4 delegation"
14451+ " for an internal unlink\n");
14452+ iput(delegated);
14453+ }
14454+ if (unlikely(err)) {
14455+ pr_err("unlink %pd after coo failed (%d), ignored\n",
14456+ dentry, err);
14457+ err = 0;
14458+ }
14459+ goto out_parent; /* success */
14460+
14461+out_dgrade:
14462+ di_downgrade_lock(parent, AuLock_IR);
14463+out_parent:
14464+ di_read_unlock(parent, AuLock_IR);
14465+ dput(parent);
14466+out:
14467+ AuTraceErr(err);
14468+ return err;
14469+}
14470+
b912730e 14471+int au_do_open(struct file *file, struct au_do_open_args *args)
1facf9fc 14472+{
8b6a4947 14473+ int err, aopen = args->aopen;
1facf9fc 14474+ struct dentry *dentry;
076b876e 14475+ struct au_finfo *finfo;
1308ab2a 14476+
8b6a4947 14477+ if (!aopen)
b912730e
AM
14478+ err = au_finfo_init(file, args->fidir);
14479+ else {
14480+ lockdep_off();
14481+ err = au_finfo_init(file, args->fidir);
14482+ lockdep_on();
14483+ }
4a4d8108
AM
14484+ if (unlikely(err))
14485+ goto out;
1facf9fc 14486+
2000de60 14487+ dentry = file->f_path.dentry;
b912730e 14488+ AuDebugOn(IS_ERR_OR_NULL(dentry));
8b6a4947
AM
14489+ di_write_lock_child(dentry);
14490+ err = au_cmoo(dentry);
14491+ di_downgrade_lock(dentry, AuLock_IR);
14492+ if (!err) {
14493+ if (!aopen)
b912730e 14494+ err = args->open(file, vfsub_file_flags(file), NULL);
8b6a4947
AM
14495+ else {
14496+ lockdep_off();
acd2b654
AM
14497+ err = args->open(file, vfsub_file_flags(file),
14498+ args->h_file);
8b6a4947
AM
14499+ lockdep_on();
14500+ }
b912730e 14501+ }
8b6a4947 14502+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 14503+
076b876e
AM
14504+ finfo = au_fi(file);
14505+ if (!err) {
14506+ finfo->fi_file = file;
8b6a4947
AM
14507+ au_hbl_add(&finfo->fi_hlist,
14508+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
076b876e 14509+ }
8b6a4947 14510+ if (!aopen)
b912730e
AM
14511+ fi_write_unlock(file);
14512+ else {
14513+ lockdep_off();
14514+ fi_write_unlock(file);
14515+ lockdep_on();
14516+ }
4a4d8108 14517+ if (unlikely(err)) {
076b876e 14518+ finfo->fi_hdir = NULL;
1c60b727 14519+ au_finfo_fin(file);
1308ab2a 14520+ }
4a4d8108 14521+
4f0767ce 14522+out:
8b6a4947 14523+ AuTraceErr(err);
1308ab2a 14524+ return err;
14525+}
dece6358 14526+
4a4d8108 14527+int au_reopen_nondir(struct file *file)
1308ab2a 14528+{
4a4d8108 14529+ int err;
5afbbe0d 14530+ aufs_bindex_t btop;
4a4d8108 14531+ struct dentry *dentry;
acd2b654 14532+ struct au_branch *br;
4a4d8108 14533+ struct file *h_file, *h_file_tmp;
1308ab2a 14534+
2000de60 14535+ dentry = file->f_path.dentry;
5afbbe0d 14536+ btop = au_dbtop(dentry);
acd2b654 14537+ br = au_sbr(dentry->d_sb, btop);
4a4d8108 14538+ h_file_tmp = NULL;
5afbbe0d 14539+ if (au_fbtop(file) == btop) {
4a4d8108
AM
14540+ h_file = au_hf_top(file);
14541+ if (file->f_mode == h_file->f_mode)
14542+ return 0; /* success */
14543+ h_file_tmp = h_file;
14544+ get_file(h_file_tmp);
acd2b654 14545+ au_lcnt_inc(&br->br_nfiles);
5afbbe0d 14546+ au_set_h_fptr(file, btop, NULL);
4a4d8108
AM
14547+ }
14548+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
14549+ /*
14550+ * it can happen
14551+ * file exists on both of rw and ro
5afbbe0d 14552+ * open --> dbtop and fbtop are both 0
86dc4139
AM
14553+ * prepend a branch as rw, "rw" become ro
14554+ * remove rw/file
14555+ * delete the top branch, "rw" becomes rw again
5afbbe0d
AM
14556+ * --> dbtop is 1, fbtop is still 0
14557+ * write --> fbtop is 0 but dbtop is 1
86dc4139 14558+ */
5afbbe0d 14559+ /* AuDebugOn(au_fbtop(file) < btop); */
1308ab2a 14560+
5afbbe0d 14561+ h_file = au_h_open(dentry, btop, vfsub_file_flags(file) & ~O_TRUNC,
392086de 14562+ file, /*force_wr*/0);
4a4d8108 14563+ err = PTR_ERR(h_file);
86dc4139
AM
14564+ if (IS_ERR(h_file)) {
14565+ if (h_file_tmp) {
acd2b654 14566+ /* revert */
5afbbe0d 14567+ au_set_h_fptr(file, btop, h_file_tmp);
86dc4139
AM
14568+ h_file_tmp = NULL;
14569+ }
4a4d8108 14570+ goto out; /* todo: close all? */
86dc4139 14571+ }
4a4d8108
AM
14572+
14573+ err = 0;
5afbbe0d
AM
14574+ au_set_fbtop(file, btop);
14575+ au_set_h_fptr(file, btop, h_file);
4a4d8108
AM
14576+ au_update_figen(file);
14577+ /* todo: necessary? */
14578+ /* file->f_ra = h_file->f_ra; */
14579+
4f0767ce 14580+out:
acd2b654 14581+ if (h_file_tmp) {
4a4d8108 14582+ fput(h_file_tmp);
acd2b654
AM
14583+ au_lcnt_dec(&br->br_nfiles);
14584+ }
4a4d8108 14585+ return err;
1facf9fc 14586+}
14587+
1308ab2a 14588+/* ---------------------------------------------------------------------- */
14589+
4a4d8108
AM
14590+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
14591+ struct dentry *hi_wh)
1facf9fc 14592+{
4a4d8108 14593+ int err;
5afbbe0d 14594+ aufs_bindex_t btop;
4a4d8108
AM
14595+ struct au_dinfo *dinfo;
14596+ struct dentry *h_dentry;
14597+ struct au_hdentry *hdp;
1facf9fc 14598+
2000de60 14599+ dinfo = au_di(file->f_path.dentry);
4a4d8108 14600+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 14601+
5afbbe0d
AM
14602+ btop = dinfo->di_btop;
14603+ dinfo->di_btop = btgt;
14604+ hdp = au_hdentry(dinfo, btgt);
14605+ h_dentry = hdp->hd_dentry;
14606+ hdp->hd_dentry = hi_wh;
4a4d8108 14607+ err = au_reopen_nondir(file);
5afbbe0d
AM
14608+ hdp->hd_dentry = h_dentry;
14609+ dinfo->di_btop = btop;
1facf9fc 14610+
1facf9fc 14611+ return err;
14612+}
14613+
4a4d8108 14614+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 14615+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 14616+{
4a4d8108 14617+ int err;
027c5e7a 14618+ struct inode *inode, *h_inode;
c2b27bf2
AM
14619+ struct dentry *h_dentry, *hi_wh;
14620+ struct au_cp_generic cpg = {
2000de60 14621+ .dentry = file->f_path.dentry,
c2b27bf2
AM
14622+ .bdst = bcpup,
14623+ .bsrc = -1,
14624+ .len = len,
14625+ .pin = pin
14626+ };
1facf9fc 14627+
5afbbe0d 14628+ au_update_dbtop(cpg.dentry);
5527c038 14629+ inode = d_inode(cpg.dentry);
027c5e7a 14630+ h_inode = NULL;
5afbbe0d
AM
14631+ if (au_dbtop(cpg.dentry) <= bcpup
14632+ && au_dbbot(cpg.dentry) >= bcpup) {
c2b27bf2 14633+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
5527c038
JR
14634+ if (h_dentry && d_is_positive(h_dentry))
14635+ h_inode = d_inode(h_dentry);
027c5e7a 14636+ }
4a4d8108 14637+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 14638+ if (!hi_wh && !h_inode)
c2b27bf2 14639+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
14640+ else
14641+ /* already copied-up after unlink */
14642+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 14643+
4a4d8108 14644+ if (!err
38d290e6
JR
14645+ && (inode->i_nlink > 1
14646+ || (inode->i_state & I_LINKABLE))
c2b27bf2
AM
14647+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
14648+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 14649+
dece6358 14650+ return err;
1facf9fc 14651+}
14652+
4a4d8108
AM
14653+/*
14654+ * prepare the @file for writing.
14655+ */
14656+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 14657+{
4a4d8108 14658+ int err;
5afbbe0d 14659+ aufs_bindex_t dbtop;
c1595e42 14660+ struct dentry *parent;
86dc4139 14661+ struct inode *inode;
1facf9fc 14662+ struct super_block *sb;
4a4d8108 14663+ struct file *h_file;
c2b27bf2 14664+ struct au_cp_generic cpg = {
2000de60 14665+ .dentry = file->f_path.dentry,
c2b27bf2
AM
14666+ .bdst = -1,
14667+ .bsrc = -1,
14668+ .len = len,
14669+ .pin = pin,
14670+ .flags = AuCpup_DTIME
14671+ };
1facf9fc 14672+
c2b27bf2 14673+ sb = cpg.dentry->d_sb;
5527c038 14674+ inode = d_inode(cpg.dentry);
5afbbe0d 14675+ cpg.bsrc = au_fbtop(file);
c2b27bf2 14676+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 14677+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
14678+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
14679+ /*flags*/0);
1facf9fc 14680+ goto out;
4a4d8108 14681+ }
1facf9fc 14682+
027c5e7a 14683+ /* need to cpup or reopen */
c2b27bf2 14684+ parent = dget_parent(cpg.dentry);
4a4d8108 14685+ di_write_lock_parent(parent);
c2b27bf2
AM
14686+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
14687+ cpg.bdst = err;
4a4d8108
AM
14688+ if (unlikely(err < 0))
14689+ goto out_dgrade;
14690+ err = 0;
14691+
c2b27bf2
AM
14692+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
14693+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 14694+ if (unlikely(err))
4a4d8108
AM
14695+ goto out_dgrade;
14696+ }
14697+
c2b27bf2 14698+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
14699+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14700+ if (unlikely(err))
14701+ goto out_dgrade;
14702+
5afbbe0d
AM
14703+ dbtop = au_dbtop(cpg.dentry);
14704+ if (dbtop <= cpg.bdst)
c2b27bf2 14705+ cpg.bsrc = cpg.bdst;
027c5e7a 14706+
5afbbe0d 14707+ if (dbtop <= cpg.bdst /* just reopen */
c2b27bf2 14708+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 14709+ ) {
392086de 14710+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 14711+ if (IS_ERR(h_file))
027c5e7a 14712+ err = PTR_ERR(h_file);
86dc4139 14713+ else {
027c5e7a 14714+ di_downgrade_lock(parent, AuLock_IR);
5afbbe0d 14715+ if (dbtop > cpg.bdst)
c2b27bf2 14716+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
14717+ if (!err)
14718+ err = au_reopen_nondir(file);
c2b27bf2 14719+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 14720+ }
027c5e7a
AM
14721+ } else { /* copyup as wh and reopen */
14722+ /*
14723+ * since writable hfsplus branch is not supported,
14724+ * h_open_pre/post() are unnecessary.
14725+ */
c2b27bf2 14726+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 14727+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 14728+ }
4a4d8108
AM
14729+
14730+ if (!err) {
14731+ au_pin_set_parent_lflag(pin, /*lflag*/0);
14732+ goto out_dput; /* success */
14733+ }
14734+ au_unpin(pin);
14735+ goto out_unlock;
1facf9fc 14736+
4f0767ce 14737+out_dgrade:
4a4d8108 14738+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 14739+out_unlock:
4a4d8108 14740+ di_read_unlock(parent, AuLock_IR);
4f0767ce 14741+out_dput:
4a4d8108 14742+ dput(parent);
4f0767ce 14743+out:
1facf9fc 14744+ return err;
14745+}
14746+
4a4d8108
AM
14747+/* ---------------------------------------------------------------------- */
14748+
14749+int au_do_flush(struct file *file, fl_owner_t id,
14750+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 14751+{
4a4d8108 14752+ int err;
1facf9fc 14753+ struct super_block *sb;
4a4d8108 14754+ struct inode *inode;
1facf9fc 14755+
c06a8ce3
AM
14756+ inode = file_inode(file);
14757+ sb = inode->i_sb;
4a4d8108
AM
14758+ si_noflush_read_lock(sb);
14759+ fi_read_lock(file);
b752ccd1 14760+ ii_read_lock_child(inode);
1facf9fc 14761+
4a4d8108
AM
14762+ err = flush(file, id);
14763+ au_cpup_attr_timesizes(inode);
1facf9fc 14764+
b752ccd1 14765+ ii_read_unlock(inode);
4a4d8108 14766+ fi_read_unlock(file);
1308ab2a 14767+ si_read_unlock(sb);
dece6358 14768+ return err;
1facf9fc 14769+}
14770+
4a4d8108
AM
14771+/* ---------------------------------------------------------------------- */
14772+
14773+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 14774+{
4a4d8108 14775+ int err;
4a4d8108
AM
14776+ struct au_pin pin;
14777+ struct au_finfo *finfo;
c2b27bf2 14778+ struct dentry *parent, *hi_wh;
4a4d8108 14779+ struct inode *inode;
1facf9fc 14780+ struct super_block *sb;
c2b27bf2 14781+ struct au_cp_generic cpg = {
2000de60 14782+ .dentry = file->f_path.dentry,
c2b27bf2
AM
14783+ .bdst = -1,
14784+ .bsrc = -1,
14785+ .len = -1,
14786+ .pin = &pin,
14787+ .flags = AuCpup_DTIME
14788+ };
1facf9fc 14789+
4a4d8108
AM
14790+ FiMustWriteLock(file);
14791+
14792+ err = 0;
14793+ finfo = au_fi(file);
c2b27bf2 14794+ sb = cpg.dentry->d_sb;
5527c038 14795+ inode = d_inode(cpg.dentry);
5afbbe0d 14796+ cpg.bdst = au_ibtop(inode);
c2b27bf2 14797+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 14798+ goto out;
dece6358 14799+
c2b27bf2
AM
14800+ parent = dget_parent(cpg.dentry);
14801+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 14802+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
14803+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
14804+ cpg.bdst = err;
4a4d8108
AM
14805+ di_read_unlock(parent, !AuLock_IR);
14806+ if (unlikely(err < 0))
14807+ goto out_parent;
14808+ err = 0;
1facf9fc 14809+ }
1facf9fc 14810+
4a4d8108 14811+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 14812+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
14813+ if (!S_ISDIR(inode->i_mode)
14814+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 14815+ && au_plink_test(inode)
c2b27bf2 14816+ && !d_unhashed(cpg.dentry)
5afbbe0d 14817+ && cpg.bdst < au_dbtop(cpg.dentry)) {
c2b27bf2 14818+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
14819+ if (unlikely(err))
14820+ goto out_unlock;
14821+
14822+ /* always superio. */
c2b27bf2 14823+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 14824+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 14825+ if (!err) {
c2b27bf2 14826+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
14827+ au_unpin(&pin);
14828+ }
4a4d8108
AM
14829+ } else if (hi_wh) {
14830+ /* already copied-up after unlink */
c2b27bf2 14831+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
14832+ *need_reopen = 0;
14833+ }
1facf9fc 14834+
4f0767ce 14835+out_unlock:
4a4d8108 14836+ di_read_unlock(parent, AuLock_IR);
4f0767ce 14837+out_parent:
4a4d8108 14838+ dput(parent);
4f0767ce 14839+out:
1308ab2a 14840+ return err;
dece6358 14841+}
1facf9fc 14842+
4a4d8108 14843+static void au_do_refresh_dir(struct file *file)
dece6358 14844+{
5afbbe0d 14845+ aufs_bindex_t bindex, bbot, new_bindex, brid;
4a4d8108
AM
14846+ struct au_hfile *p, tmp, *q;
14847+ struct au_finfo *finfo;
1308ab2a 14848+ struct super_block *sb;
4a4d8108 14849+ struct au_fidir *fidir;
1facf9fc 14850+
4a4d8108 14851+ FiMustWriteLock(file);
1facf9fc 14852+
2000de60 14853+ sb = file->f_path.dentry->d_sb;
4a4d8108
AM
14854+ finfo = au_fi(file);
14855+ fidir = finfo->fi_hdir;
14856+ AuDebugOn(!fidir);
14857+ p = fidir->fd_hfile + finfo->fi_btop;
14858+ brid = p->hf_br->br_id;
5afbbe0d
AM
14859+ bbot = fidir->fd_bbot;
14860+ for (bindex = finfo->fi_btop; bindex <= bbot; bindex++, p++) {
4a4d8108
AM
14861+ if (!p->hf_file)
14862+ continue;
1308ab2a 14863+
4a4d8108
AM
14864+ new_bindex = au_br_index(sb, p->hf_br->br_id);
14865+ if (new_bindex == bindex)
14866+ continue;
14867+ if (new_bindex < 0) {
14868+ au_set_h_fptr(file, bindex, NULL);
14869+ continue;
14870+ }
1308ab2a 14871+
4a4d8108
AM
14872+ /* swap two lower inode, and loop again */
14873+ q = fidir->fd_hfile + new_bindex;
14874+ tmp = *q;
14875+ *q = *p;
14876+ *p = tmp;
14877+ if (tmp.hf_file) {
14878+ bindex--;
14879+ p--;
14880+ }
14881+ }
1308ab2a 14882+
4a4d8108 14883+ p = fidir->fd_hfile;
2000de60 14884+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) {
5afbbe0d
AM
14885+ bbot = au_sbbot(sb);
14886+ for (finfo->fi_btop = 0; finfo->fi_btop <= bbot;
4a4d8108
AM
14887+ finfo->fi_btop++, p++)
14888+ if (p->hf_file) {
c06a8ce3 14889+ if (file_inode(p->hf_file))
4a4d8108 14890+ break;
1c60b727 14891+ au_hfput(p, /*execed*/0);
4a4d8108
AM
14892+ }
14893+ } else {
5afbbe0d
AM
14894+ bbot = au_br_index(sb, brid);
14895+ for (finfo->fi_btop = 0; finfo->fi_btop < bbot;
4a4d8108
AM
14896+ finfo->fi_btop++, p++)
14897+ if (p->hf_file)
1c60b727 14898+ au_hfput(p, /*execed*/0);
5afbbe0d 14899+ bbot = au_sbbot(sb);
4a4d8108 14900+ }
1308ab2a 14901+
5afbbe0d
AM
14902+ p = fidir->fd_hfile + bbot;
14903+ for (fidir->fd_bbot = bbot; fidir->fd_bbot >= finfo->fi_btop;
4a4d8108
AM
14904+ fidir->fd_bbot--, p--)
14905+ if (p->hf_file) {
c06a8ce3 14906+ if (file_inode(p->hf_file))
4a4d8108 14907+ break;
1c60b727 14908+ au_hfput(p, /*execed*/0);
4a4d8108
AM
14909+ }
14910+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 14911+}
14912+
4a4d8108
AM
14913+/*
14914+ * after branch manipulating, refresh the file.
14915+ */
14916+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 14917+{
e2f27e51 14918+ int err, need_reopen, nbr;
5afbbe0d 14919+ aufs_bindex_t bbot, bindex;
4a4d8108 14920+ struct dentry *dentry;
e2f27e51 14921+ struct super_block *sb;
1308ab2a 14922+ struct au_finfo *finfo;
4a4d8108 14923+ struct au_hfile *hfile;
1facf9fc 14924+
2000de60 14925+ dentry = file->f_path.dentry;
e2f27e51
AM
14926+ sb = dentry->d_sb;
14927+ nbr = au_sbbot(sb) + 1;
1308ab2a 14928+ finfo = au_fi(file);
4a4d8108
AM
14929+ if (!finfo->fi_hdir) {
14930+ hfile = &finfo->fi_htop;
14931+ AuDebugOn(!hfile->hf_file);
e2f27e51 14932+ bindex = au_br_index(sb, hfile->hf_br->br_id);
4a4d8108
AM
14933+ AuDebugOn(bindex < 0);
14934+ if (bindex != finfo->fi_btop)
5afbbe0d 14935+ au_set_fbtop(file, bindex);
4a4d8108 14936+ } else {
e2f27e51 14937+ err = au_fidir_realloc(finfo, nbr, /*may_shrink*/0);
4a4d8108
AM
14938+ if (unlikely(err))
14939+ goto out;
14940+ au_do_refresh_dir(file);
14941+ }
1facf9fc 14942+
4a4d8108
AM
14943+ err = 0;
14944+ need_reopen = 1;
14945+ if (!au_test_mmapped(file))
14946+ err = au_file_refresh_by_inode(file, &need_reopen);
e2f27e51
AM
14947+ if (finfo->fi_hdir)
14948+ /* harmless if err */
14949+ au_fidir_realloc(finfo, nbr, /*may_shrink*/1);
027c5e7a 14950+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
14951+ err = reopen(file);
14952+ if (!err) {
14953+ au_update_figen(file);
14954+ goto out; /* success */
14955+ }
14956+
14957+ /* error, close all lower files */
14958+ if (finfo->fi_hdir) {
5afbbe0d
AM
14959+ bbot = au_fbbot_dir(file);
14960+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++)
4a4d8108
AM
14961+ au_set_h_fptr(file, bindex, NULL);
14962+ }
1facf9fc 14963+
4f0767ce 14964+out:
1facf9fc 14965+ return err;
14966+}
14967+
4a4d8108
AM
14968+/* common function to regular file and dir */
14969+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
521ced18 14970+ int wlock, unsigned int fi_lsc)
dece6358 14971+{
1308ab2a 14972+ int err;
4a4d8108 14973+ unsigned int sigen, figen;
5afbbe0d 14974+ aufs_bindex_t btop;
4a4d8108
AM
14975+ unsigned char pseudo_link;
14976+ struct dentry *dentry;
14977+ struct inode *inode;
1facf9fc 14978+
4a4d8108 14979+ err = 0;
2000de60 14980+ dentry = file->f_path.dentry;
5527c038 14981+ inode = d_inode(dentry);
4a4d8108 14982+ sigen = au_sigen(dentry->d_sb);
521ced18 14983+ fi_write_lock_nested(file, fi_lsc);
4a4d8108 14984+ figen = au_figen(file);
521ced18
JR
14985+ if (!fi_lsc)
14986+ di_write_lock_child(dentry);
14987+ else
14988+ di_write_lock_child2(dentry);
5afbbe0d
AM
14989+ btop = au_dbtop(dentry);
14990+ pseudo_link = (btop != au_ibtop(inode));
14991+ if (sigen == figen && !pseudo_link && au_fbtop(file) == btop) {
4a4d8108
AM
14992+ if (!wlock) {
14993+ di_downgrade_lock(dentry, AuLock_IR);
14994+ fi_downgrade_lock(file);
14995+ }
14996+ goto out; /* success */
14997+ }
dece6358 14998+
4a4d8108 14999+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 15000+ if (au_digen_test(dentry, sigen)) {
4a4d8108 15001+ err = au_reval_dpath(dentry, sigen);
027c5e7a 15002+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 15003+ }
dece6358 15004+
027c5e7a
AM
15005+ if (!err)
15006+ err = refresh_file(file, reopen);
4a4d8108
AM
15007+ if (!err) {
15008+ if (!wlock) {
15009+ di_downgrade_lock(dentry, AuLock_IR);
15010+ fi_downgrade_lock(file);
15011+ }
15012+ } else {
15013+ di_write_unlock(dentry);
15014+ fi_write_unlock(file);
15015+ }
1facf9fc 15016+
4f0767ce 15017+out:
1308ab2a 15018+ return err;
15019+}
1facf9fc 15020+
4a4d8108
AM
15021+/* ---------------------------------------------------------------------- */
15022+
15023+/* cf. aufs_nopage() */
15024+/* for madvise(2) */
15025+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 15026+{
4a4d8108
AM
15027+ unlock_page(page);
15028+ return 0;
15029+}
1facf9fc 15030+
4a4d8108 15031+/* it will never be called, but necessary to support O_DIRECT */
5afbbe0d 15032+static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
4a4d8108 15033+{ BUG(); return 0; }
1facf9fc 15034+
4a4d8108
AM
15035+/* they will never be called. */
15036+#ifdef CONFIG_AUFS_DEBUG
15037+static int aufs_write_begin(struct file *file, struct address_space *mapping,
15038+ loff_t pos, unsigned len, unsigned flags,
15039+ struct page **pagep, void **fsdata)
15040+{ AuUnsupport(); return 0; }
15041+static int aufs_write_end(struct file *file, struct address_space *mapping,
15042+ loff_t pos, unsigned len, unsigned copied,
15043+ struct page *page, void *fsdata)
15044+{ AuUnsupport(); return 0; }
15045+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
15046+{ AuUnsupport(); return 0; }
1308ab2a 15047+
4a4d8108
AM
15048+static int aufs_set_page_dirty(struct page *page)
15049+{ AuUnsupport(); return 0; }
392086de
AM
15050+static void aufs_invalidatepage(struct page *page, unsigned int offset,
15051+ unsigned int length)
4a4d8108
AM
15052+{ AuUnsupport(); }
15053+static int aufs_releasepage(struct page *page, gfp_t gfp)
15054+{ AuUnsupport(); return 0; }
79b8bda9 15055+#if 0 /* called by memory compaction regardless file */
4a4d8108 15056+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 15057+ struct page *page, enum migrate_mode mode)
4a4d8108 15058+{ AuUnsupport(); return 0; }
79b8bda9 15059+#endif
e2f27e51
AM
15060+static bool aufs_isolate_page(struct page *page, isolate_mode_t mode)
15061+{ AuUnsupport(); return true; }
15062+static void aufs_putback_page(struct page *page)
15063+{ AuUnsupport(); }
4a4d8108
AM
15064+static int aufs_launder_page(struct page *page)
15065+{ AuUnsupport(); return 0; }
15066+static int aufs_is_partially_uptodate(struct page *page,
38d290e6
JR
15067+ unsigned long from,
15068+ unsigned long count)
4a4d8108 15069+{ AuUnsupport(); return 0; }
392086de
AM
15070+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
15071+ bool *writeback)
15072+{ AuUnsupport(); }
4a4d8108
AM
15073+static int aufs_error_remove_page(struct address_space *mapping,
15074+ struct page *page)
15075+{ AuUnsupport(); return 0; }
b4510431
AM
15076+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
15077+ sector_t *span)
15078+{ AuUnsupport(); return 0; }
15079+static void aufs_swap_deactivate(struct file *file)
15080+{ AuUnsupport(); }
4a4d8108
AM
15081+#endif /* CONFIG_AUFS_DEBUG */
15082+
15083+const struct address_space_operations aufs_aop = {
15084+ .readpage = aufs_readpage,
15085+ .direct_IO = aufs_direct_IO,
4a4d8108
AM
15086+#ifdef CONFIG_AUFS_DEBUG
15087+ .writepage = aufs_writepage,
4a4d8108
AM
15088+ /* no writepages, because of writepage */
15089+ .set_page_dirty = aufs_set_page_dirty,
15090+ /* no readpages, because of readpage */
15091+ .write_begin = aufs_write_begin,
15092+ .write_end = aufs_write_end,
15093+ /* no bmap, no block device */
15094+ .invalidatepage = aufs_invalidatepage,
15095+ .releasepage = aufs_releasepage,
79b8bda9
AM
15096+ /* is fallback_migrate_page ok? */
15097+ /* .migratepage = aufs_migratepage, */
e2f27e51
AM
15098+ .isolate_page = aufs_isolate_page,
15099+ .putback_page = aufs_putback_page,
4a4d8108
AM
15100+ .launder_page = aufs_launder_page,
15101+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 15102+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
15103+ .error_remove_page = aufs_error_remove_page,
15104+ .swap_activate = aufs_swap_activate,
15105+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 15106+#endif /* CONFIG_AUFS_DEBUG */
dece6358 15107+};
7f207e10
AM
15108diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
15109--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 15110+++ linux/fs/aufs/file.h 2019-03-05 12:13:00.139224339 +0100
9f237c51 15111@@ -0,0 +1,342 @@
062440b3 15112+/* SPDX-License-Identifier: GPL-2.0 */
4a4d8108 15113+/*
ba1aed25 15114+ * Copyright (C) 2005-2019 Junjiro R. Okajima
4a4d8108
AM
15115+ *
15116+ * This program, aufs is free software; you can redistribute it and/or modify
15117+ * it under the terms of the GNU General Public License as published by
15118+ * the Free Software Foundation; either version 2 of the License, or
15119+ * (at your option) any later version.
15120+ *
15121+ * This program is distributed in the hope that it will be useful,
15122+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15123+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15124+ * GNU General Public License for more details.
15125+ *
15126+ * You should have received a copy of the GNU General Public License
523b37e3 15127+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15128+ */
1facf9fc 15129+
4a4d8108
AM
15130+/*
15131+ * file operations
15132+ */
1facf9fc 15133+
4a4d8108
AM
15134+#ifndef __AUFS_FILE_H__
15135+#define __AUFS_FILE_H__
1facf9fc 15136+
4a4d8108 15137+#ifdef __KERNEL__
1facf9fc 15138+
2cbb1c4b 15139+#include <linux/file.h>
4a4d8108 15140+#include <linux/fs.h>
3c1bdaff 15141+#include <linux/mm_types.h>
4a4d8108 15142+#include <linux/poll.h>
4a4d8108 15143+#include "rwsem.h"
1facf9fc 15144+
4a4d8108
AM
15145+struct au_branch;
15146+struct au_hfile {
15147+ struct file *hf_file;
15148+ struct au_branch *hf_br;
15149+};
1facf9fc 15150+
4a4d8108
AM
15151+struct au_vdir;
15152+struct au_fidir {
15153+ aufs_bindex_t fd_bbot;
15154+ aufs_bindex_t fd_nent;
15155+ struct au_vdir *fd_vdir_cache;
15156+ struct au_hfile fd_hfile[];
15157+};
1facf9fc 15158+
4a4d8108 15159+static inline int au_fidir_sz(int nent)
dece6358 15160+{
4f0767ce
JR
15161+ AuDebugOn(nent < 0);
15162+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 15163+}
1facf9fc 15164+
4a4d8108
AM
15165+struct au_finfo {
15166+ atomic_t fi_generation;
dece6358 15167+
4a4d8108
AM
15168+ struct au_rwsem fi_rwsem;
15169+ aufs_bindex_t fi_btop;
15170+
15171+ /* do not union them */
15172+ struct { /* for non-dir */
15173+ struct au_hfile fi_htop;
2cbb1c4b 15174+ atomic_t fi_mmapped;
4a4d8108
AM
15175+ };
15176+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3 15177+
8b6a4947 15178+ struct hlist_bl_node fi_hlist;
1c60b727 15179+ struct file *fi_file; /* very ugly */
9f237c51 15180+ struct rcu_head rcu;
4a4d8108 15181+} ____cacheline_aligned_in_smp;
1facf9fc 15182+
4a4d8108 15183+/* ---------------------------------------------------------------------- */
1facf9fc 15184+
4a4d8108
AM
15185+/* file.c */
15186+extern const struct address_space_operations aufs_aop;
15187+unsigned int au_file_roflags(unsigned int flags);
15188+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 15189+ struct file *file, int force_wr);
b912730e 15190+struct au_do_open_args {
8b6a4947 15191+ int aopen;
b912730e
AM
15192+ int (*open)(struct file *file, int flags,
15193+ struct file *h_file);
15194+ struct au_fidir *fidir;
15195+ struct file *h_file;
15196+};
15197+int au_do_open(struct file *file, struct au_do_open_args *args);
4a4d8108
AM
15198+int au_reopen_nondir(struct file *file);
15199+struct au_pin;
15200+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
15201+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
521ced18 15202+ int wlock, unsigned int fi_lsc);
4a4d8108
AM
15203+int au_do_flush(struct file *file, fl_owner_t id,
15204+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 15205+
4a4d8108
AM
15206+/* poll.c */
15207+#ifdef CONFIG_AUFS_POLL
cd7a4cd9 15208+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt);
4a4d8108 15209+#endif
1facf9fc 15210+
4a4d8108
AM
15211+#ifdef CONFIG_AUFS_BR_HFSPLUS
15212+/* hfsplus.c */
392086de
AM
15213+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
15214+ int force_wr);
4a4d8108
AM
15215+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
15216+ struct file *h_file);
15217+#else
c1595e42
JR
15218+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
15219+ aufs_bindex_t bindex, int force_wr)
4a4d8108
AM
15220+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
15221+ struct file *h_file);
15222+#endif
1facf9fc 15223+
4a4d8108
AM
15224+/* f_op.c */
15225+extern const struct file_operations aufs_file_fop;
b912730e 15226+int au_do_open_nondir(struct file *file, int flags, struct file *h_file);
4a4d8108 15227+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
521ced18 15228+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc);
4a4d8108 15229+
4a4d8108 15230+/* finfo.c */
f0c0a007 15231+void au_hfput(struct au_hfile *hf, int execed);
4a4d8108
AM
15232+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
15233+ struct file *h_file);
1facf9fc 15234+
4a4d8108 15235+void au_update_figen(struct file *file);
4a4d8108 15236+struct au_fidir *au_fidir_alloc(struct super_block *sb);
e2f27e51 15237+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink);
1facf9fc 15238+
4a4d8108 15239+void au_fi_init_once(void *_fi);
1c60b727 15240+void au_finfo_fin(struct file *file);
4a4d8108 15241+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 15242+
4a4d8108
AM
15243+/* ioctl.c */
15244+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
15245+#ifdef CONFIG_COMPAT
15246+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
15247+ unsigned long arg);
c2b27bf2
AM
15248+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
15249+ unsigned long arg);
b752ccd1 15250+#endif
1facf9fc 15251+
4a4d8108 15252+/* ---------------------------------------------------------------------- */
1facf9fc 15253+
4a4d8108
AM
15254+static inline struct au_finfo *au_fi(struct file *file)
15255+{
38d290e6 15256+ return file->private_data;
4a4d8108 15257+}
1facf9fc 15258+
4a4d8108 15259+/* ---------------------------------------------------------------------- */
1facf9fc 15260+
8b6a4947
AM
15261+#define fi_read_lock(f) au_rw_read_lock(&au_fi(f)->fi_rwsem)
15262+#define fi_write_lock(f) au_rw_write_lock(&au_fi(f)->fi_rwsem)
15263+#define fi_read_trylock(f) au_rw_read_trylock(&au_fi(f)->fi_rwsem)
15264+#define fi_write_trylock(f) au_rw_write_trylock(&au_fi(f)->fi_rwsem)
4a4d8108 15265+/*
8b6a4947
AM
15266+#define fi_read_trylock_nested(f) \
15267+ au_rw_read_trylock_nested(&au_fi(f)->fi_rwsem)
15268+#define fi_write_trylock_nested(f) \
15269+ au_rw_write_trylock_nested(&au_fi(f)->fi_rwsem)
15270+*/
15271+
15272+#define fi_read_unlock(f) au_rw_read_unlock(&au_fi(f)->fi_rwsem)
15273+#define fi_write_unlock(f) au_rw_write_unlock(&au_fi(f)->fi_rwsem)
15274+#define fi_downgrade_lock(f) au_rw_dgrade_lock(&au_fi(f)->fi_rwsem)
1308ab2a 15275+
521ced18
JR
15276+/* lock subclass for finfo */
15277+enum {
15278+ AuLsc_FI_1,
15279+ AuLsc_FI_2
15280+};
15281+
15282+static inline void fi_read_lock_nested(struct file *f, unsigned int lsc)
15283+{
15284+ au_rw_read_lock_nested(&au_fi(f)->fi_rwsem, lsc);
15285+}
15286+
15287+static inline void fi_write_lock_nested(struct file *f, unsigned int lsc)
15288+{
15289+ au_rw_write_lock_nested(&au_fi(f)->fi_rwsem, lsc);
15290+}
15291+
15292+/*
15293+ * fi_read_lock_1, fi_write_lock_1,
15294+ * fi_read_lock_2, fi_write_lock_2
15295+ */
15296+#define AuReadLockFunc(name) \
15297+static inline void fi_read_lock_##name(struct file *f) \
15298+{ fi_read_lock_nested(f, AuLsc_FI_##name); }
15299+
15300+#define AuWriteLockFunc(name) \
15301+static inline void fi_write_lock_##name(struct file *f) \
15302+{ fi_write_lock_nested(f, AuLsc_FI_##name); }
15303+
15304+#define AuRWLockFuncs(name) \
15305+ AuReadLockFunc(name) \
15306+ AuWriteLockFunc(name)
15307+
15308+AuRWLockFuncs(1);
15309+AuRWLockFuncs(2);
15310+
15311+#undef AuReadLockFunc
15312+#undef AuWriteLockFunc
15313+#undef AuRWLockFuncs
15314+
4a4d8108
AM
15315+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
15316+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
15317+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 15318+
1308ab2a 15319+/* ---------------------------------------------------------------------- */
15320+
4a4d8108 15321+/* todo: hard/soft set? */
5afbbe0d 15322+static inline aufs_bindex_t au_fbtop(struct file *file)
dece6358 15323+{
4a4d8108
AM
15324+ FiMustAnyLock(file);
15325+ return au_fi(file)->fi_btop;
15326+}
dece6358 15327+
5afbbe0d 15328+static inline aufs_bindex_t au_fbbot_dir(struct file *file)
4a4d8108
AM
15329+{
15330+ FiMustAnyLock(file);
15331+ AuDebugOn(!au_fi(file)->fi_hdir);
15332+ return au_fi(file)->fi_hdir->fd_bbot;
15333+}
1facf9fc 15334+
4a4d8108
AM
15335+static inline struct au_vdir *au_fvdir_cache(struct file *file)
15336+{
15337+ FiMustAnyLock(file);
15338+ AuDebugOn(!au_fi(file)->fi_hdir);
15339+ return au_fi(file)->fi_hdir->fd_vdir_cache;
15340+}
1facf9fc 15341+
5afbbe0d 15342+static inline void au_set_fbtop(struct file *file, aufs_bindex_t bindex)
4a4d8108
AM
15343+{
15344+ FiMustWriteLock(file);
15345+ au_fi(file)->fi_btop = bindex;
15346+}
1facf9fc 15347+
5afbbe0d 15348+static inline void au_set_fbbot_dir(struct file *file, aufs_bindex_t bindex)
4a4d8108
AM
15349+{
15350+ FiMustWriteLock(file);
15351+ AuDebugOn(!au_fi(file)->fi_hdir);
15352+ au_fi(file)->fi_hdir->fd_bbot = bindex;
15353+}
1308ab2a 15354+
4a4d8108
AM
15355+static inline void au_set_fvdir_cache(struct file *file,
15356+ struct au_vdir *vdir_cache)
15357+{
15358+ FiMustWriteLock(file);
15359+ AuDebugOn(!au_fi(file)->fi_hdir);
15360+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
15361+}
dece6358 15362+
4a4d8108
AM
15363+static inline struct file *au_hf_top(struct file *file)
15364+{
15365+ FiMustAnyLock(file);
15366+ AuDebugOn(au_fi(file)->fi_hdir);
15367+ return au_fi(file)->fi_htop.hf_file;
15368+}
1facf9fc 15369+
4a4d8108
AM
15370+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
15371+{
15372+ FiMustAnyLock(file);
15373+ AuDebugOn(!au_fi(file)->fi_hdir);
15374+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
15375+}
15376+
4a4d8108
AM
15377+/* todo: memory barrier? */
15378+static inline unsigned int au_figen(struct file *f)
dece6358 15379+{
4a4d8108
AM
15380+ return atomic_read(&au_fi(f)->fi_generation);
15381+}
dece6358 15382+
2cbb1c4b
JR
15383+static inline void au_set_mmapped(struct file *f)
15384+{
15385+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
15386+ return;
0c3ec466 15387+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
15388+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
15389+ ;
15390+}
15391+
15392+static inline void au_unset_mmapped(struct file *f)
15393+{
15394+ atomic_dec(&au_fi(f)->fi_mmapped);
15395+}
15396+
4a4d8108
AM
15397+static inline int au_test_mmapped(struct file *f)
15398+{
2cbb1c4b
JR
15399+ return atomic_read(&au_fi(f)->fi_mmapped);
15400+}
15401+
15402+/* customize vma->vm_file */
15403+
15404+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
15405+ struct file *file)
15406+{
53392da6
AM
15407+ struct file *f;
15408+
15409+ f = vma->vm_file;
2cbb1c4b
JR
15410+ get_file(file);
15411+ vma->vm_file = file;
53392da6 15412+ fput(f);
2cbb1c4b
JR
15413+}
15414+
15415+#ifdef CONFIG_MMU
15416+#define AuDbgVmRegion(file, vma) do {} while (0)
15417+
15418+static inline void au_vm_file_reset(struct vm_area_struct *vma,
15419+ struct file *file)
15420+{
15421+ au_do_vm_file_reset(vma, file);
15422+}
15423+#else
15424+#define AuDbgVmRegion(file, vma) \
15425+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
15426+
15427+static inline void au_vm_file_reset(struct vm_area_struct *vma,
15428+ struct file *file)
15429+{
53392da6
AM
15430+ struct file *f;
15431+
2cbb1c4b 15432+ au_do_vm_file_reset(vma, file);
53392da6 15433+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
15434+ get_file(file);
15435+ vma->vm_region->vm_file = file;
53392da6 15436+ fput(f);
2cbb1c4b
JR
15437+}
15438+#endif /* CONFIG_MMU */
15439+
15440+/* handle vma->vm_prfile */
fb47a38f 15441+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
15442+ struct file *file)
15443+{
2cbb1c4b
JR
15444+ get_file(file);
15445+ vma->vm_prfile = file;
15446+#ifndef CONFIG_MMU
15447+ get_file(file);
15448+ vma->vm_region->vm_prfile = file;
15449+#endif
fb47a38f 15450+}
1308ab2a 15451+
4a4d8108
AM
15452+#endif /* __KERNEL__ */
15453+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
15454diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
15455--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 15456+++ linux/fs/aufs/finfo.c 2019-03-05 12:13:00.139224339 +0100
062440b3 15457@@ -0,0 +1,149 @@
cd7a4cd9 15458+// SPDX-License-Identifier: GPL-2.0
4a4d8108 15459+/*
ba1aed25 15460+ * Copyright (C) 2005-2019 Junjiro R. Okajima
4a4d8108
AM
15461+ *
15462+ * This program, aufs is free software; you can redistribute it and/or modify
15463+ * it under the terms of the GNU General Public License as published by
15464+ * the Free Software Foundation; either version 2 of the License, or
15465+ * (at your option) any later version.
15466+ *
15467+ * This program is distributed in the hope that it will be useful,
15468+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15469+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15470+ * GNU General Public License for more details.
15471+ *
15472+ * You should have received a copy of the GNU General Public License
523b37e3 15473+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15474+ */
1308ab2a 15475+
4a4d8108
AM
15476+/*
15477+ * file private data
15478+ */
1facf9fc 15479+
4a4d8108 15480+#include "aufs.h"
1facf9fc 15481+
f0c0a007 15482+void au_hfput(struct au_hfile *hf, int execed)
4a4d8108 15483+{
f0c0a007 15484+ if (execed)
4a4d8108
AM
15485+ allow_write_access(hf->hf_file);
15486+ fput(hf->hf_file);
15487+ hf->hf_file = NULL;
acd2b654 15488+ au_lcnt_dec(&hf->hf_br->br_nfiles);
4a4d8108
AM
15489+ hf->hf_br = NULL;
15490+}
1facf9fc 15491+
4a4d8108
AM
15492+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
15493+{
15494+ struct au_finfo *finfo = au_fi(file);
15495+ struct au_hfile *hf;
15496+ struct au_fidir *fidir;
15497+
15498+ fidir = finfo->fi_hdir;
15499+ if (!fidir) {
15500+ AuDebugOn(finfo->fi_btop != bindex);
15501+ hf = &finfo->fi_htop;
15502+ } else
15503+ hf = fidir->fd_hfile + bindex;
15504+
15505+ if (hf && hf->hf_file)
f0c0a007 15506+ au_hfput(hf, vfsub_file_execed(file));
4a4d8108
AM
15507+ if (val) {
15508+ FiMustWriteLock(file);
b912730e 15509+ AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry));
4a4d8108 15510+ hf->hf_file = val;
2000de60 15511+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex);
1308ab2a 15512+ }
4a4d8108 15513+}
1facf9fc 15514+
4a4d8108
AM
15515+void au_update_figen(struct file *file)
15516+{
2000de60 15517+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry));
4a4d8108 15518+ /* smp_mb(); */ /* atomic_set */
1facf9fc 15519+}
15520+
4a4d8108
AM
15521+/* ---------------------------------------------------------------------- */
15522+
4a4d8108
AM
15523+struct au_fidir *au_fidir_alloc(struct super_block *sb)
15524+{
15525+ struct au_fidir *fidir;
15526+ int nbr;
15527+
5afbbe0d 15528+ nbr = au_sbbot(sb) + 1;
4a4d8108
AM
15529+ if (nbr < 2)
15530+ nbr = 2; /* initial allocate for 2 branches */
15531+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
15532+ if (fidir) {
15533+ fidir->fd_bbot = -1;
15534+ fidir->fd_nent = nbr;
4a4d8108
AM
15535+ }
15536+
15537+ return fidir;
15538+}
15539+
e2f27e51 15540+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink)
4a4d8108
AM
15541+{
15542+ int err;
15543+ struct au_fidir *fidir, *p;
15544+
15545+ AuRwMustWriteLock(&finfo->fi_rwsem);
15546+ fidir = finfo->fi_hdir;
15547+ AuDebugOn(!fidir);
15548+
15549+ err = -ENOMEM;
15550+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
e2f27e51 15551+ GFP_NOFS, may_shrink);
4a4d8108
AM
15552+ if (p) {
15553+ p->fd_nent = nbr;
15554+ finfo->fi_hdir = p;
15555+ err = 0;
15556+ }
1facf9fc 15557+
dece6358 15558+ return err;
1facf9fc 15559+}
1308ab2a 15560+
15561+/* ---------------------------------------------------------------------- */
15562+
1c60b727 15563+void au_finfo_fin(struct file *file)
1308ab2a 15564+{
4a4d8108
AM
15565+ struct au_finfo *finfo;
15566+
acd2b654 15567+ au_lcnt_dec(&au_sbi(file->f_path.dentry->d_sb)->si_nfiles);
7f207e10 15568+
4a4d8108
AM
15569+ finfo = au_fi(file);
15570+ AuDebugOn(finfo->fi_hdir);
15571+ AuRwDestroy(&finfo->fi_rwsem);
1c60b727 15572+ au_cache_free_finfo(finfo);
1308ab2a 15573+}
1308ab2a 15574+
e49829fe 15575+void au_fi_init_once(void *_finfo)
4a4d8108 15576+{
e49829fe 15577+ struct au_finfo *finfo = _finfo;
1308ab2a 15578+
e49829fe 15579+ au_rw_init(&finfo->fi_rwsem);
4a4d8108 15580+}
1308ab2a 15581+
4a4d8108
AM
15582+int au_finfo_init(struct file *file, struct au_fidir *fidir)
15583+{
1716fcea 15584+ int err;
4a4d8108
AM
15585+ struct au_finfo *finfo;
15586+ struct dentry *dentry;
15587+
15588+ err = -ENOMEM;
2000de60 15589+ dentry = file->f_path.dentry;
4a4d8108
AM
15590+ finfo = au_cache_alloc_finfo();
15591+ if (unlikely(!finfo))
15592+ goto out;
15593+
15594+ err = 0;
acd2b654 15595+ au_lcnt_inc(&au_sbi(dentry->d_sb)->si_nfiles);
4a4d8108
AM
15596+ au_rw_write_lock(&finfo->fi_rwsem);
15597+ finfo->fi_btop = -1;
15598+ finfo->fi_hdir = fidir;
15599+ atomic_set(&finfo->fi_generation, au_digen(dentry));
15600+ /* smp_mb(); */ /* atomic_set */
15601+
15602+ file->private_data = finfo;
15603+
15604+out:
15605+ return err;
15606+}
7f207e10
AM
15607diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
15608--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 15609+++ linux/fs/aufs/f_op.c 2019-03-05 12:13:00.139224339 +0100
acd2b654 15610@@ -0,0 +1,819 @@
cd7a4cd9 15611+// SPDX-License-Identifier: GPL-2.0
dece6358 15612+/*
ba1aed25 15613+ * Copyright (C) 2005-2019 Junjiro R. Okajima
dece6358
AM
15614+ *
15615+ * This program, aufs is free software; you can redistribute it and/or modify
15616+ * it under the terms of the GNU General Public License as published by
15617+ * the Free Software Foundation; either version 2 of the License, or
15618+ * (at your option) any later version.
15619+ *
15620+ * This program is distributed in the hope that it will be useful,
15621+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15622+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15623+ * GNU General Public License for more details.
15624+ *
15625+ * You should have received a copy of the GNU General Public License
523b37e3 15626+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 15627+ */
1facf9fc 15628+
15629+/*
4a4d8108 15630+ * file and vm operations
1facf9fc 15631+ */
dece6358 15632+
86dc4139 15633+#include <linux/aio.h>
4a4d8108
AM
15634+#include <linux/fs_stack.h>
15635+#include <linux/mman.h>
4a4d8108 15636+#include <linux/security.h>
dece6358
AM
15637+#include "aufs.h"
15638+
b912730e 15639+int au_do_open_nondir(struct file *file, int flags, struct file *h_file)
1facf9fc 15640+{
4a4d8108
AM
15641+ int err;
15642+ aufs_bindex_t bindex;
8cdd5066 15643+ struct dentry *dentry, *h_dentry;
4a4d8108 15644+ struct au_finfo *finfo;
38d290e6 15645+ struct inode *h_inode;
4a4d8108
AM
15646+
15647+ FiMustWriteLock(file);
15648+
523b37e3 15649+ err = 0;
2000de60 15650+ dentry = file->f_path.dentry;
b912730e 15651+ AuDebugOn(IS_ERR_OR_NULL(dentry));
4a4d8108
AM
15652+ finfo = au_fi(file);
15653+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 15654+ atomic_set(&finfo->fi_mmapped, 0);
5afbbe0d 15655+ bindex = au_dbtop(dentry);
8cdd5066
JR
15656+ if (!h_file) {
15657+ h_dentry = au_h_dptr(dentry, bindex);
15658+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
15659+ if (unlikely(err))
15660+ goto out;
b912730e 15661+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
acd2b654
AM
15662+ if (IS_ERR(h_file)) {
15663+ err = PTR_ERR(h_file);
15664+ goto out;
15665+ }
8cdd5066
JR
15666+ } else {
15667+ h_dentry = h_file->f_path.dentry;
15668+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
15669+ if (unlikely(err))
15670+ goto out;
acd2b654 15671+ /* br ref is already inc-ed */
8cdd5066 15672+ }
acd2b654
AM
15673+
15674+ if ((flags & __O_TMPFILE)
15675+ && !(flags & O_EXCL)) {
15676+ h_inode = file_inode(h_file);
15677+ spin_lock(&h_inode->i_lock);
15678+ h_inode->i_state |= I_LINKABLE;
15679+ spin_unlock(&h_inode->i_lock);
4a4d8108 15680+ }
acd2b654
AM
15681+ au_set_fbtop(file, bindex);
15682+ au_set_h_fptr(file, bindex, h_file);
15683+ au_update_figen(file);
15684+ /* todo: necessary? */
15685+ /* file->f_ra = h_file->f_ra; */
027c5e7a 15686+
8cdd5066 15687+out:
4a4d8108 15688+ return err;
1facf9fc 15689+}
15690+
4a4d8108
AM
15691+static int aufs_open_nondir(struct inode *inode __maybe_unused,
15692+ struct file *file)
1facf9fc 15693+{
4a4d8108 15694+ int err;
1308ab2a 15695+ struct super_block *sb;
b912730e
AM
15696+ struct au_do_open_args args = {
15697+ .open = au_do_open_nondir
15698+ };
1facf9fc 15699+
523b37e3
AM
15700+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
15701+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 15702+
2000de60 15703+ sb = file->f_path.dentry->d_sb;
4a4d8108 15704+ si_read_lock(sb, AuLock_FLUSH);
b912730e 15705+ err = au_do_open(file, &args);
4a4d8108
AM
15706+ si_read_unlock(sb);
15707+ return err;
15708+}
1facf9fc 15709+
4a4d8108
AM
15710+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
15711+{
15712+ struct au_finfo *finfo;
15713+ aufs_bindex_t bindex;
1facf9fc 15714+
4a4d8108 15715+ finfo = au_fi(file);
8b6a4947
AM
15716+ au_hbl_del(&finfo->fi_hlist,
15717+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108 15718+ bindex = finfo->fi_btop;
b4510431 15719+ if (bindex >= 0)
4a4d8108 15720+ au_set_h_fptr(file, bindex, NULL);
7f207e10 15721+
1c60b727 15722+ au_finfo_fin(file);
4a4d8108 15723+ return 0;
1facf9fc 15724+}
15725+
4a4d8108
AM
15726+/* ---------------------------------------------------------------------- */
15727+
15728+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 15729+{
1308ab2a 15730+ int err;
4a4d8108
AM
15731+ struct file *h_file;
15732+
15733+ err = 0;
15734+ h_file = au_hf_top(file);
15735+ if (h_file)
15736+ err = vfsub_flush(h_file, id);
15737+ return err;
15738+}
15739+
15740+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
15741+{
15742+ return au_do_flush(file, id, au_do_flush_nondir);
15743+}
15744+
15745+/* ---------------------------------------------------------------------- */
9dbd164d
AM
15746+/*
15747+ * read and write functions acquire [fdi]_rwsem once, but release before
15748+ * mmap_sem. This is because to stop a race condition between mmap(2).
acd2b654 15749+ * Releasing these aufs-rwsem should be safe, no branch-management (by keeping
9dbd164d
AM
15750+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
15751+ * read functions after [fdi]_rwsem are released, but it should be harmless.
15752+ */
4a4d8108 15753+
b912730e 15754+/* Callers should call au_read_post() or fput() in the end */
521ced18 15755+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc)
4a4d8108 15756+{
4a4d8108 15757+ struct file *h_file;
b912730e 15758+ int err;
1facf9fc 15759+
521ced18 15760+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, lsc);
b912730e
AM
15761+ if (!err) {
15762+ di_read_unlock(file->f_path.dentry, AuLock_IR);
15763+ h_file = au_hf_top(file);
15764+ get_file(h_file);
15765+ if (!keep_fi)
15766+ fi_read_unlock(file);
15767+ } else
15768+ h_file = ERR_PTR(err);
15769+
15770+ return h_file;
15771+}
15772+
15773+static void au_read_post(struct inode *inode, struct file *h_file)
15774+{
15775+ /* update without lock, I don't think it a problem */
15776+ fsstack_copy_attr_atime(inode, file_inode(h_file));
15777+ fput(h_file);
15778+}
15779+
15780+struct au_write_pre {
521ced18
JR
15781+ /* input */
15782+ unsigned int lsc;
15783+
15784+ /* output */
b912730e 15785+ blkcnt_t blks;
5afbbe0d 15786+ aufs_bindex_t btop;
b912730e
AM
15787+};
15788+
15789+/*
15790+ * return with iinfo is write-locked
15791+ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the
15792+ * end
15793+ */
15794+static struct file *au_write_pre(struct file *file, int do_ready,
15795+ struct au_write_pre *wpre)
15796+{
15797+ struct file *h_file;
15798+ struct dentry *dentry;
15799+ int err;
521ced18 15800+ unsigned int lsc;
b912730e
AM
15801+ struct au_pin pin;
15802+
521ced18
JR
15803+ lsc = 0;
15804+ if (wpre)
15805+ lsc = wpre->lsc;
15806+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, lsc);
b912730e 15807+ h_file = ERR_PTR(err);
dece6358
AM
15808+ if (unlikely(err))
15809+ goto out;
1facf9fc 15810+
b912730e
AM
15811+ dentry = file->f_path.dentry;
15812+ if (do_ready) {
15813+ err = au_ready_to_write(file, -1, &pin);
15814+ if (unlikely(err)) {
15815+ h_file = ERR_PTR(err);
15816+ di_write_unlock(dentry);
15817+ goto out_fi;
15818+ }
15819+ }
15820+
15821+ di_downgrade_lock(dentry, /*flags*/0);
15822+ if (wpre)
5afbbe0d 15823+ wpre->btop = au_fbtop(file);
4a4d8108 15824+ h_file = au_hf_top(file);
9dbd164d 15825+ get_file(h_file);
b912730e
AM
15826+ if (wpre)
15827+ wpre->blks = file_inode(h_file)->i_blocks;
15828+ if (do_ready)
15829+ au_unpin(&pin);
15830+ di_read_unlock(dentry, /*flags*/0);
15831+
15832+out_fi:
15833+ fi_write_unlock(file);
15834+out:
15835+ return h_file;
15836+}
15837+
15838+static void au_write_post(struct inode *inode, struct file *h_file,
15839+ struct au_write_pre *wpre, ssize_t written)
15840+{
15841+ struct inode *h_inode;
15842+
15843+ au_cpup_attr_timesizes(inode);
5afbbe0d 15844+ AuDebugOn(au_ibtop(inode) != wpre->btop);
b912730e
AM
15845+ h_inode = file_inode(h_file);
15846+ inode->i_mode = h_inode->i_mode;
15847+ ii_write_unlock(inode);
b912730e
AM
15848+ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */
15849+ if (written > 0)
5afbbe0d 15850+ au_fhsm_wrote(inode->i_sb, wpre->btop,
b912730e 15851+ /*force*/h_inode->i_blocks > wpre->blks);
1c60b727 15852+ fput(h_file);
b912730e
AM
15853+}
15854+
15855+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
15856+ loff_t *ppos)
15857+{
15858+ ssize_t err;
15859+ struct inode *inode;
15860+ struct file *h_file;
15861+ struct super_block *sb;
15862+
15863+ inode = file_inode(file);
15864+ sb = inode->i_sb;
15865+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
15866+
521ced18 15867+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
15868+ err = PTR_ERR(h_file);
15869+ if (IS_ERR(h_file))
15870+ goto out;
9dbd164d
AM
15871+
15872+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
15873+ err = vfsub_read_u(h_file, buf, count, ppos);
15874+ /* todo: necessary? */
15875+ /* file->f_ra = h_file->f_ra; */
b912730e 15876+ au_read_post(inode, h_file);
1308ab2a 15877+
4f0767ce 15878+out:
dece6358
AM
15879+ si_read_unlock(sb);
15880+ return err;
15881+}
1facf9fc 15882+
e49829fe
JR
15883+/*
15884+ * todo: very ugly
15885+ * it locks both of i_mutex and si_rwsem for read in safe.
15886+ * if the plink maintenance mode continues forever (that is the problem),
15887+ * may loop forever.
15888+ */
15889+static void au_mtx_and_read_lock(struct inode *inode)
15890+{
15891+ int err;
15892+ struct super_block *sb = inode->i_sb;
15893+
15894+ while (1) {
febd17d6 15895+ inode_lock(inode);
e49829fe
JR
15896+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
15897+ if (!err)
15898+ break;
febd17d6 15899+ inode_unlock(inode);
e49829fe
JR
15900+ si_read_lock(sb, AuLock_NOPLMW);
15901+ si_read_unlock(sb);
15902+ }
15903+}
15904+
4a4d8108
AM
15905+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
15906+ size_t count, loff_t *ppos)
dece6358 15907+{
4a4d8108 15908+ ssize_t err;
b912730e
AM
15909+ struct au_write_pre wpre;
15910+ struct inode *inode;
4a4d8108
AM
15911+ struct file *h_file;
15912+ char __user *buf = (char __user *)ubuf;
1facf9fc 15913+
b912730e 15914+ inode = file_inode(file);
e49829fe 15915+ au_mtx_and_read_lock(inode);
1facf9fc 15916+
521ced18 15917+ wpre.lsc = 0;
b912730e
AM
15918+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15919+ err = PTR_ERR(h_file);
15920+ if (IS_ERR(h_file))
9dbd164d 15921+ goto out;
9dbd164d 15922+
4a4d8108 15923+ err = vfsub_write_u(h_file, buf, count, ppos);
b912730e 15924+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 15925+
4f0767ce 15926+out:
b912730e 15927+ si_read_unlock(inode->i_sb);
febd17d6 15928+ inode_unlock(inode);
dece6358
AM
15929+ return err;
15930+}
1facf9fc 15931+
076b876e
AM
15932+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
15933+ struct iov_iter *iov_iter)
dece6358 15934+{
4a4d8108
AM
15935+ ssize_t err;
15936+ struct file *file;
076b876e 15937+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
1facf9fc 15938+
4a4d8108
AM
15939+ err = security_file_permission(h_file, rw);
15940+ if (unlikely(err))
15941+ goto out;
1facf9fc 15942+
4a4d8108 15943+ err = -ENOSYS;
076b876e 15944+ iter = NULL;
5527c038 15945+ if (rw == MAY_READ)
076b876e 15946+ iter = h_file->f_op->read_iter;
5527c038 15947+ else if (rw == MAY_WRITE)
076b876e 15948+ iter = h_file->f_op->write_iter;
076b876e
AM
15949+
15950+ file = kio->ki_filp;
15951+ kio->ki_filp = h_file;
15952+ if (iter) {
2cbb1c4b 15953+ lockdep_off();
076b876e
AM
15954+ err = iter(kio, iov_iter);
15955+ lockdep_on();
4a4d8108
AM
15956+ } else
15957+ /* currently there is no such fs */
15958+ WARN_ON_ONCE(1);
076b876e 15959+ kio->ki_filp = file;
1facf9fc 15960+
4f0767ce 15961+out:
dece6358
AM
15962+ return err;
15963+}
1facf9fc 15964+
076b876e 15965+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1facf9fc 15966+{
4a4d8108
AM
15967+ ssize_t err;
15968+ struct file *file, *h_file;
b912730e 15969+ struct inode *inode;
dece6358 15970+ struct super_block *sb;
1facf9fc 15971+
4a4d8108 15972+ file = kio->ki_filp;
b912730e
AM
15973+ inode = file_inode(file);
15974+ sb = inode->i_sb;
e49829fe 15975+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 15976+
521ced18 15977+ h_file = au_read_pre(file, /*keep_fi*/1, /*lsc*/0);
b912730e
AM
15978+ err = PTR_ERR(h_file);
15979+ if (IS_ERR(h_file))
15980+ goto out;
9dbd164d 15981+
5afbbe0d
AM
15982+ if (au_test_loopback_kthread()) {
15983+ au_warn_loopback(h_file->f_path.dentry->d_sb);
15984+ if (file->f_mapping != h_file->f_mapping) {
15985+ file->f_mapping = h_file->f_mapping;
15986+ smp_mb(); /* unnecessary? */
15987+ }
15988+ }
15989+ fi_read_unlock(file);
15990+
076b876e 15991+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
4a4d8108
AM
15992+ /* todo: necessary? */
15993+ /* file->f_ra = h_file->f_ra; */
b912730e 15994+ au_read_post(inode, h_file);
1facf9fc 15995+
4f0767ce 15996+out:
4a4d8108 15997+ si_read_unlock(sb);
1308ab2a 15998+ return err;
15999+}
1facf9fc 16000+
076b876e 16001+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1308ab2a 16002+{
4a4d8108 16003+ ssize_t err;
b912730e
AM
16004+ struct au_write_pre wpre;
16005+ struct inode *inode;
4a4d8108 16006+ struct file *file, *h_file;
1308ab2a 16007+
4a4d8108 16008+ file = kio->ki_filp;
b912730e 16009+ inode = file_inode(file);
e49829fe
JR
16010+ au_mtx_and_read_lock(inode);
16011+
521ced18 16012+ wpre.lsc = 0;
b912730e
AM
16013+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
16014+ err = PTR_ERR(h_file);
16015+ if (IS_ERR(h_file))
9dbd164d 16016+ goto out;
9dbd164d 16017+
076b876e 16018+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
b912730e 16019+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 16020+
4f0767ce 16021+out:
b912730e 16022+ si_read_unlock(inode->i_sb);
febd17d6 16023+ inode_unlock(inode);
dece6358 16024+ return err;
1facf9fc 16025+}
16026+
4a4d8108
AM
16027+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
16028+ struct pipe_inode_info *pipe, size_t len,
16029+ unsigned int flags)
1facf9fc 16030+{
4a4d8108
AM
16031+ ssize_t err;
16032+ struct file *h_file;
b912730e 16033+ struct inode *inode;
dece6358 16034+ struct super_block *sb;
1facf9fc 16035+
b912730e
AM
16036+ inode = file_inode(file);
16037+ sb = inode->i_sb;
e49829fe 16038+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 16039+
521ced18 16040+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
16041+ err = PTR_ERR(h_file);
16042+ if (IS_ERR(h_file))
dece6358 16043+ goto out;
1facf9fc 16044+
4a4d8108 16045+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
acd2b654 16046+ /* todo: necessary? */
4a4d8108 16047+ /* file->f_ra = h_file->f_ra; */
b912730e 16048+ au_read_post(inode, h_file);
1facf9fc 16049+
4f0767ce 16050+out:
4a4d8108 16051+ si_read_unlock(sb);
dece6358 16052+ return err;
1facf9fc 16053+}
16054+
4a4d8108
AM
16055+static ssize_t
16056+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
16057+ size_t len, unsigned int flags)
1facf9fc 16058+{
4a4d8108 16059+ ssize_t err;
b912730e
AM
16060+ struct au_write_pre wpre;
16061+ struct inode *inode;
076b876e 16062+ struct file *h_file;
1facf9fc 16063+
b912730e 16064+ inode = file_inode(file);
e49829fe 16065+ au_mtx_and_read_lock(inode);
9dbd164d 16066+
521ced18 16067+ wpre.lsc = 0;
b912730e
AM
16068+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
16069+ err = PTR_ERR(h_file);
16070+ if (IS_ERR(h_file))
9dbd164d 16071+ goto out;
9dbd164d 16072+
4a4d8108 16073+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
b912730e 16074+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 16075+
4f0767ce 16076+out:
b912730e 16077+ si_read_unlock(inode->i_sb);
febd17d6 16078+ inode_unlock(inode);
4a4d8108
AM
16079+ return err;
16080+}
1facf9fc 16081+
38d290e6
JR
16082+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
16083+ loff_t len)
16084+{
16085+ long err;
b912730e 16086+ struct au_write_pre wpre;
38d290e6
JR
16087+ struct inode *inode;
16088+ struct file *h_file;
16089+
b912730e 16090+ inode = file_inode(file);
38d290e6
JR
16091+ au_mtx_and_read_lock(inode);
16092+
521ced18 16093+ wpre.lsc = 0;
b912730e
AM
16094+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
16095+ err = PTR_ERR(h_file);
16096+ if (IS_ERR(h_file))
38d290e6 16097+ goto out;
38d290e6
JR
16098+
16099+ lockdep_off();
03673fb0 16100+ err = vfs_fallocate(h_file, mode, offset, len);
38d290e6 16101+ lockdep_on();
b912730e 16102+ au_write_post(inode, h_file, &wpre, /*written*/1);
38d290e6
JR
16103+
16104+out:
b912730e 16105+ si_read_unlock(inode->i_sb);
febd17d6 16106+ inode_unlock(inode);
38d290e6
JR
16107+ return err;
16108+}
16109+
521ced18
JR
16110+static ssize_t aufs_copy_file_range(struct file *src, loff_t src_pos,
16111+ struct file *dst, loff_t dst_pos,
16112+ size_t len, unsigned int flags)
16113+{
16114+ ssize_t err;
16115+ struct au_write_pre wpre;
16116+ enum { SRC, DST };
16117+ struct {
16118+ struct inode *inode;
16119+ struct file *h_file;
16120+ struct super_block *h_sb;
16121+ } a[2];
16122+#define a_src a[SRC]
16123+#define a_dst a[DST]
16124+
16125+ err = -EINVAL;
16126+ a_src.inode = file_inode(src);
16127+ if (unlikely(!S_ISREG(a_src.inode->i_mode)))
16128+ goto out;
16129+ a_dst.inode = file_inode(dst);
16130+ if (unlikely(!S_ISREG(a_dst.inode->i_mode)))
16131+ goto out;
16132+
16133+ au_mtx_and_read_lock(a_dst.inode);
16134+ /*
16135+ * in order to match the order in di_write_lock2_{child,parent}(),
acd2b654 16136+ * use f_path.dentry for this comparison.
521ced18
JR
16137+ */
16138+ if (src->f_path.dentry < dst->f_path.dentry) {
16139+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_1);
16140+ err = PTR_ERR(a_src.h_file);
16141+ if (IS_ERR(a_src.h_file))
16142+ goto out_si;
16143+
16144+ wpre.lsc = AuLsc_FI_2;
16145+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre);
16146+ err = PTR_ERR(a_dst.h_file);
16147+ if (IS_ERR(a_dst.h_file)) {
16148+ au_read_post(a_src.inode, a_src.h_file);
16149+ goto out_si;
16150+ }
16151+ } else {
16152+ wpre.lsc = AuLsc_FI_1;
16153+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre);
16154+ err = PTR_ERR(a_dst.h_file);
16155+ if (IS_ERR(a_dst.h_file))
16156+ goto out_si;
16157+
16158+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_2);
16159+ err = PTR_ERR(a_src.h_file);
16160+ if (IS_ERR(a_src.h_file)) {
16161+ au_write_post(a_dst.inode, a_dst.h_file, &wpre,
16162+ /*written*/0);
16163+ goto out_si;
16164+ }
16165+ }
16166+
16167+ err = -EXDEV;
16168+ a_src.h_sb = file_inode(a_src.h_file)->i_sb;
16169+ a_dst.h_sb = file_inode(a_dst.h_file)->i_sb;
16170+ if (unlikely(a_src.h_sb != a_dst.h_sb)) {
16171+ AuDbgFile(src);
16172+ AuDbgFile(dst);
16173+ goto out_file;
16174+ }
16175+
16176+ err = vfsub_copy_file_range(a_src.h_file, src_pos, a_dst.h_file,
16177+ dst_pos, len, flags);
16178+
16179+out_file:
16180+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, err);
16181+ fi_read_unlock(src);
16182+ au_read_post(a_src.inode, a_src.h_file);
16183+out_si:
16184+ si_read_unlock(a_dst.inode->i_sb);
16185+ inode_unlock(a_dst.inode);
16186+out:
16187+ return err;
16188+#undef a_src
16189+#undef a_dst
16190+}
16191+
4a4d8108
AM
16192+/* ---------------------------------------------------------------------- */
16193+
9dbd164d
AM
16194+/*
16195+ * The locking order around current->mmap_sem.
16196+ * - in most and regular cases
16197+ * file I/O syscall -- aufs_read() or something
16198+ * -- si_rwsem for read -- mmap_sem
16199+ * (Note that [fdi]i_rwsem are released before mmap_sem).
16200+ * - in mmap case
16201+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
acd2b654
AM
16202+ * This AB-BA order is definitely bad, but is not a problem since "si_rwsem for
16203+ * read" allows multiple processes to acquire it and [fdi]i_rwsem are not held
16204+ * in file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
9dbd164d
AM
16205+ * It means that when aufs acquires si_rwsem for write, the process should never
16206+ * acquire mmap_sem.
16207+ *
392086de 16208+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
16209+ * problem either since any directory is not able to be mmap-ed.
16210+ * The similar scenario is applied to aufs_readlink() too.
16211+ */
16212+
38d290e6 16213+#if 0 /* stop calling security_file_mmap() */
2dfbb274
AM
16214+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
16215+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
16216+
16217+static unsigned long au_arch_prot_conv(unsigned long flags)
16218+{
16219+ /* currently ppc64 only */
16220+#ifdef CONFIG_PPC64
16221+ /* cf. linux/arch/powerpc/include/asm/mman.h */
16222+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
16223+ return AuConv_VM_PROT(flags, SAO);
16224+#else
16225+ AuDebugOn(arch_calc_vm_prot_bits(-1));
16226+ return 0;
16227+#endif
16228+}
16229+
16230+static unsigned long au_prot_conv(unsigned long flags)
16231+{
16232+ return AuConv_VM_PROT(flags, READ)
16233+ | AuConv_VM_PROT(flags, WRITE)
16234+ | AuConv_VM_PROT(flags, EXEC)
16235+ | au_arch_prot_conv(flags);
16236+}
16237+
16238+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
16239+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
16240+
16241+static unsigned long au_flag_conv(unsigned long flags)
16242+{
16243+ return AuConv_VM_MAP(flags, GROWSDOWN)
16244+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
16245+ | AuConv_VM_MAP(flags, LOCKED);
16246+}
38d290e6 16247+#endif
2dfbb274 16248+
9dbd164d 16249+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 16250+{
4a4d8108 16251+ int err;
4a4d8108 16252+ const unsigned char wlock
9dbd164d 16253+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108 16254+ struct super_block *sb;
9dbd164d 16255+ struct file *h_file;
b912730e 16256+ struct inode *inode;
9dbd164d
AM
16257+
16258+ AuDbgVmRegion(file, vma);
1308ab2a 16259+
b912730e
AM
16260+ inode = file_inode(file);
16261+ sb = inode->i_sb;
9dbd164d 16262+ lockdep_off();
e49829fe 16263+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108 16264+
b912730e 16265+ h_file = au_write_pre(file, wlock, /*wpre*/NULL);
9dbd164d 16266+ lockdep_on();
b912730e
AM
16267+ err = PTR_ERR(h_file);
16268+ if (IS_ERR(h_file))
16269+ goto out;
1308ab2a 16270+
b912730e
AM
16271+ err = 0;
16272+ au_set_mmapped(file);
9dbd164d 16273+ au_vm_file_reset(vma, h_file);
38d290e6
JR
16274+ /*
16275+ * we cannot call security_mmap_file() here since it may acquire
16276+ * mmap_sem or i_mutex.
16277+ *
16278+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
16279+ * au_flag_conv(vma->vm_flags));
16280+ */
9dbd164d 16281+ if (!err)
521ced18 16282+ err = call_mmap(h_file, vma);
b912730e
AM
16283+ if (!err) {
16284+ au_vm_prfile_set(vma, file);
16285+ fsstack_copy_attr_atime(inode, file_inode(h_file));
16286+ goto out_fput; /* success */
16287+ }
2cbb1c4b
JR
16288+ au_unset_mmapped(file);
16289+ au_vm_file_reset(vma, file);
b912730e 16290+
2cbb1c4b 16291+out_fput:
9dbd164d 16292+ lockdep_off();
b912730e
AM
16293+ ii_write_unlock(inode);
16294+ lockdep_on();
16295+ fput(h_file);
4f0767ce 16296+out:
b912730e 16297+ lockdep_off();
9dbd164d
AM
16298+ si_read_unlock(sb);
16299+ lockdep_on();
16300+ AuTraceErr(err);
4a4d8108
AM
16301+ return err;
16302+}
16303+
16304+/* ---------------------------------------------------------------------- */
16305+
1e00d052
AM
16306+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
16307+ int datasync)
4a4d8108
AM
16308+{
16309+ int err;
b912730e 16310+ struct au_write_pre wpre;
4a4d8108
AM
16311+ struct inode *inode;
16312+ struct file *h_file;
4a4d8108
AM
16313+
16314+ err = 0; /* -EBADF; */ /* posix? */
16315+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
b912730e 16316+ goto out;
4a4d8108 16317+
b912730e
AM
16318+ inode = file_inode(file);
16319+ au_mtx_and_read_lock(inode);
16320+
521ced18 16321+ wpre.lsc = 0;
b912730e
AM
16322+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
16323+ err = PTR_ERR(h_file);
16324+ if (IS_ERR(h_file))
4a4d8108 16325+ goto out_unlock;
4a4d8108 16326+
53392da6 16327+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
b912730e 16328+ au_write_post(inode, h_file, &wpre, /*written*/0);
4a4d8108 16329+
4f0767ce 16330+out_unlock:
b912730e 16331+ si_read_unlock(inode->i_sb);
febd17d6 16332+ inode_unlock(inode);
b912730e 16333+out:
4a4d8108 16334+ return err;
dece6358
AM
16335+}
16336+
4a4d8108 16337+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 16338+{
4a4d8108
AM
16339+ int err;
16340+ struct file *h_file;
4a4d8108 16341+ struct super_block *sb;
1308ab2a 16342+
b912730e 16343+ sb = file->f_path.dentry->d_sb;
e49829fe 16344+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 16345+
521ced18 16346+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
16347+ err = PTR_ERR(h_file);
16348+ if (IS_ERR(h_file))
4a4d8108
AM
16349+ goto out;
16350+
523b37e3 16351+ if (h_file->f_op->fasync)
4a4d8108 16352+ err = h_file->f_op->fasync(fd, h_file, flag);
b912730e 16353+ fput(h_file); /* instead of au_read_post() */
1308ab2a 16354+
4f0767ce 16355+out:
4a4d8108 16356+ si_read_unlock(sb);
1308ab2a 16357+ return err;
dece6358 16358+}
4a4d8108 16359+
febd17d6
JR
16360+static int aufs_setfl(struct file *file, unsigned long arg)
16361+{
16362+ int err;
16363+ struct file *h_file;
16364+ struct super_block *sb;
16365+
16366+ sb = file->f_path.dentry->d_sb;
16367+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
16368+
521ced18 16369+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
febd17d6
JR
16370+ err = PTR_ERR(h_file);
16371+ if (IS_ERR(h_file))
16372+ goto out;
16373+
1c60b727
AM
16374+ /* stop calling h_file->fasync */
16375+ arg |= vfsub_file_flags(file) & FASYNC;
febd17d6
JR
16376+ err = setfl(/*unused fd*/-1, h_file, arg);
16377+ fput(h_file); /* instead of au_read_post() */
16378+
16379+out:
16380+ si_read_unlock(sb);
16381+ return err;
16382+}
16383+
4a4d8108
AM
16384+/* ---------------------------------------------------------------------- */
16385+
16386+/* no one supports this operation, currently */
16387+#if 0
16388+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
2000de60 16389+ size_t len, loff_t *pos, int more)
4a4d8108
AM
16390+{
16391+}
16392+#endif
16393+
16394+/* ---------------------------------------------------------------------- */
16395+
16396+const struct file_operations aufs_file_fop = {
16397+ .owner = THIS_MODULE,
2cbb1c4b 16398+
027c5e7a 16399+ .llseek = default_llseek,
4a4d8108
AM
16400+
16401+ .read = aufs_read,
16402+ .write = aufs_write,
076b876e
AM
16403+ .read_iter = aufs_read_iter,
16404+ .write_iter = aufs_write_iter,
16405+
4a4d8108
AM
16406+#ifdef CONFIG_AUFS_POLL
16407+ .poll = aufs_poll,
16408+#endif
16409+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 16410+#ifdef CONFIG_COMPAT
c2b27bf2 16411+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 16412+#endif
4a4d8108
AM
16413+ .mmap = aufs_mmap,
16414+ .open = aufs_open_nondir,
16415+ .flush = aufs_flush_nondir,
16416+ .release = aufs_release_nondir,
16417+ .fsync = aufs_fsync_nondir,
4a4d8108
AM
16418+ .fasync = aufs_fasync,
16419+ /* .sendpage = aufs_sendpage, */
febd17d6 16420+ .setfl = aufs_setfl,
4a4d8108
AM
16421+ .splice_write = aufs_splice_write,
16422+ .splice_read = aufs_splice_read,
16423+#if 0
16424+ .aio_splice_write = aufs_aio_splice_write,
38d290e6 16425+ .aio_splice_read = aufs_aio_splice_read,
4a4d8108 16426+#endif
521ced18
JR
16427+ .fallocate = aufs_fallocate,
16428+ .copy_file_range = aufs_copy_file_range
4a4d8108 16429+};
7f207e10
AM
16430diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
16431--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 16432+++ linux/fs/aufs/fstype.h 2019-03-05 12:13:00.139224339 +0100
062440b3
AM
16433@@ -0,0 +1,401 @@
16434+/* SPDX-License-Identifier: GPL-2.0 */
4a4d8108 16435+/*
ba1aed25 16436+ * Copyright (C) 2005-2019 Junjiro R. Okajima
4a4d8108
AM
16437+ *
16438+ * This program, aufs is free software; you can redistribute it and/or modify
16439+ * it under the terms of the GNU General Public License as published by
16440+ * the Free Software Foundation; either version 2 of the License, or
16441+ * (at your option) any later version.
16442+ *
16443+ * This program is distributed in the hope that it will be useful,
16444+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16445+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16446+ * GNU General Public License for more details.
16447+ *
16448+ * You should have received a copy of the GNU General Public License
523b37e3 16449+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16450+ */
16451+
16452+/*
16453+ * judging filesystem type
16454+ */
16455+
16456+#ifndef __AUFS_FSTYPE_H__
16457+#define __AUFS_FSTYPE_H__
16458+
16459+#ifdef __KERNEL__
16460+
16461+#include <linux/fs.h>
16462+#include <linux/magic.h>
b912730e 16463+#include <linux/nfs_fs.h>
b95c5147 16464+#include <linux/romfs_fs.h>
4a4d8108
AM
16465+
16466+static inline int au_test_aufs(struct super_block *sb)
16467+{
16468+ return sb->s_magic == AUFS_SUPER_MAGIC;
16469+}
16470+
16471+static inline const char *au_sbtype(struct super_block *sb)
16472+{
16473+ return sb->s_type->name;
16474+}
1308ab2a 16475+
16476+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
16477+{
f0c0a007 16478+#if IS_ENABLED(CONFIG_ISO9660_FS)
2000de60 16479+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
16480+#else
16481+ return 0;
16482+#endif
16483+}
16484+
1308ab2a 16485+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 16486+{
f0c0a007 16487+#if IS_ENABLED(CONFIG_ROMFS_FS)
2000de60 16488+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
16489+#else
16490+ return 0;
16491+#endif
16492+}
16493+
1308ab2a 16494+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 16495+{
f0c0a007 16496+#if IS_ENABLED(CONFIG_CRAMFS)
1308ab2a 16497+ return sb->s_magic == CRAMFS_MAGIC;
16498+#endif
16499+ return 0;
16500+}
16501+
16502+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
16503+{
f0c0a007 16504+#if IS_ENABLED(CONFIG_NFS_FS)
1308ab2a 16505+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
16506+#else
16507+ return 0;
16508+#endif
16509+}
16510+
1308ab2a 16511+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 16512+{
f0c0a007 16513+#if IS_ENABLED(CONFIG_FUSE_FS)
1308ab2a 16514+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
16515+#else
16516+ return 0;
16517+#endif
16518+}
16519+
1308ab2a 16520+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 16521+{
f0c0a007 16522+#if IS_ENABLED(CONFIG_XFS_FS)
1308ab2a 16523+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
16524+#else
16525+ return 0;
16526+#endif
16527+}
16528+
1308ab2a 16529+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 16530+{
1308ab2a 16531+#ifdef CONFIG_TMPFS
16532+ return sb->s_magic == TMPFS_MAGIC;
16533+#else
16534+ return 0;
dece6358 16535+#endif
dece6358
AM
16536+}
16537+
1308ab2a 16538+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 16539+{
f0c0a007 16540+#if IS_ENABLED(CONFIG_ECRYPT_FS)
1308ab2a 16541+ return !strcmp(au_sbtype(sb), "ecryptfs");
16542+#else
16543+ return 0;
16544+#endif
1facf9fc 16545+}
16546+
1308ab2a 16547+static inline int au_test_ramfs(struct super_block *sb)
16548+{
16549+ return sb->s_magic == RAMFS_MAGIC;
16550+}
16551+
16552+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
16553+{
f0c0a007 16554+#if IS_ENABLED(CONFIG_UBIFS_FS)
1308ab2a 16555+ return sb->s_magic == UBIFS_SUPER_MAGIC;
16556+#else
16557+ return 0;
16558+#endif
16559+}
16560+
16561+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
16562+{
16563+#ifdef CONFIG_PROC_FS
16564+ return sb->s_magic == PROC_SUPER_MAGIC;
16565+#else
16566+ return 0;
16567+#endif
16568+}
16569+
16570+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
16571+{
16572+#ifdef CONFIG_SYSFS
16573+ return sb->s_magic == SYSFS_MAGIC;
16574+#else
16575+ return 0;
16576+#endif
16577+}
16578+
16579+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
16580+{
f0c0a007 16581+#if IS_ENABLED(CONFIG_CONFIGFS_FS)
1308ab2a 16582+ return sb->s_magic == CONFIGFS_MAGIC;
16583+#else
16584+ return 0;
16585+#endif
16586+}
16587+
16588+static inline int au_test_minix(struct super_block *sb __maybe_unused)
16589+{
f0c0a007 16590+#if IS_ENABLED(CONFIG_MINIX_FS)
1308ab2a 16591+ return sb->s_magic == MINIX3_SUPER_MAGIC
16592+ || sb->s_magic == MINIX2_SUPER_MAGIC
16593+ || sb->s_magic == MINIX2_SUPER_MAGIC2
16594+ || sb->s_magic == MINIX_SUPER_MAGIC
16595+ || sb->s_magic == MINIX_SUPER_MAGIC2;
16596+#else
16597+ return 0;
16598+#endif
16599+}
16600+
1308ab2a 16601+static inline int au_test_fat(struct super_block *sb __maybe_unused)
16602+{
f0c0a007 16603+#if IS_ENABLED(CONFIG_FAT_FS)
1308ab2a 16604+ return sb->s_magic == MSDOS_SUPER_MAGIC;
16605+#else
16606+ return 0;
16607+#endif
16608+}
16609+
16610+static inline int au_test_msdos(struct super_block *sb)
16611+{
16612+ return au_test_fat(sb);
16613+}
16614+
16615+static inline int au_test_vfat(struct super_block *sb)
16616+{
16617+ return au_test_fat(sb);
16618+}
16619+
16620+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
16621+{
16622+#ifdef CONFIG_SECURITYFS
16623+ return sb->s_magic == SECURITYFS_MAGIC;
16624+#else
16625+ return 0;
16626+#endif
16627+}
16628+
16629+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
16630+{
f0c0a007 16631+#if IS_ENABLED(CONFIG_SQUASHFS)
1308ab2a 16632+ return sb->s_magic == SQUASHFS_MAGIC;
16633+#else
16634+ return 0;
16635+#endif
16636+}
16637+
16638+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
16639+{
f0c0a007 16640+#if IS_ENABLED(CONFIG_BTRFS_FS)
1308ab2a 16641+ return sb->s_magic == BTRFS_SUPER_MAGIC;
16642+#else
16643+ return 0;
16644+#endif
16645+}
16646+
16647+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
16648+{
f0c0a007 16649+#if IS_ENABLED(CONFIG_XENFS)
1308ab2a 16650+ return sb->s_magic == XENFS_SUPER_MAGIC;
16651+#else
16652+ return 0;
16653+#endif
16654+}
16655+
16656+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
16657+{
16658+#ifdef CONFIG_DEBUG_FS
16659+ return sb->s_magic == DEBUGFS_MAGIC;
16660+#else
16661+ return 0;
16662+#endif
16663+}
16664+
16665+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
16666+{
f0c0a007 16667+#if IS_ENABLED(CONFIG_NILFS)
1308ab2a 16668+ return sb->s_magic == NILFS_SUPER_MAGIC;
16669+#else
16670+ return 0;
16671+#endif
16672+}
16673+
4a4d8108
AM
16674+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
16675+{
f0c0a007 16676+#if IS_ENABLED(CONFIG_HFSPLUS_FS)
4a4d8108
AM
16677+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
16678+#else
16679+ return 0;
16680+#endif
16681+}
16682+
1308ab2a 16683+/* ---------------------------------------------------------------------- */
16684+/*
16685+ * they can't be an aufs branch.
16686+ */
16687+static inline int au_test_fs_unsuppoted(struct super_block *sb)
16688+{
16689+ return
16690+#ifndef CONFIG_AUFS_BR_RAMFS
16691+ au_test_ramfs(sb) ||
16692+#endif
16693+ au_test_procfs(sb)
16694+ || au_test_sysfs(sb)
16695+ || au_test_configfs(sb)
16696+ || au_test_debugfs(sb)
16697+ || au_test_securityfs(sb)
16698+ || au_test_xenfs(sb)
16699+ || au_test_ecryptfs(sb)
16700+ /* || !strcmp(au_sbtype(sb), "unionfs") */
16701+ || au_test_aufs(sb); /* will be supported in next version */
16702+}
16703+
1308ab2a 16704+static inline int au_test_fs_remote(struct super_block *sb)
16705+{
16706+ return !au_test_tmpfs(sb)
16707+#ifdef CONFIG_AUFS_BR_RAMFS
16708+ && !au_test_ramfs(sb)
16709+#endif
16710+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
16711+}
16712+
16713+/* ---------------------------------------------------------------------- */
16714+
16715+/*
16716+ * Note: these functions (below) are created after reading ->getattr() in all
16717+ * filesystems under linux/fs. it means we have to do so in every update...
16718+ */
16719+
16720+/*
16721+ * some filesystems require getattr to refresh the inode attributes before
16722+ * referencing.
16723+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
16724+ * and leave the work for d_revalidate()
16725+ */
16726+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
16727+{
16728+ return au_test_nfs(sb)
16729+ || au_test_fuse(sb)
1308ab2a 16730+ /* || au_test_btrfs(sb) */ /* untested */
1308ab2a 16731+ ;
16732+}
16733+
16734+/*
16735+ * filesystems which don't maintain i_size or i_blocks.
16736+ */
16737+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
16738+{
16739+ return au_test_xfs(sb)
4a4d8108
AM
16740+ || au_test_btrfs(sb)
16741+ || au_test_ubifs(sb)
16742+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 16743+ /* || au_test_minix(sb) */ /* untested */
16744+ ;
16745+}
16746+
16747+/*
16748+ * filesystems which don't store the correct value in some of their inode
16749+ * attributes.
16750+ */
16751+static inline int au_test_fs_bad_iattr(struct super_block *sb)
16752+{
16753+ return au_test_fs_bad_iattr_size(sb)
1308ab2a 16754+ || au_test_fat(sb)
16755+ || au_test_msdos(sb)
16756+ || au_test_vfat(sb);
1facf9fc 16757+}
16758+
16759+/* they don't check i_nlink in link(2) */
16760+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
16761+{
16762+ return au_test_tmpfs(sb)
16763+#ifdef CONFIG_AUFS_BR_RAMFS
16764+ || au_test_ramfs(sb)
16765+#endif
4a4d8108 16766+ || au_test_ubifs(sb)
4a4d8108 16767+ || au_test_hfsplus(sb);
1facf9fc 16768+}
16769+
16770+/*
16771+ * filesystems which sets S_NOATIME and S_NOCMTIME.
16772+ */
16773+static inline int au_test_fs_notime(struct super_block *sb)
16774+{
16775+ return au_test_nfs(sb)
16776+ || au_test_fuse(sb)
dece6358 16777+ || au_test_ubifs(sb)
1facf9fc 16778+ ;
16779+}
16780+
1facf9fc 16781+/* temporary support for i#1 in cramfs */
16782+static inline int au_test_fs_unique_ino(struct inode *inode)
16783+{
16784+ if (au_test_cramfs(inode->i_sb))
16785+ return inode->i_ino != 1;
16786+ return 1;
16787+}
16788+
16789+/* ---------------------------------------------------------------------- */
16790+
16791+/*
16792+ * the filesystem where the xino files placed must support i/o after unlink and
16793+ * maintain i_size and i_blocks.
16794+ */
16795+static inline int au_test_fs_bad_xino(struct super_block *sb)
16796+{
16797+ return au_test_fs_remote(sb)
16798+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 16799+ /* don't want unnecessary work for xino */
16800+ || au_test_aufs(sb)
1308ab2a 16801+ || au_test_ecryptfs(sb)
16802+ || au_test_nilfs(sb);
1facf9fc 16803+}
16804+
16805+static inline int au_test_fs_trunc_xino(struct super_block *sb)
16806+{
16807+ return au_test_tmpfs(sb)
16808+ || au_test_ramfs(sb);
16809+}
16810+
16811+/*
16812+ * test if the @sb is real-readonly.
16813+ */
16814+static inline int au_test_fs_rr(struct super_block *sb)
16815+{
16816+ return au_test_squashfs(sb)
16817+ || au_test_iso9660(sb)
16818+ || au_test_cramfs(sb)
16819+ || au_test_romfs(sb);
16820+}
16821+
b912730e
AM
16822+/*
16823+ * test if the @inode is nfs with 'noacl' option
2121bcd9 16824+ * NFS always sets SB_POSIXACL regardless its mount option 'noacl.'
b912730e
AM
16825+ */
16826+static inline int au_test_nfs_noacl(struct inode *inode)
16827+{
16828+ return au_test_nfs(inode->i_sb)
16829+ /* && IS_POSIXACL(inode) */
16830+ && !nfs_server_capable(inode, NFS_CAP_ACLS);
16831+}
16832+
1facf9fc 16833+#endif /* __KERNEL__ */
16834+#endif /* __AUFS_FSTYPE_H__ */
8b6a4947
AM
16835diff -urN /usr/share/empty/fs/aufs/hbl.h linux/fs/aufs/hbl.h
16836--- /usr/share/empty/fs/aufs/hbl.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 16837+++ linux/fs/aufs/hbl.h 2019-03-05 12:13:00.139224339 +0100
062440b3
AM
16838@@ -0,0 +1,65 @@
16839+/* SPDX-License-Identifier: GPL-2.0 */
8b6a4947 16840+/*
ba1aed25 16841+ * Copyright (C) 2017-2019 Junjiro R. Okajima
8b6a4947
AM
16842+ *
16843+ * This program, aufs is free software; you can redistribute it and/or modify
16844+ * it under the terms of the GNU General Public License as published by
16845+ * the Free Software Foundation; either version 2 of the License, or
16846+ * (at your option) any later version.
16847+ *
16848+ * This program is distributed in the hope that it will be useful,
16849+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16850+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16851+ * GNU General Public License for more details.
16852+ *
16853+ * You should have received a copy of the GNU General Public License
16854+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16855+ */
16856+
16857+/*
16858+ * helpers for hlist_bl.h
16859+ */
16860+
16861+#ifndef __AUFS_HBL_H__
16862+#define __AUFS_HBL_H__
16863+
16864+#ifdef __KERNEL__
16865+
16866+#include <linux/list_bl.h>
16867+
16868+static inline void au_hbl_add(struct hlist_bl_node *node,
16869+ struct hlist_bl_head *hbl)
16870+{
16871+ hlist_bl_lock(hbl);
16872+ hlist_bl_add_head(node, hbl);
16873+ hlist_bl_unlock(hbl);
16874+}
16875+
16876+static inline void au_hbl_del(struct hlist_bl_node *node,
16877+ struct hlist_bl_head *hbl)
16878+{
16879+ hlist_bl_lock(hbl);
16880+ hlist_bl_del(node);
16881+ hlist_bl_unlock(hbl);
16882+}
16883+
16884+#define au_hbl_for_each(pos, head) \
16885+ for (pos = hlist_bl_first(head); \
16886+ pos; \
16887+ pos = pos->next)
16888+
16889+static inline unsigned long au_hbl_count(struct hlist_bl_head *hbl)
16890+{
16891+ unsigned long cnt;
16892+ struct hlist_bl_node *pos;
16893+
16894+ cnt = 0;
16895+ hlist_bl_lock(hbl);
16896+ au_hbl_for_each(pos, hbl)
16897+ cnt++;
16898+ hlist_bl_unlock(hbl);
16899+ return cnt;
16900+}
16901+
16902+#endif /* __KERNEL__ */
16903+#endif /* __AUFS_HBL_H__ */
7f207e10
AM
16904diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
16905--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 16906+++ linux/fs/aufs/hfsnotify.c 2019-03-05 12:13:00.139224339 +0100
acd2b654 16907@@ -0,0 +1,289 @@
cd7a4cd9 16908+// SPDX-License-Identifier: GPL-2.0
1facf9fc 16909+/*
ba1aed25 16910+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 16911+ *
16912+ * This program, aufs is free software; you can redistribute it and/or modify
16913+ * it under the terms of the GNU General Public License as published by
16914+ * the Free Software Foundation; either version 2 of the License, or
16915+ * (at your option) any later version.
dece6358
AM
16916+ *
16917+ * This program is distributed in the hope that it will be useful,
16918+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16919+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16920+ * GNU General Public License for more details.
16921+ *
16922+ * You should have received a copy of the GNU General Public License
523b37e3 16923+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 16924+ */
16925+
16926+/*
4a4d8108 16927+ * fsnotify for the lower directories
1facf9fc 16928+ */
16929+
16930+#include "aufs.h"
16931+
4a4d8108
AM
16932+/* FS_IN_IGNORED is unnecessary */
16933+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
16934+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 16935+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 16936+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 16937+
0c5527e5 16938+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 16939+{
0c5527e5
AM
16940+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
16941+ hn_mark);
5afbbe0d 16942+ /* AuDbg("here\n"); */
1c60b727 16943+ au_cache_free_hnotify(hn);
8b6a4947 16944+ smp_mb__before_atomic(); /* for atomic64_dec */
1716fcea
AM
16945+ if (atomic64_dec_and_test(&au_hfsn_ifree))
16946+ wake_up(&au_hfsn_wq);
4a4d8108 16947+}
1facf9fc 16948+
027c5e7a 16949+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 16950+{
1716fcea 16951+ int err;
027c5e7a
AM
16952+ struct au_hnotify *hn;
16953+ struct super_block *sb;
16954+ struct au_branch *br;
0c5527e5 16955+ struct fsnotify_mark *mark;
027c5e7a 16956+ aufs_bindex_t bindex;
1facf9fc 16957+
027c5e7a
AM
16958+ hn = hinode->hi_notify;
16959+ sb = hn->hn_aufs_inode->i_sb;
16960+ bindex = au_br_index(sb, hinode->hi_id);
16961+ br = au_sbr(sb, bindex);
1716fcea
AM
16962+ AuDebugOn(!br->br_hfsn);
16963+
0c5527e5 16964+ mark = &hn->hn_mark;
ffa93bbd 16965+ fsnotify_init_mark(mark, br->br_hfsn->hfsn_group);
0c5527e5 16966+ mark->mask = AuHfsnMask;
7f207e10
AM
16967+ /*
16968+ * by udba rename or rmdir, aufs assign a new inode to the known
16969+ * h_inode, so specify 1 to allow dups.
16970+ */
c1595e42 16971+ lockdep_off();
acd2b654 16972+ err = fsnotify_add_inode_mark(mark, hinode->hi_inode, /*allow_dups*/1);
c1595e42 16973+ lockdep_on();
1716fcea
AM
16974+
16975+ return err;
1facf9fc 16976+}
16977+
7eafdf33 16978+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 16979+{
0c5527e5 16980+ struct fsnotify_mark *mark;
7eafdf33 16981+ unsigned long long ull;
1716fcea 16982+ struct fsnotify_group *group;
7eafdf33
AM
16983+
16984+ ull = atomic64_inc_return(&au_hfsn_ifree);
16985+ BUG_ON(!ull);
953406b4 16986+
0c5527e5 16987+ mark = &hn->hn_mark;
1716fcea
AM
16988+ spin_lock(&mark->lock);
16989+ group = mark->group;
16990+ fsnotify_get_group(group);
16991+ spin_unlock(&mark->lock);
c1595e42 16992+ lockdep_off();
1716fcea 16993+ fsnotify_destroy_mark(mark, group);
5afbbe0d 16994+ fsnotify_put_mark(mark);
1716fcea 16995+ fsnotify_put_group(group);
c1595e42 16996+ lockdep_on();
7f207e10 16997+
7eafdf33
AM
16998+ /* free hn by myself */
16999+ return 0;
1facf9fc 17000+}
17001+
17002+/* ---------------------------------------------------------------------- */
17003+
4a4d8108 17004+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 17005+{
0c5527e5 17006+ struct fsnotify_mark *mark;
1facf9fc 17007+
0c5527e5
AM
17008+ mark = &hinode->hi_notify->hn_mark;
17009+ spin_lock(&mark->lock);
1facf9fc 17010+ if (do_set) {
0c5527e5
AM
17011+ AuDebugOn(mark->mask & AuHfsnMask);
17012+ mark->mask |= AuHfsnMask;
1facf9fc 17013+ } else {
0c5527e5
AM
17014+ AuDebugOn(!(mark->mask & AuHfsnMask));
17015+ mark->mask &= ~AuHfsnMask;
1facf9fc 17016+ }
0c5527e5 17017+ spin_unlock(&mark->lock);
4a4d8108 17018+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 17019+}
17020+
4a4d8108 17021+/* ---------------------------------------------------------------------- */
1facf9fc 17022+
4a4d8108
AM
17023+/* #define AuDbgHnotify */
17024+#ifdef AuDbgHnotify
17025+static char *au_hfsn_name(u32 mask)
17026+{
17027+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
17028+#define test_ret(flag) \
17029+ do { \
17030+ if (mask & flag) \
17031+ return #flag; \
17032+ } while (0)
4a4d8108
AM
17033+ test_ret(FS_ACCESS);
17034+ test_ret(FS_MODIFY);
17035+ test_ret(FS_ATTRIB);
17036+ test_ret(FS_CLOSE_WRITE);
17037+ test_ret(FS_CLOSE_NOWRITE);
17038+ test_ret(FS_OPEN);
17039+ test_ret(FS_MOVED_FROM);
17040+ test_ret(FS_MOVED_TO);
17041+ test_ret(FS_CREATE);
17042+ test_ret(FS_DELETE);
17043+ test_ret(FS_DELETE_SELF);
17044+ test_ret(FS_MOVE_SELF);
17045+ test_ret(FS_UNMOUNT);
17046+ test_ret(FS_Q_OVERFLOW);
17047+ test_ret(FS_IN_IGNORED);
b912730e 17048+ test_ret(FS_ISDIR);
4a4d8108
AM
17049+ test_ret(FS_IN_ONESHOT);
17050+ test_ret(FS_EVENT_ON_CHILD);
17051+ return "";
17052+#undef test_ret
17053+#else
17054+ return "??";
17055+#endif
1facf9fc 17056+}
4a4d8108 17057+#endif
1facf9fc 17058+
17059+/* ---------------------------------------------------------------------- */
17060+
1716fcea
AM
17061+static void au_hfsn_free_group(struct fsnotify_group *group)
17062+{
17063+ struct au_br_hfsnotify *hfsn = group->private;
17064+
5afbbe0d 17065+ /* AuDbg("here\n"); */
9f237c51 17066+ au_kfree_try_rcu(hfsn);
1716fcea
AM
17067+}
17068+
4a4d8108 17069+static int au_hfsn_handle_event(struct fsnotify_group *group,
fb47a38f 17070+ struct inode *inode,
a2654f78 17071+ u32 mask, const void *data, int data_type,
ffa93bbd
AM
17072+ const unsigned char *file_name, u32 cookie,
17073+ struct fsnotify_iter_info *iter_info)
1facf9fc 17074+{
17075+ int err;
4a4d8108
AM
17076+ struct au_hnotify *hnotify;
17077+ struct inode *h_dir, *h_inode;
fb47a38f 17078+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
cd7a4cd9 17079+ struct fsnotify_mark *inode_mark;
4a4d8108 17080+
fb47a38f 17081+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 17082+
17083+ err = 0;
0c5527e5 17084+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108 17085+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 17086+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 17087+ goto out;
1facf9fc 17088+
fb47a38f
JR
17089+ h_dir = inode;
17090+ h_inode = NULL;
4a4d8108 17091+#ifdef AuDbgHnotify
392086de 17092+ au_debug_on();
4a4d8108
AM
17093+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
17094+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
17095+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
17096+ h_dir->i_ino, mask, au_hfsn_name(mask),
17097+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
17098+ /* WARN_ON(1); */
1facf9fc 17099+ }
392086de 17100+ au_debug_off();
1facf9fc 17101+#endif
4a4d8108 17102+
cd7a4cd9 17103+ inode_mark = fsnotify_iter_inode_mark(iter_info);
0c5527e5
AM
17104+ AuDebugOn(!inode_mark);
17105+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
17106+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 17107+
4a4d8108
AM
17108+out:
17109+ return err;
17110+}
1facf9fc 17111+
4a4d8108 17112+static struct fsnotify_ops au_hfsn_ops = {
1716fcea 17113+ .handle_event = au_hfsn_handle_event,
ffa93bbd
AM
17114+ .free_group_priv = au_hfsn_free_group,
17115+ .free_mark = au_hfsn_free_mark
4a4d8108
AM
17116+};
17117+
17118+/* ---------------------------------------------------------------------- */
17119+
027c5e7a
AM
17120+static void au_hfsn_fin_br(struct au_branch *br)
17121+{
1716fcea 17122+ struct au_br_hfsnotify *hfsn;
027c5e7a 17123+
1716fcea 17124+ hfsn = br->br_hfsn;
c1595e42
JR
17125+ if (hfsn) {
17126+ lockdep_off();
1716fcea 17127+ fsnotify_put_group(hfsn->hfsn_group);
c1595e42
JR
17128+ lockdep_on();
17129+ }
027c5e7a
AM
17130+}
17131+
1716fcea 17132+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
17133+{
17134+ int err;
1716fcea
AM
17135+ struct fsnotify_group *group;
17136+ struct au_br_hfsnotify *hfsn;
1facf9fc 17137+
4a4d8108 17138+ err = 0;
1716fcea
AM
17139+ br->br_hfsn = NULL;
17140+ if (!au_br_hnotifyable(perm))
027c5e7a 17141+ goto out;
027c5e7a 17142+
1716fcea
AM
17143+ err = -ENOMEM;
17144+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
17145+ if (unlikely(!hfsn))
027c5e7a
AM
17146+ goto out;
17147+
1716fcea
AM
17148+ err = 0;
17149+ group = fsnotify_alloc_group(&au_hfsn_ops);
17150+ if (IS_ERR(group)) {
17151+ err = PTR_ERR(group);
0c5527e5 17152+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 17153+ goto out_hfsn;
4a4d8108 17154+ }
1facf9fc 17155+
1716fcea
AM
17156+ group->private = hfsn;
17157+ hfsn->hfsn_group = group;
17158+ br->br_hfsn = hfsn;
17159+ goto out; /* success */
17160+
17161+out_hfsn:
9f237c51 17162+ au_kfree_try_rcu(hfsn);
027c5e7a 17163+out:
1716fcea
AM
17164+ return err;
17165+}
17166+
17167+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
17168+{
17169+ int err;
17170+
17171+ err = 0;
17172+ if (!br->br_hfsn)
17173+ err = au_hfsn_init_br(br, perm);
17174+
1facf9fc 17175+ return err;
17176+}
17177+
7eafdf33
AM
17178+/* ---------------------------------------------------------------------- */
17179+
17180+static void au_hfsn_fin(void)
17181+{
17182+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
17183+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
17184+}
17185+
4a4d8108
AM
17186+const struct au_hnotify_op au_hnotify_op = {
17187+ .ctl = au_hfsn_ctl,
17188+ .alloc = au_hfsn_alloc,
17189+ .free = au_hfsn_free,
1facf9fc 17190+
7eafdf33
AM
17191+ .fin = au_hfsn_fin,
17192+
027c5e7a
AM
17193+ .reset_br = au_hfsn_reset_br,
17194+ .fin_br = au_hfsn_fin_br,
17195+ .init_br = au_hfsn_init_br
4a4d8108 17196+};
7f207e10
AM
17197diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
17198--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 17199+++ linux/fs/aufs/hfsplus.c 2019-03-05 12:13:00.139224339 +0100
acd2b654 17200@@ -0,0 +1,60 @@
cd7a4cd9 17201+// SPDX-License-Identifier: GPL-2.0
4a4d8108 17202+/*
ba1aed25 17203+ * Copyright (C) 2010-2019 Junjiro R. Okajima
4a4d8108
AM
17204+ *
17205+ * This program, aufs is free software; you can redistribute it and/or modify
17206+ * it under the terms of the GNU General Public License as published by
17207+ * the Free Software Foundation; either version 2 of the License, or
17208+ * (at your option) any later version.
17209+ *
17210+ * This program is distributed in the hope that it will be useful,
17211+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17213+ * GNU General Public License for more details.
17214+ *
17215+ * You should have received a copy of the GNU General Public License
523b37e3 17216+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 17217+ */
1facf9fc 17218+
4a4d8108 17219+/*
acd2b654 17220+ * special support for filesystems which acquires an inode mutex
4a4d8108
AM
17221+ * at final closing a file, eg, hfsplus.
17222+ *
17223+ * This trick is very simple and stupid, just to open the file before really
acd2b654 17224+ * necessary open to tell hfsplus that this is not the final closing.
4a4d8108
AM
17225+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
17226+ * and au_h_open_post() after releasing it.
17227+ */
1facf9fc 17228+
4a4d8108 17229+#include "aufs.h"
1facf9fc 17230+
392086de
AM
17231+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
17232+ int force_wr)
4a4d8108
AM
17233+{
17234+ struct file *h_file;
17235+ struct dentry *h_dentry;
1facf9fc 17236+
4a4d8108
AM
17237+ h_dentry = au_h_dptr(dentry, bindex);
17238+ AuDebugOn(!h_dentry);
5527c038 17239+ AuDebugOn(d_is_negative(h_dentry));
4a4d8108
AM
17240+
17241+ h_file = NULL;
17242+ if (au_test_hfsplus(h_dentry->d_sb)
7e9cd9fe 17243+ && d_is_reg(h_dentry))
4a4d8108
AM
17244+ h_file = au_h_open(dentry, bindex,
17245+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 17246+ /*file*/NULL, force_wr);
4a4d8108 17247+ return h_file;
1facf9fc 17248+}
17249+
4a4d8108
AM
17250+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
17251+ struct file *h_file)
17252+{
acd2b654
AM
17253+ struct au_branch *br;
17254+
4a4d8108
AM
17255+ if (h_file) {
17256+ fput(h_file);
acd2b654
AM
17257+ br = au_sbr(dentry->d_sb, bindex);
17258+ au_lcnt_dec(&br->br_nfiles);
4a4d8108
AM
17259+ }
17260+}
7f207e10
AM
17261diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
17262--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
17263+++ linux/fs/aufs/hnotify.c 2019-05-06 09:03:04.816810402 +0200
17264@@ -0,0 +1,721 @@
cd7a4cd9 17265+// SPDX-License-Identifier: GPL-2.0
e49829fe 17266+/*
ba1aed25 17267+ * Copyright (C) 2005-2019 Junjiro R. Okajima
e49829fe
JR
17268+ *
17269+ * This program, aufs is free software; you can redistribute it and/or modify
17270+ * it under the terms of the GNU General Public License as published by
17271+ * the Free Software Foundation; either version 2 of the License, or
17272+ * (at your option) any later version.
17273+ *
17274+ * This program is distributed in the hope that it will be useful,
17275+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17276+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17277+ * GNU General Public License for more details.
17278+ *
17279+ * You should have received a copy of the GNU General Public License
523b37e3 17280+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
17281+ */
17282+
17283+/*
7f207e10 17284+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
17285+ */
17286+
eca801bf 17287+/* #include <linux/iversion.h> */
e49829fe
JR
17288+#include "aufs.h"
17289+
027c5e7a 17290+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
17291+{
17292+ int err;
7f207e10 17293+ struct au_hnotify *hn;
1facf9fc 17294+
4a4d8108
AM
17295+ err = -ENOMEM;
17296+ hn = au_cache_alloc_hnotify();
17297+ if (hn) {
17298+ hn->hn_aufs_inode = inode;
027c5e7a
AM
17299+ hinode->hi_notify = hn;
17300+ err = au_hnotify_op.alloc(hinode);
17301+ AuTraceErr(err);
17302+ if (unlikely(err)) {
17303+ hinode->hi_notify = NULL;
1c60b727 17304+ au_cache_free_hnotify(hn);
4a4d8108
AM
17305+ /*
17306+ * The upper dir was removed by udba, but the same named
acd2b654 17307+ * dir left. In this case, aufs assigns a new inode
4a4d8108 17308+ * number and set the monitor again.
acd2b654 17309+ * For the lower dir, the old monitor is still left.
4a4d8108
AM
17310+ */
17311+ if (err == -EEXIST)
17312+ err = 0;
17313+ }
1308ab2a 17314+ }
1308ab2a 17315+
027c5e7a 17316+ AuTraceErr(err);
1308ab2a 17317+ return err;
dece6358 17318+}
1facf9fc 17319+
4a4d8108 17320+void au_hn_free(struct au_hinode *hinode)
dece6358 17321+{
4a4d8108 17322+ struct au_hnotify *hn;
1facf9fc 17323+
4a4d8108
AM
17324+ hn = hinode->hi_notify;
17325+ if (hn) {
4a4d8108 17326+ hinode->hi_notify = NULL;
7eafdf33 17327+ if (au_hnotify_op.free(hinode, hn))
1c60b727 17328+ au_cache_free_hnotify(hn);
4a4d8108
AM
17329+ }
17330+}
dece6358 17331+
4a4d8108 17332+/* ---------------------------------------------------------------------- */
dece6358 17333+
4a4d8108
AM
17334+void au_hn_ctl(struct au_hinode *hinode, int do_set)
17335+{
17336+ if (hinode->hi_notify)
17337+ au_hnotify_op.ctl(hinode, do_set);
17338+}
17339+
17340+void au_hn_reset(struct inode *inode, unsigned int flags)
17341+{
5afbbe0d 17342+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
17343+ struct inode *hi;
17344+ struct dentry *iwhdentry;
1facf9fc 17345+
5afbbe0d
AM
17346+ bbot = au_ibbot(inode);
17347+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
4a4d8108
AM
17348+ hi = au_h_iptr(inode, bindex);
17349+ if (!hi)
17350+ continue;
1308ab2a 17351+
febd17d6 17352+ /* inode_lock_nested(hi, AuLsc_I_CHILD); */
4a4d8108
AM
17353+ iwhdentry = au_hi_wh(inode, bindex);
17354+ if (iwhdentry)
17355+ dget(iwhdentry);
17356+ au_igrab(hi);
17357+ au_set_h_iptr(inode, bindex, NULL, 0);
17358+ au_set_h_iptr(inode, bindex, au_igrab(hi),
17359+ flags & ~AuHi_XINO);
17360+ iput(hi);
17361+ dput(iwhdentry);
febd17d6 17362+ /* inode_unlock(hi); */
1facf9fc 17363+ }
1facf9fc 17364+}
17365+
1308ab2a 17366+/* ---------------------------------------------------------------------- */
1facf9fc 17367+
4a4d8108 17368+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 17369+{
4a4d8108 17370+ int err;
5afbbe0d 17371+ aufs_bindex_t bindex, bbot, bfound, btop;
4a4d8108 17372+ struct inode *h_i;
1facf9fc 17373+
4a4d8108
AM
17374+ err = 0;
17375+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 17376+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
17377+ goto out;
17378+ }
1facf9fc 17379+
4a4d8108 17380+ bfound = -1;
5afbbe0d
AM
17381+ bbot = au_ibbot(inode);
17382+ btop = au_ibtop(inode);
4a4d8108 17383+#if 0 /* reserved for future use */
5afbbe0d 17384+ if (bindex == bbot) {
4a4d8108
AM
17385+ /* keep this ino in rename case */
17386+ goto out;
17387+ }
17388+#endif
5afbbe0d 17389+ for (bindex = btop; bindex <= bbot; bindex++)
4a4d8108
AM
17390+ if (au_h_iptr(inode, bindex) == h_inode) {
17391+ bfound = bindex;
17392+ break;
17393+ }
17394+ if (bfound < 0)
1308ab2a 17395+ goto out;
1facf9fc 17396+
5afbbe0d 17397+ for (bindex = btop; bindex <= bbot; bindex++) {
4a4d8108
AM
17398+ h_i = au_h_iptr(inode, bindex);
17399+ if (!h_i)
17400+ continue;
1facf9fc 17401+
4a4d8108
AM
17402+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
17403+ /* ignore this error */
17404+ /* bad action? */
1facf9fc 17405+ }
1facf9fc 17406+
4a4d8108 17407+ /* children inode number will be broken */
1facf9fc 17408+
4f0767ce 17409+out:
4a4d8108
AM
17410+ AuTraceErr(err);
17411+ return err;
1facf9fc 17412+}
17413+
4a4d8108 17414+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 17415+{
4a4d8108
AM
17416+ int err, i, j, ndentry;
17417+ struct au_dcsub_pages dpages;
17418+ struct au_dpage *dpage;
17419+ struct dentry **dentries;
1facf9fc 17420+
4a4d8108
AM
17421+ err = au_dpages_init(&dpages, GFP_NOFS);
17422+ if (unlikely(err))
17423+ goto out;
17424+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
17425+ if (unlikely(err))
17426+ goto out_dpages;
1facf9fc 17427+
4a4d8108
AM
17428+ for (i = 0; i < dpages.ndpage; i++) {
17429+ dpage = dpages.dpages + i;
17430+ dentries = dpage->dentries;
17431+ ndentry = dpage->ndentry;
17432+ for (j = 0; j < ndentry; j++) {
17433+ struct dentry *d;
17434+
17435+ d = dentries[j];
17436+ if (IS_ROOT(d))
17437+ continue;
17438+
4a4d8108 17439+ au_digen_dec(d);
5527c038 17440+ if (d_really_is_positive(d))
4a4d8108
AM
17441+ /* todo: reset children xino?
17442+ cached children only? */
5527c038 17443+ au_iigen_dec(d_inode(d));
1308ab2a 17444+ }
dece6358 17445+ }
1facf9fc 17446+
4f0767ce 17447+out_dpages:
4a4d8108 17448+ au_dpages_free(&dpages);
dece6358 17449+
027c5e7a 17450+#if 0
4a4d8108
AM
17451+ /* discard children */
17452+ dentry_unhash(dentry);
17453+ dput(dentry);
027c5e7a 17454+#endif
4f0767ce 17455+out:
dece6358
AM
17456+ return err;
17457+}
17458+
1308ab2a 17459+/*
4a4d8108 17460+ * return 0 if processed.
1308ab2a 17461+ */
4a4d8108
AM
17462+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
17463+ const unsigned int isdir)
dece6358 17464+{
1308ab2a 17465+ int err;
4a4d8108
AM
17466+ struct dentry *d;
17467+ struct qstr *dname;
1facf9fc 17468+
4a4d8108
AM
17469+ err = 1;
17470+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 17471+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
17472+ err = 0;
17473+ goto out;
17474+ }
dece6358 17475+
4a4d8108
AM
17476+ if (!isdir) {
17477+ AuDebugOn(!name);
17478+ au_iigen_dec(inode);
027c5e7a 17479+ spin_lock(&inode->i_lock);
c1595e42 17480+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 17481+ spin_lock(&d->d_lock);
4a4d8108
AM
17482+ dname = &d->d_name;
17483+ if (dname->len != nlen
027c5e7a
AM
17484+ && memcmp(dname->name, name, nlen)) {
17485+ spin_unlock(&d->d_lock);
4a4d8108 17486+ continue;
027c5e7a 17487+ }
4a4d8108 17488+ err = 0;
4a4d8108
AM
17489+ au_digen_dec(d);
17490+ spin_unlock(&d->d_lock);
17491+ break;
1facf9fc 17492+ }
027c5e7a 17493+ spin_unlock(&inode->i_lock);
1308ab2a 17494+ } else {
027c5e7a 17495+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
c1595e42 17496+ d = d_find_any_alias(inode);
4a4d8108
AM
17497+ if (!d) {
17498+ au_iigen_dec(inode);
17499+ goto out;
17500+ }
1facf9fc 17501+
027c5e7a 17502+ spin_lock(&d->d_lock);
4a4d8108 17503+ dname = &d->d_name;
027c5e7a
AM
17504+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
17505+ spin_unlock(&d->d_lock);
4a4d8108 17506+ err = hn_gen_tree(d);
027c5e7a
AM
17507+ spin_lock(&d->d_lock);
17508+ }
17509+ spin_unlock(&d->d_lock);
4a4d8108
AM
17510+ dput(d);
17511+ }
1facf9fc 17512+
4f0767ce 17513+out:
4a4d8108 17514+ AuTraceErr(err);
1308ab2a 17515+ return err;
17516+}
dece6358 17517+
4a4d8108 17518+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 17519+{
4a4d8108 17520+ int err;
1facf9fc 17521+
5527c038 17522+ if (IS_ROOT(dentry)) {
0c3ec466 17523+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
17524+ return 0;
17525+ }
1308ab2a 17526+
4a4d8108
AM
17527+ err = 0;
17528+ if (!isdir) {
4a4d8108 17529+ au_digen_dec(dentry);
5527c038
JR
17530+ if (d_really_is_positive(dentry))
17531+ au_iigen_dec(d_inode(dentry));
4a4d8108 17532+ } else {
027c5e7a 17533+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
5527c038 17534+ if (d_really_is_positive(dentry))
4a4d8108
AM
17535+ err = hn_gen_tree(dentry);
17536+ }
17537+
17538+ AuTraceErr(err);
17539+ return err;
1facf9fc 17540+}
17541+
4a4d8108 17542+/* ---------------------------------------------------------------------- */
1facf9fc 17543+
4a4d8108
AM
17544+/* hnotify job flags */
17545+#define AuHnJob_XINO0 1
17546+#define AuHnJob_GEN (1 << 1)
17547+#define AuHnJob_DIRENT (1 << 2)
17548+#define AuHnJob_ISDIR (1 << 3)
17549+#define AuHnJob_TRYXINO0 (1 << 4)
17550+#define AuHnJob_MNTPNT (1 << 5)
17551+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
17552+#define au_fset_hnjob(flags, name) \
17553+ do { (flags) |= AuHnJob_##name; } while (0)
17554+#define au_fclr_hnjob(flags, name) \
17555+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 17556+
4a4d8108
AM
17557+enum {
17558+ AuHn_CHILD,
17559+ AuHn_PARENT,
17560+ AuHnLast
17561+};
1facf9fc 17562+
4a4d8108
AM
17563+struct au_hnotify_args {
17564+ struct inode *h_dir, *dir, *h_child_inode;
17565+ u32 mask;
17566+ unsigned int flags[AuHnLast];
17567+ unsigned int h_child_nlen;
17568+ char h_child_name[];
17569+};
1facf9fc 17570+
4a4d8108
AM
17571+struct hn_job_args {
17572+ unsigned int flags;
17573+ struct inode *inode, *h_inode, *dir, *h_dir;
17574+ struct dentry *dentry;
17575+ char *h_name;
17576+ int h_nlen;
17577+};
1308ab2a 17578+
4a4d8108
AM
17579+static int hn_job(struct hn_job_args *a)
17580+{
17581+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
076b876e 17582+ int e;
1308ab2a 17583+
4a4d8108
AM
17584+ /* reset xino */
17585+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
17586+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 17587+
4a4d8108
AM
17588+ if (au_ftest_hnjob(a->flags, TRYXINO0)
17589+ && a->inode
17590+ && a->h_inode) {
be118d29 17591+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
38d290e6
JR
17592+ if (!a->h_inode->i_nlink
17593+ && !(a->h_inode->i_state & I_LINKABLE))
4a4d8108 17594+ hn_xino(a->inode, a->h_inode); /* ignore this error */
3c1bdaff 17595+ inode_unlock_shared(a->h_inode);
1308ab2a 17596+ }
1facf9fc 17597+
4a4d8108
AM
17598+ /* make the generation obsolete */
17599+ if (au_ftest_hnjob(a->flags, GEN)) {
076b876e 17600+ e = -1;
4a4d8108 17601+ if (a->inode)
076b876e 17602+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
4a4d8108 17603+ isdir);
076b876e 17604+ if (e && a->dentry)
4a4d8108
AM
17605+ hn_gen_by_name(a->dentry, isdir);
17606+ /* ignore this error */
1facf9fc 17607+ }
1facf9fc 17608+
4a4d8108
AM
17609+ /* make dir entries obsolete */
17610+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
17611+ struct au_vdir *vdir;
1facf9fc 17612+
4a4d8108
AM
17613+ vdir = au_ivdir(a->inode);
17614+ if (vdir)
17615+ vdir->vd_jiffy = 0;
17616+ /* IMustLock(a->inode); */
be118d29 17617+ /* inode_inc_iversion(a->inode); */
4a4d8108 17618+ }
1facf9fc 17619+
4a4d8108
AM
17620+ /* can do nothing but warn */
17621+ if (au_ftest_hnjob(a->flags, MNTPNT)
17622+ && a->dentry
17623+ && d_mountpoint(a->dentry))
523b37e3 17624+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 17625+
4a4d8108 17626+ return 0;
1308ab2a 17627+}
1facf9fc 17628+
1308ab2a 17629+/* ---------------------------------------------------------------------- */
1facf9fc 17630+
4a4d8108
AM
17631+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
17632+ struct inode *dir)
1308ab2a 17633+{
4a4d8108
AM
17634+ struct dentry *dentry, *d, *parent;
17635+ struct qstr *dname;
1308ab2a 17636+
c1595e42 17637+ parent = d_find_any_alias(dir);
4a4d8108
AM
17638+ if (!parent)
17639+ return NULL;
1308ab2a 17640+
4a4d8108 17641+ dentry = NULL;
027c5e7a 17642+ spin_lock(&parent->d_lock);
c1595e42 17643+ list_for_each_entry(d, &parent->d_subdirs, d_child) {
523b37e3 17644+ /* AuDbg("%pd\n", d); */
027c5e7a 17645+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
17646+ dname = &d->d_name;
17647+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
17648+ goto cont_unlock;
17649+ if (au_di(d))
17650+ au_digen_dec(d);
17651+ else
17652+ goto cont_unlock;
c1595e42 17653+ if (au_dcount(d) > 0) {
027c5e7a 17654+ dentry = dget_dlock(d);
4a4d8108 17655+ spin_unlock(&d->d_lock);
027c5e7a 17656+ break;
dece6358 17657+ }
1facf9fc 17658+
f6b6e03d 17659+cont_unlock:
027c5e7a 17660+ spin_unlock(&d->d_lock);
1308ab2a 17661+ }
027c5e7a 17662+ spin_unlock(&parent->d_lock);
4a4d8108 17663+ dput(parent);
1facf9fc 17664+
4a4d8108
AM
17665+ if (dentry)
17666+ di_write_lock_child(dentry);
1308ab2a 17667+
4a4d8108
AM
17668+ return dentry;
17669+}
dece6358 17670+
4a4d8108
AM
17671+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
17672+ aufs_bindex_t bindex, ino_t h_ino)
17673+{
17674+ struct inode *inode;
17675+ ino_t ino;
17676+ int err;
17677+
17678+ inode = NULL;
17679+ err = au_xino_read(sb, bindex, h_ino, &ino);
17680+ if (!err && ino)
17681+ inode = ilookup(sb, ino);
17682+ if (!inode)
17683+ goto out;
17684+
17685+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 17686+ pr_warn("wrong root branch\n");
4a4d8108
AM
17687+ iput(inode);
17688+ inode = NULL;
17689+ goto out;
1308ab2a 17690+ }
17691+
4a4d8108 17692+ ii_write_lock_child(inode);
1308ab2a 17693+
4f0767ce 17694+out:
4a4d8108 17695+ return inode;
dece6358
AM
17696+}
17697+
4a4d8108 17698+static void au_hn_bh(void *_args)
1facf9fc 17699+{
4a4d8108
AM
17700+ struct au_hnotify_args *a = _args;
17701+ struct super_block *sb;
5afbbe0d 17702+ aufs_bindex_t bindex, bbot, bfound;
4a4d8108 17703+ unsigned char xino, try_iput;
1facf9fc 17704+ int err;
1308ab2a 17705+ struct inode *inode;
4a4d8108
AM
17706+ ino_t h_ino;
17707+ struct hn_job_args args;
17708+ struct dentry *dentry;
17709+ struct au_sbinfo *sbinfo;
1facf9fc 17710+
4a4d8108
AM
17711+ AuDebugOn(!_args);
17712+ AuDebugOn(!a->h_dir);
17713+ AuDebugOn(!a->dir);
17714+ AuDebugOn(!a->mask);
17715+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
17716+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
17717+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 17718+
4a4d8108
AM
17719+ inode = NULL;
17720+ dentry = NULL;
17721+ /*
17722+ * do not lock a->dir->i_mutex here
17723+ * because of d_revalidate() may cause a deadlock.
17724+ */
17725+ sb = a->dir->i_sb;
17726+ AuDebugOn(!sb);
17727+ sbinfo = au_sbi(sb);
17728+ AuDebugOn(!sbinfo);
7f207e10 17729+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 17730+
8b6a4947
AM
17731+ if (au_opt_test(sbinfo->si_mntflags, DIRREN))
17732+ switch (a->mask & FS_EVENTS_POSS_ON_CHILD) {
17733+ case FS_MOVED_FROM:
17734+ case FS_MOVED_TO:
17735+ AuWarn1("DIRREN with UDBA may not work correctly "
17736+ "for the direct rename(2)\n");
17737+ }
17738+
4a4d8108
AM
17739+ ii_read_lock_parent(a->dir);
17740+ bfound = -1;
5afbbe0d
AM
17741+ bbot = au_ibbot(a->dir);
17742+ for (bindex = au_ibtop(a->dir); bindex <= bbot; bindex++)
4a4d8108
AM
17743+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
17744+ bfound = bindex;
17745+ break;
17746+ }
17747+ ii_read_unlock(a->dir);
17748+ if (unlikely(bfound < 0))
17749+ goto out;
1facf9fc 17750+
4a4d8108
AM
17751+ xino = !!au_opt_test(au_mntflags(sb), XINO);
17752+ h_ino = 0;
17753+ if (a->h_child_inode)
17754+ h_ino = a->h_child_inode->i_ino;
1facf9fc 17755+
4a4d8108
AM
17756+ if (a->h_child_nlen
17757+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
17758+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
17759+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
17760+ a->dir);
17761+ try_iput = 0;
5527c038
JR
17762+ if (dentry && d_really_is_positive(dentry))
17763+ inode = d_inode(dentry);
4a4d8108
AM
17764+ if (xino && !inode && h_ino
17765+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
17766+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
17767+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
17768+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
17769+ try_iput = 1;
f0c0a007 17770+ }
1facf9fc 17771+
4a4d8108
AM
17772+ args.flags = a->flags[AuHn_CHILD];
17773+ args.dentry = dentry;
17774+ args.inode = inode;
17775+ args.h_inode = a->h_child_inode;
17776+ args.dir = a->dir;
17777+ args.h_dir = a->h_dir;
17778+ args.h_name = a->h_child_name;
17779+ args.h_nlen = a->h_child_nlen;
17780+ err = hn_job(&args);
17781+ if (dentry) {
027c5e7a 17782+ if (au_di(dentry))
4a4d8108
AM
17783+ di_write_unlock(dentry);
17784+ dput(dentry);
17785+ }
17786+ if (inode && try_iput) {
17787+ ii_write_unlock(inode);
17788+ iput(inode);
17789+ }
1facf9fc 17790+
4a4d8108
AM
17791+ ii_write_lock_parent(a->dir);
17792+ args.flags = a->flags[AuHn_PARENT];
17793+ args.dentry = NULL;
17794+ args.inode = a->dir;
17795+ args.h_inode = a->h_dir;
17796+ args.dir = NULL;
17797+ args.h_dir = NULL;
17798+ args.h_name = NULL;
17799+ args.h_nlen = 0;
17800+ err = hn_job(&args);
17801+ ii_write_unlock(a->dir);
1facf9fc 17802+
4f0767ce 17803+out:
4a4d8108
AM
17804+ iput(a->h_child_inode);
17805+ iput(a->h_dir);
17806+ iput(a->dir);
027c5e7a
AM
17807+ si_write_unlock(sb);
17808+ au_nwt_done(&sbinfo->si_nowait);
9f237c51 17809+ au_kfree_rcu(a);
dece6358 17810+}
1facf9fc 17811+
4a4d8108
AM
17812+/* ---------------------------------------------------------------------- */
17813+
17814+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
17815+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 17816+{
4a4d8108 17817+ int err, len;
53392da6 17818+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
17819+ unsigned char isdir, isroot, wh;
17820+ struct inode *dir;
17821+ struct au_hnotify_args *args;
17822+ char *p, *h_child_name;
dece6358 17823+
1308ab2a 17824+ err = 0;
4a4d8108
AM
17825+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
17826+ dir = igrab(hnotify->hn_aufs_inode);
17827+ if (!dir)
17828+ goto out;
1facf9fc 17829+
4a4d8108
AM
17830+ isroot = (dir->i_ino == AUFS_ROOT_INO);
17831+ wh = 0;
17832+ h_child_name = (void *)h_child_qstr->name;
17833+ len = h_child_qstr->len;
17834+ if (h_child_name) {
17835+ if (len > AUFS_WH_PFX_LEN
17836+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
17837+ h_child_name += AUFS_WH_PFX_LEN;
17838+ len -= AUFS_WH_PFX_LEN;
17839+ wh = 1;
17840+ }
1facf9fc 17841+ }
dece6358 17842+
4a4d8108
AM
17843+ isdir = 0;
17844+ if (h_child_inode)
17845+ isdir = !!S_ISDIR(h_child_inode->i_mode);
17846+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
17847+ flags[AuHn_CHILD] = 0;
17848+ if (isdir)
17849+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
17850+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
17851+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
17852+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
17853+ case FS_MOVED_FROM:
17854+ case FS_MOVED_TO:
17855+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
17856+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
17857+ /*FALLTHROUGH*/
17858+ case FS_CREATE:
fb47a38f 17859+ AuDebugOn(!h_child_name);
4a4d8108 17860+ break;
1facf9fc 17861+
4a4d8108
AM
17862+ case FS_DELETE:
17863+ /*
17864+ * aufs never be able to get this child inode.
17865+ * revalidation should be in d_revalidate()
17866+ * by checking i_nlink, i_generation or d_unhashed().
17867+ */
17868+ AuDebugOn(!h_child_name);
17869+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
17870+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
17871+ break;
dece6358 17872+
4a4d8108
AM
17873+ default:
17874+ AuDebugOn(1);
17875+ }
1308ab2a 17876+
4a4d8108
AM
17877+ if (wh)
17878+ h_child_inode = NULL;
1308ab2a 17879+
4a4d8108
AM
17880+ err = -ENOMEM;
17881+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 17882+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
17883+ if (unlikely(!args)) {
17884+ AuErr1("no memory\n");
17885+ iput(dir);
17886+ goto out;
17887+ }
17888+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
17889+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
17890+ args->mask = mask;
17891+ args->dir = dir;
17892+ args->h_dir = igrab(h_dir);
17893+ if (h_child_inode)
17894+ h_child_inode = igrab(h_child_inode); /* can be NULL */
17895+ args->h_child_inode = h_child_inode;
17896+ args->h_child_nlen = len;
17897+ if (len) {
17898+ p = (void *)args;
17899+ p += sizeof(*args);
17900+ memcpy(p, h_child_name, len);
17901+ p[len] = 0;
1308ab2a 17902+ }
1308ab2a 17903+
38d290e6 17904+ /* NFS fires the event for silly-renamed one from kworker */
53392da6 17905+ f = 0;
38d290e6
JR
17906+ if (!dir->i_nlink
17907+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
53392da6
AM
17908+ f = AuWkq_NEST;
17909+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
17910+ if (unlikely(err)) {
17911+ pr_err("wkq %d\n", err);
17912+ iput(args->h_child_inode);
17913+ iput(args->h_dir);
17914+ iput(args->dir);
9f237c51 17915+ au_kfree_rcu(args);
1facf9fc 17916+ }
1facf9fc 17917+
4a4d8108 17918+out:
1facf9fc 17919+ return err;
17920+}
17921+
027c5e7a
AM
17922+/* ---------------------------------------------------------------------- */
17923+
17924+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
17925+{
17926+ int err;
17927+
17928+ AuDebugOn(!(udba & AuOptMask_UDBA));
17929+
17930+ err = 0;
17931+ if (au_hnotify_op.reset_br)
17932+ err = au_hnotify_op.reset_br(udba, br, perm);
17933+
17934+ return err;
17935+}
17936+
17937+int au_hnotify_init_br(struct au_branch *br, int perm)
17938+{
17939+ int err;
17940+
17941+ err = 0;
17942+ if (au_hnotify_op.init_br)
17943+ err = au_hnotify_op.init_br(br, perm);
17944+
17945+ return err;
17946+}
17947+
17948+void au_hnotify_fin_br(struct au_branch *br)
17949+{
17950+ if (au_hnotify_op.fin_br)
17951+ au_hnotify_op.fin_br(br);
17952+}
17953+
4a4d8108
AM
17954+static void au_hn_destroy_cache(void)
17955+{
1c60b727
AM
17956+ kmem_cache_destroy(au_cache[AuCache_HNOTIFY]);
17957+ au_cache[AuCache_HNOTIFY] = NULL;
4a4d8108 17958+}
1308ab2a 17959+
4a4d8108 17960+int __init au_hnotify_init(void)
1facf9fc 17961+{
1308ab2a 17962+ int err;
1308ab2a 17963+
4a4d8108 17964+ err = -ENOMEM;
1c60b727
AM
17965+ au_cache[AuCache_HNOTIFY] = AuCache(au_hnotify);
17966+ if (au_cache[AuCache_HNOTIFY]) {
027c5e7a
AM
17967+ err = 0;
17968+ if (au_hnotify_op.init)
17969+ err = au_hnotify_op.init();
4a4d8108
AM
17970+ if (unlikely(err))
17971+ au_hn_destroy_cache();
1308ab2a 17972+ }
1308ab2a 17973+ AuTraceErr(err);
4a4d8108 17974+ return err;
1308ab2a 17975+}
17976+
4a4d8108 17977+void au_hnotify_fin(void)
1308ab2a 17978+{
027c5e7a
AM
17979+ if (au_hnotify_op.fin)
17980+ au_hnotify_op.fin();
f0c0a007 17981+
4a4d8108 17982+ /* cf. au_cache_fin() */
1c60b727 17983+ if (au_cache[AuCache_HNOTIFY])
4a4d8108 17984+ au_hn_destroy_cache();
dece6358 17985+}
7f207e10
AM
17986diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
17987--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 17988+++ linux/fs/aufs/iinfo.c 2019-03-05 12:13:00.139224339 +0100
062440b3 17989@@ -0,0 +1,286 @@
cd7a4cd9 17990+// SPDX-License-Identifier: GPL-2.0
dece6358 17991+/*
ba1aed25 17992+ * Copyright (C) 2005-2019 Junjiro R. Okajima
dece6358
AM
17993+ *
17994+ * This program, aufs is free software; you can redistribute it and/or modify
17995+ * it under the terms of the GNU General Public License as published by
17996+ * the Free Software Foundation; either version 2 of the License, or
17997+ * (at your option) any later version.
17998+ *
17999+ * This program is distributed in the hope that it will be useful,
18000+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18001+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18002+ * GNU General Public License for more details.
18003+ *
18004+ * You should have received a copy of the GNU General Public License
523b37e3 18005+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 18006+ */
1facf9fc 18007+
dece6358 18008+/*
4a4d8108 18009+ * inode private data
dece6358 18010+ */
1facf9fc 18011+
1308ab2a 18012+#include "aufs.h"
1facf9fc 18013+
4a4d8108 18014+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 18015+{
4a4d8108 18016+ struct inode *h_inode;
5afbbe0d 18017+ struct au_hinode *hinode;
1facf9fc 18018+
4a4d8108 18019+ IiMustAnyLock(inode);
1facf9fc 18020+
5afbbe0d
AM
18021+ hinode = au_hinode(au_ii(inode), bindex);
18022+ h_inode = hinode->hi_inode;
4a4d8108
AM
18023+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
18024+ return h_inode;
18025+}
1facf9fc 18026+
4a4d8108
AM
18027+/* todo: hard/soft set? */
18028+void au_hiput(struct au_hinode *hinode)
18029+{
18030+ au_hn_free(hinode);
18031+ dput(hinode->hi_whdentry);
18032+ iput(hinode->hi_inode);
18033+}
1facf9fc 18034+
4a4d8108
AM
18035+unsigned int au_hi_flags(struct inode *inode, int isdir)
18036+{
18037+ unsigned int flags;
18038+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 18039+
4a4d8108
AM
18040+ flags = 0;
18041+ if (au_opt_test(mnt_flags, XINO))
18042+ au_fset_hi(flags, XINO);
18043+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
18044+ au_fset_hi(flags, HNOTIFY);
18045+ return flags;
1facf9fc 18046+}
18047+
4a4d8108
AM
18048+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
18049+ struct inode *h_inode, unsigned int flags)
1308ab2a 18050+{
4a4d8108
AM
18051+ struct au_hinode *hinode;
18052+ struct inode *hi;
18053+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 18054+
4a4d8108 18055+ IiMustWriteLock(inode);
dece6358 18056+
5afbbe0d 18057+ hinode = au_hinode(iinfo, bindex);
4a4d8108
AM
18058+ hi = hinode->hi_inode;
18059+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
18060+
18061+ if (hi)
18062+ au_hiput(hinode);
18063+ hinode->hi_inode = h_inode;
18064+ if (h_inode) {
18065+ int err;
18066+ struct super_block *sb = inode->i_sb;
18067+ struct au_branch *br;
18068+
027c5e7a
AM
18069+ AuDebugOn(inode->i_mode
18070+ && (h_inode->i_mode & S_IFMT)
18071+ != (inode->i_mode & S_IFMT));
5afbbe0d 18072+ if (bindex == iinfo->ii_btop)
4a4d8108
AM
18073+ au_cpup_igen(inode, h_inode);
18074+ br = au_sbr(sb, bindex);
18075+ hinode->hi_id = br->br_id;
18076+ if (au_ftest_hi(flags, XINO)) {
18077+ err = au_xino_write(sb, bindex, h_inode->i_ino,
18078+ inode->i_ino);
18079+ if (unlikely(err))
18080+ AuIOErr1("failed au_xino_write() %d\n", err);
18081+ }
18082+
18083+ if (au_ftest_hi(flags, HNOTIFY)
18084+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 18085+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
18086+ if (unlikely(err))
18087+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 18088+ }
18089+ }
4a4d8108 18090+}
dece6358 18091+
4a4d8108
AM
18092+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
18093+ struct dentry *h_wh)
18094+{
18095+ struct au_hinode *hinode;
dece6358 18096+
4a4d8108
AM
18097+ IiMustWriteLock(inode);
18098+
5afbbe0d 18099+ hinode = au_hinode(au_ii(inode), bindex);
4a4d8108
AM
18100+ AuDebugOn(hinode->hi_whdentry);
18101+ hinode->hi_whdentry = h_wh;
1facf9fc 18102+}
18103+
537831f9 18104+void au_update_iigen(struct inode *inode, int half)
1308ab2a 18105+{
537831f9
AM
18106+ struct au_iinfo *iinfo;
18107+ struct au_iigen *iigen;
18108+ unsigned int sigen;
18109+
18110+ sigen = au_sigen(inode->i_sb);
18111+ iinfo = au_ii(inode);
18112+ iigen = &iinfo->ii_generation;
be52b249 18113+ spin_lock(&iigen->ig_spin);
537831f9
AM
18114+ iigen->ig_generation = sigen;
18115+ if (half)
18116+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
18117+ else
18118+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
be52b249 18119+ spin_unlock(&iigen->ig_spin);
4a4d8108 18120+}
1facf9fc 18121+
4a4d8108
AM
18122+/* it may be called at remount time, too */
18123+void au_update_ibrange(struct inode *inode, int do_put_zero)
18124+{
18125+ struct au_iinfo *iinfo;
5afbbe0d 18126+ aufs_bindex_t bindex, bbot;
1facf9fc 18127+
5afbbe0d 18128+ AuDebugOn(au_is_bad_inode(inode));
4a4d8108 18129+ IiMustWriteLock(inode);
1facf9fc 18130+
5afbbe0d
AM
18131+ iinfo = au_ii(inode);
18132+ if (do_put_zero && iinfo->ii_btop >= 0) {
18133+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot;
4a4d8108
AM
18134+ bindex++) {
18135+ struct inode *h_i;
1facf9fc 18136+
5afbbe0d 18137+ h_i = au_hinode(iinfo, bindex)->hi_inode;
38d290e6
JR
18138+ if (h_i
18139+ && !h_i->i_nlink
18140+ && !(h_i->i_state & I_LINKABLE))
027c5e7a
AM
18141+ au_set_h_iptr(inode, bindex, NULL, 0);
18142+ }
4a4d8108
AM
18143+ }
18144+
5afbbe0d
AM
18145+ iinfo->ii_btop = -1;
18146+ iinfo->ii_bbot = -1;
18147+ bbot = au_sbbot(inode->i_sb);
18148+ for (bindex = 0; bindex <= bbot; bindex++)
18149+ if (au_hinode(iinfo, bindex)->hi_inode) {
18150+ iinfo->ii_btop = bindex;
4a4d8108 18151+ break;
027c5e7a 18152+ }
5afbbe0d
AM
18153+ if (iinfo->ii_btop >= 0)
18154+ for (bindex = bbot; bindex >= iinfo->ii_btop; bindex--)
18155+ if (au_hinode(iinfo, bindex)->hi_inode) {
18156+ iinfo->ii_bbot = bindex;
027c5e7a
AM
18157+ break;
18158+ }
5afbbe0d 18159+ AuDebugOn(iinfo->ii_btop > iinfo->ii_bbot);
1308ab2a 18160+}
1facf9fc 18161+
dece6358 18162+/* ---------------------------------------------------------------------- */
1facf9fc 18163+
4a4d8108 18164+void au_icntnr_init_once(void *_c)
dece6358 18165+{
4a4d8108
AM
18166+ struct au_icntnr *c = _c;
18167+ struct au_iinfo *iinfo = &c->iinfo;
1facf9fc 18168+
be52b249 18169+ spin_lock_init(&iinfo->ii_generation.ig_spin);
4a4d8108
AM
18170+ au_rw_init(&iinfo->ii_rwsem);
18171+ inode_init_once(&c->vfs_inode);
18172+}
1facf9fc 18173+
5afbbe0d
AM
18174+void au_hinode_init(struct au_hinode *hinode)
18175+{
18176+ hinode->hi_inode = NULL;
18177+ hinode->hi_id = -1;
18178+ au_hn_init(hinode);
18179+ hinode->hi_whdentry = NULL;
18180+}
18181+
4a4d8108
AM
18182+int au_iinfo_init(struct inode *inode)
18183+{
18184+ struct au_iinfo *iinfo;
18185+ struct super_block *sb;
5afbbe0d 18186+ struct au_hinode *hi;
4a4d8108 18187+ int nbr, i;
1facf9fc 18188+
4a4d8108
AM
18189+ sb = inode->i_sb;
18190+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
5afbbe0d 18191+ nbr = au_sbbot(sb) + 1;
4a4d8108
AM
18192+ if (unlikely(nbr <= 0))
18193+ nbr = 1;
5afbbe0d
AM
18194+ hi = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
18195+ if (hi) {
acd2b654 18196+ au_lcnt_inc(&au_sbi(sb)->si_ninodes);
5afbbe0d
AM
18197+
18198+ iinfo->ii_hinode = hi;
18199+ for (i = 0; i < nbr; i++, hi++)
18200+ au_hinode_init(hi);
1facf9fc 18201+
537831f9 18202+ iinfo->ii_generation.ig_generation = au_sigen(sb);
5afbbe0d
AM
18203+ iinfo->ii_btop = -1;
18204+ iinfo->ii_bbot = -1;
4a4d8108
AM
18205+ iinfo->ii_vdir = NULL;
18206+ return 0;
1308ab2a 18207+ }
4a4d8108
AM
18208+ return -ENOMEM;
18209+}
1facf9fc 18210+
e2f27e51 18211+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink)
4a4d8108 18212+{
5afbbe0d 18213+ int err, i;
4a4d8108 18214+ struct au_hinode *hip;
1facf9fc 18215+
4a4d8108
AM
18216+ AuRwMustWriteLock(&iinfo->ii_rwsem);
18217+
18218+ err = -ENOMEM;
e2f27e51
AM
18219+ hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS,
18220+ may_shrink);
4a4d8108
AM
18221+ if (hip) {
18222+ iinfo->ii_hinode = hip;
5afbbe0d
AM
18223+ i = iinfo->ii_bbot + 1;
18224+ hip += i;
18225+ for (; i < nbr; i++, hip++)
18226+ au_hinode_init(hip);
4a4d8108 18227+ err = 0;
1308ab2a 18228+ }
4a4d8108 18229+
1308ab2a 18230+ return err;
1facf9fc 18231+}
18232+
4a4d8108 18233+void au_iinfo_fin(struct inode *inode)
1facf9fc 18234+{
4a4d8108
AM
18235+ struct au_iinfo *iinfo;
18236+ struct au_hinode *hi;
18237+ struct super_block *sb;
5afbbe0d 18238+ aufs_bindex_t bindex, bbot;
b752ccd1 18239+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 18240+
5afbbe0d 18241+ AuDebugOn(au_is_bad_inode(inode));
1308ab2a 18242+
b752ccd1 18243+ sb = inode->i_sb;
acd2b654 18244+ au_lcnt_dec(&au_sbi(sb)->si_ninodes);
b752ccd1
AM
18245+ if (si_pid_test(sb))
18246+ au_xino_delete_inode(inode, unlinked);
18247+ else {
18248+ /*
18249+ * it is safe to hide the dependency between sbinfo and
18250+ * sb->s_umount.
18251+ */
18252+ lockdep_off();
18253+ si_noflush_read_lock(sb);
18254+ au_xino_delete_inode(inode, unlinked);
18255+ si_read_unlock(sb);
18256+ lockdep_on();
18257+ }
18258+
5afbbe0d 18259+ iinfo = au_ii(inode);
4a4d8108 18260+ if (iinfo->ii_vdir)
1c60b727 18261+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 18262+
5afbbe0d 18263+ bindex = iinfo->ii_btop;
b752ccd1 18264+ if (bindex >= 0) {
5afbbe0d
AM
18265+ hi = au_hinode(iinfo, bindex);
18266+ bbot = iinfo->ii_bbot;
18267+ while (bindex++ <= bbot) {
b752ccd1 18268+ if (hi->hi_inode)
4a4d8108 18269+ au_hiput(hi);
4a4d8108
AM
18270+ hi++;
18271+ }
18272+ }
9f237c51 18273+ au_kfree_rcu(iinfo->ii_hinode);
4a4d8108 18274+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 18275+}
7f207e10
AM
18276diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
18277--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
18278+++ linux/fs/aufs/inode.c 2019-05-06 09:03:04.820143837 +0200
18279@@ -0,0 +1,529 @@
cd7a4cd9 18280+// SPDX-License-Identifier: GPL-2.0
4a4d8108 18281+/*
ba1aed25 18282+ * Copyright (C) 2005-2019 Junjiro R. Okajima
4a4d8108
AM
18283+ *
18284+ * This program, aufs is free software; you can redistribute it and/or modify
18285+ * it under the terms of the GNU General Public License as published by
18286+ * the Free Software Foundation; either version 2 of the License, or
18287+ * (at your option) any later version.
18288+ *
18289+ * This program is distributed in the hope that it will be useful,
18290+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18291+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18292+ * GNU General Public License for more details.
18293+ *
18294+ * You should have received a copy of the GNU General Public License
523b37e3 18295+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 18296+ */
1facf9fc 18297+
4a4d8108
AM
18298+/*
18299+ * inode functions
18300+ */
1facf9fc 18301+
eca801bf 18302+#include <linux/iversion.h>
4a4d8108 18303+#include "aufs.h"
1308ab2a 18304+
4a4d8108
AM
18305+struct inode *au_igrab(struct inode *inode)
18306+{
18307+ if (inode) {
18308+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 18309+ ihold(inode);
1facf9fc 18310+ }
4a4d8108
AM
18311+ return inode;
18312+}
1facf9fc 18313+
4a4d8108
AM
18314+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
18315+{
18316+ au_cpup_attr_all(inode, /*force*/0);
537831f9 18317+ au_update_iigen(inode, /*half*/1);
4a4d8108 18318+ if (do_version)
be118d29 18319+ inode_inc_iversion(inode);
dece6358 18320+}
1facf9fc 18321+
027c5e7a 18322+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 18323+{
e2f27e51 18324+ int err, e, nbr;
027c5e7a 18325+ umode_t type;
4a4d8108 18326+ aufs_bindex_t bindex, new_bindex;
1308ab2a 18327+ struct super_block *sb;
4a4d8108 18328+ struct au_iinfo *iinfo;
027c5e7a 18329+ struct au_hinode *p, *q, tmp;
1facf9fc 18330+
5afbbe0d 18331+ AuDebugOn(au_is_bad_inode(inode));
4a4d8108 18332+ IiMustWriteLock(inode);
1facf9fc 18333+
027c5e7a 18334+ *update = 0;
4a4d8108 18335+ sb = inode->i_sb;
e2f27e51 18336+ nbr = au_sbbot(sb) + 1;
027c5e7a 18337+ type = inode->i_mode & S_IFMT;
4a4d8108 18338+ iinfo = au_ii(inode);
e2f27e51 18339+ err = au_hinode_realloc(iinfo, nbr, /*may_shrink*/0);
4a4d8108 18340+ if (unlikely(err))
1308ab2a 18341+ goto out;
1facf9fc 18342+
5afbbe0d
AM
18343+ AuDebugOn(iinfo->ii_btop < 0);
18344+ p = au_hinode(iinfo, iinfo->ii_btop);
18345+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot;
4a4d8108
AM
18346+ bindex++, p++) {
18347+ if (!p->hi_inode)
18348+ continue;
1facf9fc 18349+
027c5e7a 18350+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
18351+ new_bindex = au_br_index(sb, p->hi_id);
18352+ if (new_bindex == bindex)
18353+ continue;
1facf9fc 18354+
4a4d8108 18355+ if (new_bindex < 0) {
027c5e7a 18356+ *update = 1;
4a4d8108
AM
18357+ au_hiput(p);
18358+ p->hi_inode = NULL;
18359+ continue;
1308ab2a 18360+ }
4a4d8108 18361+
5afbbe0d
AM
18362+ if (new_bindex < iinfo->ii_btop)
18363+ iinfo->ii_btop = new_bindex;
18364+ if (iinfo->ii_bbot < new_bindex)
18365+ iinfo->ii_bbot = new_bindex;
4a4d8108 18366+ /* swap two lower inode, and loop again */
5afbbe0d 18367+ q = au_hinode(iinfo, new_bindex);
4a4d8108
AM
18368+ tmp = *q;
18369+ *q = *p;
18370+ *p = tmp;
18371+ if (tmp.hi_inode) {
18372+ bindex--;
18373+ p--;
1308ab2a 18374+ }
18375+ }
4a4d8108 18376+ au_update_ibrange(inode, /*do_put_zero*/0);
e2f27e51 18377+ au_hinode_realloc(iinfo, nbr, /*may_shrink*/1); /* harmless if err */
4a4d8108
AM
18378+ e = au_dy_irefresh(inode);
18379+ if (unlikely(e && !err))
18380+ err = e;
1facf9fc 18381+
4f0767ce 18382+out:
027c5e7a
AM
18383+ AuTraceErr(err);
18384+ return err;
18385+}
18386+
b95c5147
AM
18387+void au_refresh_iop(struct inode *inode, int force_getattr)
18388+{
18389+ int type;
18390+ struct au_sbinfo *sbi = au_sbi(inode->i_sb);
18391+ const struct inode_operations *iop
18392+ = force_getattr ? aufs_iop : sbi->si_iop_array;
18393+
18394+ if (inode->i_op == iop)
18395+ return;
18396+
18397+ switch (inode->i_mode & S_IFMT) {
18398+ case S_IFDIR:
18399+ type = AuIop_DIR;
18400+ break;
18401+ case S_IFLNK:
18402+ type = AuIop_SYMLINK;
18403+ break;
18404+ default:
18405+ type = AuIop_OTHER;
18406+ break;
18407+ }
18408+
18409+ inode->i_op = iop + type;
18410+ /* unnecessary smp_wmb() */
18411+}
18412+
027c5e7a
AM
18413+int au_refresh_hinode_self(struct inode *inode)
18414+{
18415+ int err, update;
18416+
18417+ err = au_ii_refresh(inode, &update);
18418+ if (!err)
18419+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
18420+
18421+ AuTraceErr(err);
4a4d8108
AM
18422+ return err;
18423+}
1facf9fc 18424+
4a4d8108
AM
18425+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
18426+{
027c5e7a 18427+ int err, e, update;
4a4d8108 18428+ unsigned int flags;
027c5e7a 18429+ umode_t mode;
5afbbe0d 18430+ aufs_bindex_t bindex, bbot;
027c5e7a 18431+ unsigned char isdir;
4a4d8108
AM
18432+ struct au_hinode *p;
18433+ struct au_iinfo *iinfo;
1facf9fc 18434+
027c5e7a 18435+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
18436+ if (unlikely(err))
18437+ goto out;
18438+
18439+ update = 0;
18440+ iinfo = au_ii(inode);
5afbbe0d 18441+ p = au_hinode(iinfo, iinfo->ii_btop);
027c5e7a
AM
18442+ mode = (inode->i_mode & S_IFMT);
18443+ isdir = S_ISDIR(mode);
4a4d8108 18444+ flags = au_hi_flags(inode, isdir);
5afbbe0d
AM
18445+ bbot = au_dbbot(dentry);
18446+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) {
5527c038 18447+ struct inode *h_i, *h_inode;
4a4d8108
AM
18448+ struct dentry *h_d;
18449+
18450+ h_d = au_h_dptr(dentry, bindex);
5527c038 18451+ if (!h_d || d_is_negative(h_d))
4a4d8108
AM
18452+ continue;
18453+
5527c038
JR
18454+ h_inode = d_inode(h_d);
18455+ AuDebugOn(mode != (h_inode->i_mode & S_IFMT));
5afbbe0d 18456+ if (iinfo->ii_btop <= bindex && bindex <= iinfo->ii_bbot) {
4a4d8108
AM
18457+ h_i = au_h_iptr(inode, bindex);
18458+ if (h_i) {
5527c038 18459+ if (h_i == h_inode)
4a4d8108
AM
18460+ continue;
18461+ err = -EIO;
18462+ break;
18463+ }
18464+ }
5afbbe0d
AM
18465+ if (bindex < iinfo->ii_btop)
18466+ iinfo->ii_btop = bindex;
18467+ if (iinfo->ii_bbot < bindex)
18468+ iinfo->ii_bbot = bindex;
5527c038 18469+ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags);
4a4d8108 18470+ update = 1;
1308ab2a 18471+ }
4a4d8108
AM
18472+ au_update_ibrange(inode, /*do_put_zero*/0);
18473+ e = au_dy_irefresh(inode);
18474+ if (unlikely(e && !err))
18475+ err = e;
027c5e7a
AM
18476+ if (!err)
18477+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 18478+
4f0767ce 18479+out:
4a4d8108 18480+ AuTraceErr(err);
1308ab2a 18481+ return err;
dece6358
AM
18482+}
18483+
4a4d8108 18484+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 18485+{
4a4d8108
AM
18486+ int err;
18487+ unsigned int flags;
18488+ umode_t mode;
5afbbe0d 18489+ aufs_bindex_t bindex, btop, btail;
4a4d8108
AM
18490+ unsigned char isdir;
18491+ struct dentry *h_dentry;
18492+ struct inode *h_inode;
18493+ struct au_iinfo *iinfo;
b95c5147 18494+ struct inode_operations *iop;
dece6358 18495+
4a4d8108 18496+ IiMustWriteLock(inode);
dece6358 18497+
4a4d8108
AM
18498+ err = 0;
18499+ isdir = 0;
b95c5147 18500+ iop = au_sbi(inode->i_sb)->si_iop_array;
5afbbe0d
AM
18501+ btop = au_dbtop(dentry);
18502+ h_dentry = au_h_dptr(dentry, btop);
5527c038 18503+ h_inode = d_inode(h_dentry);
4a4d8108
AM
18504+ mode = h_inode->i_mode;
18505+ switch (mode & S_IFMT) {
18506+ case S_IFREG:
18507+ btail = au_dbtail(dentry);
b95c5147 18508+ inode->i_op = iop + AuIop_OTHER;
4a4d8108 18509+ inode->i_fop = &aufs_file_fop;
5afbbe0d 18510+ err = au_dy_iaop(inode, btop, h_inode);
4a4d8108
AM
18511+ if (unlikely(err))
18512+ goto out;
18513+ break;
18514+ case S_IFDIR:
18515+ isdir = 1;
18516+ btail = au_dbtaildir(dentry);
b95c5147 18517+ inode->i_op = iop + AuIop_DIR;
4a4d8108
AM
18518+ inode->i_fop = &aufs_dir_fop;
18519+ break;
18520+ case S_IFLNK:
18521+ btail = au_dbtail(dentry);
b95c5147 18522+ inode->i_op = iop + AuIop_SYMLINK;
4a4d8108
AM
18523+ break;
18524+ case S_IFBLK:
18525+ case S_IFCHR:
18526+ case S_IFIFO:
18527+ case S_IFSOCK:
18528+ btail = au_dbtail(dentry);
b95c5147 18529+ inode->i_op = iop + AuIop_OTHER;
38d290e6 18530+ init_special_inode(inode, mode, h_inode->i_rdev);
4a4d8108
AM
18531+ break;
18532+ default:
18533+ AuIOErr("Unknown file type 0%o\n", mode);
18534+ err = -EIO;
1308ab2a 18535+ goto out;
4a4d8108 18536+ }
dece6358 18537+
4a4d8108
AM
18538+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
18539+ flags = au_hi_flags(inode, isdir);
18540+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
18541+ && au_ftest_hi(flags, HNOTIFY)
18542+ && dentry->d_name.len > AUFS_WH_PFX_LEN
18543+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
18544+ au_fclr_hi(flags, HNOTIFY);
18545+ iinfo = au_ii(inode);
5afbbe0d
AM
18546+ iinfo->ii_btop = btop;
18547+ iinfo->ii_bbot = btail;
18548+ for (bindex = btop; bindex <= btail; bindex++) {
4a4d8108
AM
18549+ h_dentry = au_h_dptr(dentry, bindex);
18550+ if (h_dentry)
18551+ au_set_h_iptr(inode, bindex,
5527c038 18552+ au_igrab(d_inode(h_dentry)), flags);
4a4d8108
AM
18553+ }
18554+ au_cpup_attr_all(inode, /*force*/1);
c1595e42
JR
18555+ /*
18556+ * to force calling aufs_get_acl() every time,
18557+ * do not call cache_no_acl() for aufs inode.
18558+ */
dece6358 18559+
4f0767ce 18560+out:
4a4d8108
AM
18561+ return err;
18562+}
dece6358 18563+
027c5e7a
AM
18564+/*
18565+ * successful returns with iinfo write_locked
18566+ * minus: errno
18567+ * zero: success, matched
18568+ * plus: no error, but unmatched
18569+ */
18570+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
18571+{
18572+ int err;
cfc41e69 18573+ unsigned int gen, igflags;
5afbbe0d 18574+ aufs_bindex_t bindex, bbot;
4a4d8108 18575+ struct inode *h_inode, *h_dinode;
5527c038 18576+ struct dentry *h_dentry;
dece6358 18577+
4a4d8108
AM
18578+ /*
18579+ * before this function, if aufs got any iinfo lock, it must be only
18580+ * one, the parent dir.
18581+ * it can happen by UDBA and the obsoleted inode number.
18582+ */
18583+ err = -EIO;
18584+ if (unlikely(inode->i_ino == parent_ino(dentry)))
18585+ goto out;
18586+
027c5e7a 18587+ err = 1;
4a4d8108 18588+ ii_write_lock_new_child(inode);
5afbbe0d 18589+ h_dentry = au_h_dptr(dentry, au_dbtop(dentry));
5527c038 18590+ h_dinode = d_inode(h_dentry);
5afbbe0d
AM
18591+ bbot = au_ibbot(inode);
18592+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
4a4d8108 18593+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
18594+ if (!h_inode || h_inode != h_dinode)
18595+ continue;
18596+
18597+ err = 0;
cfc41e69 18598+ gen = au_iigen(inode, &igflags);
537831f9 18599+ if (gen == au_digen(dentry)
cfc41e69 18600+ && !au_ig_ftest(igflags, HALF_REFRESHED))
4a4d8108 18601+ break;
537831f9
AM
18602+
18603+ /* fully refresh inode using dentry */
18604+ err = au_refresh_hinode(inode, dentry);
18605+ if (!err)
18606+ au_update_iigen(inode, /*half*/0);
18607+ break;
1facf9fc 18608+ }
dece6358 18609+
4a4d8108
AM
18610+ if (unlikely(err))
18611+ ii_write_unlock(inode);
4f0767ce 18612+out:
1facf9fc 18613+ return err;
18614+}
1facf9fc 18615+
4a4d8108
AM
18616+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
18617+ unsigned int d_type, ino_t *ino)
1facf9fc 18618+{
521ced18
JR
18619+ int err, idx;
18620+ const int isnondir = d_type != DT_DIR;
1facf9fc 18621+
b752ccd1 18622+ /* prevent hardlinked inode number from race condition */
521ced18
JR
18623+ if (isnondir) {
18624+ err = au_xinondir_enter(sb, bindex, h_ino, &idx);
18625+ if (unlikely(err))
18626+ goto out;
4a4d8108 18627+ }
521ced18 18628+
4a4d8108
AM
18629+ err = au_xino_read(sb, bindex, h_ino, ino);
18630+ if (unlikely(err))
521ced18 18631+ goto out_xinondir;
1308ab2a 18632+
4a4d8108
AM
18633+ if (!*ino) {
18634+ err = -EIO;
18635+ *ino = au_xino_new_ino(sb);
18636+ if (unlikely(!*ino))
521ced18 18637+ goto out_xinondir;
4a4d8108
AM
18638+ err = au_xino_write(sb, bindex, h_ino, *ino);
18639+ if (unlikely(err))
521ced18 18640+ goto out_xinondir;
1308ab2a 18641+ }
1facf9fc 18642+
521ced18
JR
18643+out_xinondir:
18644+ if (isnondir && idx >= 0)
18645+ au_xinondir_leave(sb, bindex, h_ino, idx);
4f0767ce 18646+out:
1facf9fc 18647+ return err;
18648+}
18649+
4a4d8108
AM
18650+/* successful returns with iinfo write_locked */
18651+/* todo: return with unlocked? */
18652+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 18653+{
5527c038 18654+ struct inode *inode, *h_inode;
4a4d8108
AM
18655+ struct dentry *h_dentry;
18656+ struct super_block *sb;
18657+ ino_t h_ino, ino;
521ced18 18658+ int err, idx, hlinked;
5afbbe0d 18659+ aufs_bindex_t btop;
1facf9fc 18660+
4a4d8108 18661+ sb = dentry->d_sb;
5afbbe0d
AM
18662+ btop = au_dbtop(dentry);
18663+ h_dentry = au_h_dptr(dentry, btop);
5527c038
JR
18664+ h_inode = d_inode(h_dentry);
18665+ h_ino = h_inode->i_ino;
521ced18 18666+ hlinked = !d_is_dir(h_dentry) && h_inode->i_nlink > 1;
b752ccd1 18667+
521ced18 18668+new_ino:
b752ccd1
AM
18669+ /*
18670+ * stop 'race'-ing between hardlinks under different
18671+ * parents.
18672+ */
521ced18
JR
18673+ if (hlinked) {
18674+ err = au_xinondir_enter(sb, btop, h_ino, &idx);
18675+ inode = ERR_PTR(err);
18676+ if (unlikely(err))
18677+ goto out;
18678+ }
b752ccd1 18679+
5afbbe0d 18680+ err = au_xino_read(sb, btop, h_ino, &ino);
4a4d8108
AM
18681+ inode = ERR_PTR(err);
18682+ if (unlikely(err))
521ced18 18683+ goto out_xinondir;
b752ccd1 18684+
4a4d8108
AM
18685+ if (!ino) {
18686+ ino = au_xino_new_ino(sb);
18687+ if (unlikely(!ino)) {
18688+ inode = ERR_PTR(-EIO);
521ced18 18689+ goto out_xinondir;
dece6358
AM
18690+ }
18691+ }
1facf9fc 18692+
4a4d8108
AM
18693+ AuDbg("i%lu\n", (unsigned long)ino);
18694+ inode = au_iget_locked(sb, ino);
18695+ err = PTR_ERR(inode);
18696+ if (IS_ERR(inode))
521ced18 18697+ goto out_xinondir;
1facf9fc 18698+
4a4d8108
AM
18699+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
18700+ if (inode->i_state & I_NEW) {
18701+ ii_write_lock_new_child(inode);
18702+ err = set_inode(inode, dentry);
18703+ if (!err) {
18704+ unlock_new_inode(inode);
521ced18 18705+ goto out_xinondir; /* success */
4a4d8108 18706+ }
1308ab2a 18707+
027c5e7a
AM
18708+ /*
18709+ * iget_failed() calls iput(), but we need to call
18710+ * ii_write_unlock() after iget_failed(). so dirty hack for
18711+ * i_count.
18712+ */
18713+ atomic_inc(&inode->i_count);
4a4d8108 18714+ iget_failed(inode);
027c5e7a 18715+ ii_write_unlock(inode);
5afbbe0d 18716+ au_xino_write(sb, btop, h_ino, /*ino*/0);
027c5e7a
AM
18717+ /* ignore this error */
18718+ goto out_iput;
18719+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
18720+ /*
18721+ * horrible race condition between lookup, readdir and copyup
18722+ * (or something).
18723+ */
521ced18
JR
18724+ if (hlinked && idx >= 0)
18725+ au_xinondir_leave(sb, btop, h_ino, idx);
027c5e7a
AM
18726+ err = reval_inode(inode, dentry);
18727+ if (unlikely(err < 0)) {
521ced18 18728+ hlinked = 0;
027c5e7a
AM
18729+ goto out_iput;
18730+ }
521ced18 18731+ if (!err)
4a4d8108 18732+ goto out; /* success */
521ced18
JR
18733+ else if (hlinked && idx >= 0) {
18734+ err = au_xinondir_enter(sb, btop, h_ino, &idx);
18735+ if (unlikely(err)) {
18736+ iput(inode);
18737+ inode = ERR_PTR(err);
18738+ goto out;
18739+ }
18740+ }
4a4d8108
AM
18741+ }
18742+
5527c038 18743+ if (unlikely(au_test_fs_unique_ino(h_inode)))
4a4d8108 18744+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3 18745+ " b%d, %s, %pd, hi%lu, i%lu.\n",
5afbbe0d 18746+ btop, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
18747+ (unsigned long)h_ino, (unsigned long)ino);
18748+ ino = 0;
5afbbe0d 18749+ err = au_xino_write(sb, btop, h_ino, /*ino*/0);
4a4d8108
AM
18750+ if (!err) {
18751+ iput(inode);
521ced18
JR
18752+ if (hlinked && idx >= 0)
18753+ au_xinondir_leave(sb, btop, h_ino, idx);
4a4d8108
AM
18754+ goto new_ino;
18755+ }
1308ab2a 18756+
4f0767ce 18757+out_iput:
4a4d8108 18758+ iput(inode);
4a4d8108 18759+ inode = ERR_PTR(err);
521ced18
JR
18760+out_xinondir:
18761+ if (hlinked && idx >= 0)
18762+ au_xinondir_leave(sb, btop, h_ino, idx);
4f0767ce 18763+out:
4a4d8108 18764+ return inode;
1facf9fc 18765+}
18766+
4a4d8108 18767+/* ---------------------------------------------------------------------- */
1facf9fc 18768+
4a4d8108
AM
18769+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
18770+ struct inode *inode)
18771+{
18772+ int err;
076b876e 18773+ struct inode *hi;
1facf9fc 18774+
4a4d8108 18775+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 18776+
4a4d8108
AM
18777+ /* pseudo-link after flushed may happen out of bounds */
18778+ if (!err
18779+ && inode
5afbbe0d
AM
18780+ && au_ibtop(inode) <= bindex
18781+ && bindex <= au_ibbot(inode)) {
4a4d8108
AM
18782+ /*
18783+ * permission check is unnecessary since vfsub routine
18784+ * will be called later
18785+ */
076b876e 18786+ hi = au_h_iptr(inode, bindex);
4a4d8108
AM
18787+ if (hi)
18788+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 18789+ }
18790+
4a4d8108
AM
18791+ return err;
18792+}
dece6358 18793+
4a4d8108
AM
18794+int au_test_h_perm(struct inode *h_inode, int mask)
18795+{
2dfbb274 18796+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
18797+ return 0;
18798+ return inode_permission(h_inode, mask);
18799+}
1facf9fc 18800+
4a4d8108
AM
18801+int au_test_h_perm_sio(struct inode *h_inode, int mask)
18802+{
18803+ if (au_test_nfs(h_inode->i_sb)
18804+ && (mask & MAY_WRITE)
18805+ && S_ISDIR(h_inode->i_mode))
18806+ mask |= MAY_READ; /* force permission check */
18807+ return au_test_h_perm(h_inode, mask);
1facf9fc 18808+}
7f207e10
AM
18809diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
18810--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 18811+++ linux/fs/aufs/inode.h 2019-03-05 12:13:00.142557771 +0100
9f237c51 18812@@ -0,0 +1,698 @@
062440b3 18813+/* SPDX-License-Identifier: GPL-2.0 */
4a4d8108 18814+/*
ba1aed25 18815+ * Copyright (C) 2005-2019 Junjiro R. Okajima
4a4d8108
AM
18816+ *
18817+ * This program, aufs is free software; you can redistribute it and/or modify
18818+ * it under the terms of the GNU General Public License as published by
18819+ * the Free Software Foundation; either version 2 of the License, or
18820+ * (at your option) any later version.
18821+ *
18822+ * This program is distributed in the hope that it will be useful,
18823+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18824+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18825+ * GNU General Public License for more details.
18826+ *
18827+ * You should have received a copy of the GNU General Public License
523b37e3 18828+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 18829+ */
1facf9fc 18830+
1308ab2a 18831+/*
4a4d8108 18832+ * inode operations
1308ab2a 18833+ */
dece6358 18834+
4a4d8108
AM
18835+#ifndef __AUFS_INODE_H__
18836+#define __AUFS_INODE_H__
dece6358 18837+
4a4d8108 18838+#ifdef __KERNEL__
1308ab2a 18839+
4a4d8108 18840+#include <linux/fsnotify.h>
4a4d8108 18841+#include "rwsem.h"
1308ab2a 18842+
4a4d8108 18843+struct vfsmount;
1facf9fc 18844+
4a4d8108
AM
18845+struct au_hnotify {
18846+#ifdef CONFIG_AUFS_HNOTIFY
18847+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 18848+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 18849+ struct fsnotify_mark hn_mark;
4a4d8108 18850+#endif
1c60b727 18851+ struct inode *hn_aufs_inode; /* no get/put */
9f237c51 18852+ struct rcu_head rcu;
4a4d8108
AM
18853+#endif
18854+} ____cacheline_aligned_in_smp;
1facf9fc 18855+
4a4d8108
AM
18856+struct au_hinode {
18857+ struct inode *hi_inode;
18858+ aufs_bindex_t hi_id;
18859+#ifdef CONFIG_AUFS_HNOTIFY
18860+ struct au_hnotify *hi_notify;
18861+#endif
dece6358 18862+
4a4d8108
AM
18863+ /* reference to the copied-up whiteout with get/put */
18864+ struct dentry *hi_whdentry;
18865+};
dece6358 18866+
537831f9
AM
18867+/* ig_flags */
18868+#define AuIG_HALF_REFRESHED 1
18869+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
18870+#define au_ig_fset(flags, name) \
18871+ do { (flags) |= AuIG_##name; } while (0)
18872+#define au_ig_fclr(flags, name) \
18873+ do { (flags) &= ~AuIG_##name; } while (0)
18874+
18875+struct au_iigen {
be52b249 18876+ spinlock_t ig_spin;
537831f9
AM
18877+ __u32 ig_generation, ig_flags;
18878+};
18879+
4a4d8108
AM
18880+struct au_vdir;
18881+struct au_iinfo {
7a9e40b8 18882+ struct au_iigen ii_generation;
4a4d8108 18883+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 18884+
4a4d8108 18885+ struct au_rwsem ii_rwsem;
5afbbe0d 18886+ aufs_bindex_t ii_btop, ii_bbot;
4a4d8108
AM
18887+ __u32 ii_higen;
18888+ struct au_hinode *ii_hinode;
18889+ struct au_vdir *ii_vdir;
18890+};
1facf9fc 18891+
4a4d8108 18892+struct au_icntnr {
9f237c51
AM
18893+ struct au_iinfo iinfo;
18894+ struct inode vfs_inode;
18895+ struct hlist_bl_node plink;
18896+ struct rcu_head rcu;
4a4d8108 18897+} ____cacheline_aligned_in_smp;
1308ab2a 18898+
4a4d8108
AM
18899+/* au_pin flags */
18900+#define AuPin_DI_LOCKED 1
18901+#define AuPin_MNT_WRITE (1 << 1)
18902+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
18903+#define au_fset_pin(flags, name) \
18904+ do { (flags) |= AuPin_##name; } while (0)
18905+#define au_fclr_pin(flags, name) \
18906+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
18907+
18908+struct au_pin {
18909+ /* input */
18910+ struct dentry *dentry;
18911+ unsigned int udba;
18912+ unsigned char lsc_di, lsc_hi, flags;
18913+ aufs_bindex_t bindex;
18914+
18915+ /* output */
18916+ struct dentry *parent;
18917+ struct au_hinode *hdir;
18918+ struct vfsmount *h_mnt;
86dc4139
AM
18919+
18920+ /* temporary unlock/relock for copyup */
18921+ struct dentry *h_dentry, *h_parent;
18922+ struct au_branch *br;
18923+ struct task_struct *task;
4a4d8108 18924+};
1facf9fc 18925+
86dc4139 18926+void au_pin_hdir_unlock(struct au_pin *p);
c1595e42 18927+int au_pin_hdir_lock(struct au_pin *p);
86dc4139 18928+int au_pin_hdir_relock(struct au_pin *p);
86dc4139
AM
18929+void au_pin_hdir_acquire_nest(struct au_pin *p);
18930+void au_pin_hdir_release(struct au_pin *p);
18931+
1308ab2a 18932+/* ---------------------------------------------------------------------- */
18933+
4a4d8108 18934+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 18935+{
5afbbe0d
AM
18936+ BUG_ON(is_bad_inode(inode));
18937+ return &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
4a4d8108 18938+}
1facf9fc 18939+
4a4d8108 18940+/* ---------------------------------------------------------------------- */
1facf9fc 18941+
4a4d8108
AM
18942+/* inode.c */
18943+struct inode *au_igrab(struct inode *inode);
b95c5147 18944+void au_refresh_iop(struct inode *inode, int force_getattr);
027c5e7a 18945+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
18946+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
18947+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
18948+ unsigned int d_type, ino_t *ino);
18949+struct inode *au_new_inode(struct dentry *dentry, int must_new);
18950+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
18951+ struct inode *inode);
18952+int au_test_h_perm(struct inode *h_inode, int mask);
18953+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 18954+
4a4d8108
AM
18955+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
18956+ ino_t h_ino, unsigned int d_type, ino_t *ino)
18957+{
18958+#ifdef CONFIG_AUFS_SHWH
18959+ return au_ino(sb, bindex, h_ino, d_type, ino);
18960+#else
18961+ return 0;
18962+#endif
18963+}
1facf9fc 18964+
4a4d8108 18965+/* i_op.c */
b95c5147
AM
18966+enum {
18967+ AuIop_SYMLINK,
18968+ AuIop_DIR,
18969+ AuIop_OTHER,
18970+ AuIop_Last
18971+};
18972+extern struct inode_operations aufs_iop[AuIop_Last],
18973+ aufs_iop_nogetattr[AuIop_Last];
1308ab2a 18974+
4a4d8108
AM
18975+/* au_wr_dir flags */
18976+#define AuWrDir_ADD_ENTRY 1
7e9cd9fe
AM
18977+#define AuWrDir_ISDIR (1 << 1)
18978+#define AuWrDir_TMPFILE (1 << 2)
4a4d8108 18979+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
18980+#define au_fset_wrdir(flags, name) \
18981+ do { (flags) |= AuWrDir_##name; } while (0)
18982+#define au_fclr_wrdir(flags, name) \
18983+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 18984+
4a4d8108
AM
18985+struct au_wr_dir_args {
18986+ aufs_bindex_t force_btgt;
18987+ unsigned char flags;
18988+};
18989+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
18990+ struct au_wr_dir_args *args);
dece6358 18991+
4a4d8108
AM
18992+struct dentry *au_pinned_h_parent(struct au_pin *pin);
18993+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
18994+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
18995+ unsigned int udba, unsigned char flags);
18996+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
18997+ unsigned int udba, unsigned char flags) __must_check;
18998+int au_do_pin(struct au_pin *pin) __must_check;
18999+void au_unpin(struct au_pin *pin);
c1595e42
JR
19000+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
19001+
19002+#define AuIcpup_DID_CPUP 1
19003+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
19004+#define au_fset_icpup(flags, name) \
19005+ do { (flags) |= AuIcpup_##name; } while (0)
19006+#define au_fclr_icpup(flags, name) \
19007+ do { (flags) &= ~AuIcpup_##name; } while (0)
19008+
19009+struct au_icpup_args {
19010+ unsigned char flags;
19011+ unsigned char pin_flags;
19012+ aufs_bindex_t btgt;
19013+ unsigned int udba;
19014+ struct au_pin pin;
19015+ struct path h_path;
19016+ struct inode *h_inode;
19017+};
19018+
19019+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
19020+ struct au_icpup_args *a);
19021+
a2654f78
AM
19022+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
19023+ int locked);
1facf9fc 19024+
4a4d8108
AM
19025+/* i_op_add.c */
19026+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
19027+ struct dentry *h_parent, int isdir);
7eafdf33
AM
19028+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
19029+ dev_t dev);
4a4d8108 19030+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 19031+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 19032+ bool want_excl);
b912730e
AM
19033+struct vfsub_aopen_args;
19034+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
19035+ struct vfsub_aopen_args *args);
38d290e6 19036+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
4a4d8108
AM
19037+int aufs_link(struct dentry *src_dentry, struct inode *dir,
19038+ struct dentry *dentry);
7eafdf33 19039+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 19040+
4a4d8108
AM
19041+/* i_op_del.c */
19042+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
19043+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
19044+ struct dentry *h_parent, int isdir);
19045+int aufs_unlink(struct inode *dir, struct dentry *dentry);
19046+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 19047+
4a4d8108
AM
19048+/* i_op_ren.c */
19049+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
19050+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
f2c43d5f
AM
19051+ struct inode *dir, struct dentry *dentry,
19052+ unsigned int flags);
1facf9fc 19053+
4a4d8108
AM
19054+/* iinfo.c */
19055+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
19056+void au_hiput(struct au_hinode *hinode);
19057+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
19058+ struct dentry *h_wh);
19059+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 19060+
4a4d8108
AM
19061+/* hinode flags */
19062+#define AuHi_XINO 1
19063+#define AuHi_HNOTIFY (1 << 1)
19064+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
19065+#define au_fset_hi(flags, name) \
19066+ do { (flags) |= AuHi_##name; } while (0)
19067+#define au_fclr_hi(flags, name) \
19068+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 19069+
4a4d8108
AM
19070+#ifndef CONFIG_AUFS_HNOTIFY
19071+#undef AuHi_HNOTIFY
19072+#define AuHi_HNOTIFY 0
19073+#endif
1facf9fc 19074+
4a4d8108
AM
19075+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
19076+ struct inode *h_inode, unsigned int flags);
1facf9fc 19077+
537831f9 19078+void au_update_iigen(struct inode *inode, int half);
4a4d8108 19079+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 19080+
4a4d8108 19081+void au_icntnr_init_once(void *_c);
5afbbe0d 19082+void au_hinode_init(struct au_hinode *hinode);
4a4d8108
AM
19083+int au_iinfo_init(struct inode *inode);
19084+void au_iinfo_fin(struct inode *inode);
e2f27e51 19085+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink);
1308ab2a 19086+
e49829fe 19087+#ifdef CONFIG_PROC_FS
4a4d8108 19088+/* plink.c */
e49829fe 19089+int au_plink_maint(struct super_block *sb, int flags);
7e9cd9fe 19090+struct au_sbinfo;
e49829fe
JR
19091+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
19092+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
19093+#ifdef CONFIG_AUFS_DEBUG
19094+void au_plink_list(struct super_block *sb);
19095+#else
19096+AuStubVoid(au_plink_list, struct super_block *sb)
19097+#endif
19098+int au_plink_test(struct inode *inode);
19099+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
19100+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
19101+ struct dentry *h_dentry);
e49829fe
JR
19102+void au_plink_put(struct super_block *sb, int verbose);
19103+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 19104+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
19105+#else
19106+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
19107+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
19108+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
19109+AuStubVoid(au_plink_list, struct super_block *sb);
19110+AuStubInt0(au_plink_test, struct inode *inode);
19111+AuStub(struct dentry *, au_plink_lkup, return NULL,
19112+ struct inode *inode, aufs_bindex_t bindex);
19113+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
19114+ struct dentry *h_dentry);
19115+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
19116+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
19117+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
19118+#endif /* CONFIG_PROC_FS */
1facf9fc 19119+
c1595e42
JR
19120+#ifdef CONFIG_AUFS_XATTR
19121+/* xattr.c */
7e9cd9fe
AM
19122+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
19123+ unsigned int verbose);
c1595e42 19124+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
f2c43d5f 19125+void au_xattr_init(struct super_block *sb);
c1595e42
JR
19126+#else
19127+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe 19128+ int ignore_flags, unsigned int verbose);
f2c43d5f 19129+AuStubVoid(au_xattr_init, struct super_block *sb);
c1595e42
JR
19130+#endif
19131+
19132+#ifdef CONFIG_FS_POSIX_ACL
19133+struct posix_acl *aufs_get_acl(struct inode *inode, int type);
19134+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
19135+#endif
19136+
19137+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
19138+enum {
19139+ AU_XATTR_SET,
c1595e42
JR
19140+ AU_ACL_SET
19141+};
19142+
f2c43d5f 19143+struct au_sxattr {
c1595e42
JR
19144+ int type;
19145+ union {
19146+ struct {
19147+ const char *name;
19148+ const void *value;
19149+ size_t size;
19150+ int flags;
19151+ } set;
19152+ struct {
c1595e42
JR
19153+ struct posix_acl *acl;
19154+ int type;
19155+ } acl_set;
19156+ } u;
19157+};
f2c43d5f
AM
19158+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
19159+ struct au_sxattr *arg);
c1595e42
JR
19160+#endif
19161+
4a4d8108 19162+/* ---------------------------------------------------------------------- */
1308ab2a 19163+
4a4d8108
AM
19164+/* lock subclass for iinfo */
19165+enum {
19166+ AuLsc_II_CHILD, /* child first */
19167+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
19168+ AuLsc_II_CHILD3, /* copyup dirs */
19169+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
19170+ AuLsc_II_PARENT2,
19171+ AuLsc_II_PARENT3, /* copyup dirs */
19172+ AuLsc_II_NEW_CHILD
19173+};
1308ab2a 19174+
1facf9fc 19175+/*
4a4d8108
AM
19176+ * ii_read_lock_child, ii_write_lock_child,
19177+ * ii_read_lock_child2, ii_write_lock_child2,
19178+ * ii_read_lock_child3, ii_write_lock_child3,
19179+ * ii_read_lock_parent, ii_write_lock_parent,
19180+ * ii_read_lock_parent2, ii_write_lock_parent2,
19181+ * ii_read_lock_parent3, ii_write_lock_parent3,
19182+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 19183+ */
4a4d8108
AM
19184+#define AuReadLockFunc(name, lsc) \
19185+static inline void ii_read_lock_##name(struct inode *i) \
19186+{ \
19187+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
19188+}
19189+
19190+#define AuWriteLockFunc(name, lsc) \
19191+static inline void ii_write_lock_##name(struct inode *i) \
19192+{ \
19193+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
19194+}
19195+
19196+#define AuRWLockFuncs(name, lsc) \
19197+ AuReadLockFunc(name, lsc) \
19198+ AuWriteLockFunc(name, lsc)
19199+
19200+AuRWLockFuncs(child, CHILD);
19201+AuRWLockFuncs(child2, CHILD2);
19202+AuRWLockFuncs(child3, CHILD3);
19203+AuRWLockFuncs(parent, PARENT);
19204+AuRWLockFuncs(parent2, PARENT2);
19205+AuRWLockFuncs(parent3, PARENT3);
19206+AuRWLockFuncs(new_child, NEW_CHILD);
19207+
19208+#undef AuReadLockFunc
19209+#undef AuWriteLockFunc
19210+#undef AuRWLockFuncs
1facf9fc 19211+
8b6a4947
AM
19212+#define ii_read_unlock(i) au_rw_read_unlock(&au_ii(i)->ii_rwsem)
19213+#define ii_write_unlock(i) au_rw_write_unlock(&au_ii(i)->ii_rwsem)
19214+#define ii_downgrade_lock(i) au_rw_dgrade_lock(&au_ii(i)->ii_rwsem)
1facf9fc 19215+
4a4d8108
AM
19216+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
19217+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
19218+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 19219+
4a4d8108 19220+/* ---------------------------------------------------------------------- */
1308ab2a 19221+
027c5e7a
AM
19222+static inline void au_icntnr_init(struct au_icntnr *c)
19223+{
19224+#ifdef CONFIG_AUFS_DEBUG
19225+ c->vfs_inode.i_mode = 0;
19226+#endif
19227+}
19228+
cfc41e69 19229+static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags)
4a4d8108 19230+{
537831f9
AM
19231+ unsigned int gen;
19232+ struct au_iinfo *iinfo;
be52b249 19233+ struct au_iigen *iigen;
537831f9
AM
19234+
19235+ iinfo = au_ii(inode);
be52b249
AM
19236+ iigen = &iinfo->ii_generation;
19237+ spin_lock(&iigen->ig_spin);
cfc41e69
AM
19238+ if (igflags)
19239+ *igflags = iigen->ig_flags;
be52b249
AM
19240+ gen = iigen->ig_generation;
19241+ spin_unlock(&iigen->ig_spin);
537831f9
AM
19242+
19243+ return gen;
4a4d8108 19244+}
1308ab2a 19245+
4a4d8108
AM
19246+/* tiny test for inode number */
19247+/* tmpfs generation is too rough */
19248+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
19249+{
19250+ struct au_iinfo *iinfo;
1308ab2a 19251+
4a4d8108
AM
19252+ iinfo = au_ii(inode);
19253+ AuRwMustAnyLock(&iinfo->ii_rwsem);
19254+ return !(iinfo->ii_hsb1 == h_inode->i_sb
19255+ && iinfo->ii_higen == h_inode->i_generation);
19256+}
1308ab2a 19257+
4a4d8108
AM
19258+static inline void au_iigen_dec(struct inode *inode)
19259+{
537831f9 19260+ struct au_iinfo *iinfo;
be52b249 19261+ struct au_iigen *iigen;
537831f9
AM
19262+
19263+ iinfo = au_ii(inode);
be52b249
AM
19264+ iigen = &iinfo->ii_generation;
19265+ spin_lock(&iigen->ig_spin);
19266+ iigen->ig_generation--;
19267+ spin_unlock(&iigen->ig_spin);
027c5e7a
AM
19268+}
19269+
19270+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
19271+{
19272+ int err;
19273+
19274+ err = 0;
537831f9 19275+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
19276+ err = -EIO;
19277+
19278+ return err;
4a4d8108 19279+}
1308ab2a 19280+
4a4d8108 19281+/* ---------------------------------------------------------------------- */
1308ab2a 19282+
5afbbe0d
AM
19283+static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo,
19284+ aufs_bindex_t bindex)
19285+{
19286+ return iinfo->ii_hinode + bindex;
19287+}
19288+
19289+static inline int au_is_bad_inode(struct inode *inode)
19290+{
19291+ return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0));
19292+}
19293+
4a4d8108
AM
19294+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
19295+ aufs_bindex_t bindex)
19296+{
19297+ IiMustAnyLock(inode);
5afbbe0d 19298+ return au_hinode(au_ii(inode), bindex)->hi_id;
4a4d8108 19299+}
1308ab2a 19300+
5afbbe0d 19301+static inline aufs_bindex_t au_ibtop(struct inode *inode)
4a4d8108
AM
19302+{
19303+ IiMustAnyLock(inode);
5afbbe0d 19304+ return au_ii(inode)->ii_btop;
4a4d8108 19305+}
1308ab2a 19306+
5afbbe0d 19307+static inline aufs_bindex_t au_ibbot(struct inode *inode)
4a4d8108
AM
19308+{
19309+ IiMustAnyLock(inode);
5afbbe0d 19310+ return au_ii(inode)->ii_bbot;
4a4d8108 19311+}
1308ab2a 19312+
4a4d8108
AM
19313+static inline struct au_vdir *au_ivdir(struct inode *inode)
19314+{
19315+ IiMustAnyLock(inode);
19316+ return au_ii(inode)->ii_vdir;
19317+}
1308ab2a 19318+
4a4d8108
AM
19319+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
19320+{
19321+ IiMustAnyLock(inode);
5afbbe0d 19322+ return au_hinode(au_ii(inode), bindex)->hi_whdentry;
4a4d8108 19323+}
1308ab2a 19324+
5afbbe0d 19325+static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 19326+{
4a4d8108 19327+ IiMustWriteLock(inode);
5afbbe0d 19328+ au_ii(inode)->ii_btop = bindex;
4a4d8108 19329+}
1308ab2a 19330+
5afbbe0d 19331+static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex)
4a4d8108
AM
19332+{
19333+ IiMustWriteLock(inode);
5afbbe0d 19334+ au_ii(inode)->ii_bbot = bindex;
1308ab2a 19335+}
19336+
4a4d8108
AM
19337+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
19338+{
19339+ IiMustWriteLock(inode);
19340+ au_ii(inode)->ii_vdir = vdir;
19341+}
1facf9fc 19342+
4a4d8108 19343+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 19344+{
4a4d8108 19345+ IiMustAnyLock(inode);
5afbbe0d 19346+ return au_hinode(au_ii(inode), bindex);
4a4d8108 19347+}
dece6358 19348+
4a4d8108 19349+/* ---------------------------------------------------------------------- */
1facf9fc 19350+
4a4d8108
AM
19351+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
19352+{
19353+ if (pin)
19354+ return pin->parent;
19355+ return NULL;
1facf9fc 19356+}
19357+
4a4d8108 19358+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 19359+{
4a4d8108
AM
19360+ if (pin && pin->hdir)
19361+ return pin->hdir->hi_inode;
19362+ return NULL;
1308ab2a 19363+}
1facf9fc 19364+
4a4d8108
AM
19365+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
19366+{
19367+ if (pin)
19368+ return pin->hdir;
19369+ return NULL;
19370+}
1facf9fc 19371+
4a4d8108 19372+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 19373+{
4a4d8108
AM
19374+ if (pin)
19375+ pin->dentry = dentry;
19376+}
1308ab2a 19377+
4a4d8108
AM
19378+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
19379+ unsigned char lflag)
19380+{
19381+ if (pin) {
7f207e10 19382+ if (lflag)
4a4d8108 19383+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 19384+ else
4a4d8108 19385+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 19386+ }
4a4d8108
AM
19387+}
19388+
7e9cd9fe 19389+#if 0 /* reserved */
4a4d8108
AM
19390+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
19391+{
19392+ if (pin) {
19393+ dput(pin->parent);
19394+ pin->parent = dget(parent);
1facf9fc 19395+ }
4a4d8108 19396+}
7e9cd9fe 19397+#endif
1facf9fc 19398+
4a4d8108
AM
19399+/* ---------------------------------------------------------------------- */
19400+
027c5e7a 19401+struct au_branch;
4a4d8108
AM
19402+#ifdef CONFIG_AUFS_HNOTIFY
19403+struct au_hnotify_op {
19404+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 19405+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
19406+
19407+ /*
19408+ * if it returns true, the the caller should free hinode->hi_notify,
19409+ * otherwise ->free() frees it.
19410+ */
19411+ int (*free)(struct au_hinode *hinode,
19412+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
19413+
19414+ void (*fin)(void);
19415+ int (*init)(void);
027c5e7a
AM
19416+
19417+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
19418+ void (*fin_br)(struct au_branch *br);
19419+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
19420+};
19421+
19422+/* hnotify.c */
027c5e7a 19423+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
19424+void au_hn_free(struct au_hinode *hinode);
19425+void au_hn_ctl(struct au_hinode *hinode, int do_set);
19426+void au_hn_reset(struct inode *inode, unsigned int flags);
19427+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
19428+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
19429+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
19430+int au_hnotify_init_br(struct au_branch *br, int perm);
19431+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
19432+int __init au_hnotify_init(void);
19433+void au_hnotify_fin(void);
19434+
7f207e10 19435+/* hfsnotify.c */
4a4d8108
AM
19436+extern const struct au_hnotify_op au_hnotify_op;
19437+
19438+static inline
19439+void au_hn_init(struct au_hinode *hinode)
19440+{
19441+ hinode->hi_notify = NULL;
1308ab2a 19442+}
19443+
53392da6
AM
19444+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
19445+{
19446+ return hinode->hi_notify;
19447+}
19448+
4a4d8108 19449+#else
c1595e42
JR
19450+AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
19451+ struct au_hinode *hinode __maybe_unused,
19452+ struct inode *inode __maybe_unused)
19453+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
4a4d8108
AM
19454+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
19455+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
19456+ int do_set __maybe_unused)
19457+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
19458+ unsigned int flags __maybe_unused)
027c5e7a
AM
19459+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
19460+ struct au_branch *br __maybe_unused,
19461+ int perm __maybe_unused)
19462+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
19463+ int perm __maybe_unused)
19464+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
19465+AuStubInt0(__init au_hnotify_init, void)
19466+AuStubVoid(au_hnotify_fin, void)
19467+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
19468+#endif /* CONFIG_AUFS_HNOTIFY */
19469+
19470+static inline void au_hn_suspend(struct au_hinode *hdir)
19471+{
19472+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 19473+}
19474+
4a4d8108 19475+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 19476+{
4a4d8108
AM
19477+ au_hn_ctl(hdir, /*do_set*/1);
19478+}
1308ab2a 19479+
5afbbe0d 19480+static inline void au_hn_inode_lock(struct au_hinode *hdir)
4a4d8108 19481+{
febd17d6 19482+ inode_lock(hdir->hi_inode);
4a4d8108
AM
19483+ au_hn_suspend(hdir);
19484+}
dece6358 19485+
5afbbe0d 19486+static inline void au_hn_inode_lock_nested(struct au_hinode *hdir,
4a4d8108
AM
19487+ unsigned int sc __maybe_unused)
19488+{
febd17d6 19489+ inode_lock_nested(hdir->hi_inode, sc);
4a4d8108 19490+ au_hn_suspend(hdir);
1facf9fc 19491+}
1facf9fc 19492+
8b6a4947
AM
19493+#if 0 /* unused */
19494+#include "vfsub.h"
3c1bdaff
AM
19495+static inline void au_hn_inode_lock_shared_nested(struct au_hinode *hdir,
19496+ unsigned int sc)
19497+{
be118d29 19498+ inode_lock_shared_nested(hdir->hi_inode, sc);
3c1bdaff
AM
19499+ au_hn_suspend(hdir);
19500+}
8b6a4947 19501+#endif
3c1bdaff 19502+
5afbbe0d 19503+static inline void au_hn_inode_unlock(struct au_hinode *hdir)
4a4d8108
AM
19504+{
19505+ au_hn_resume(hdir);
febd17d6 19506+ inode_unlock(hdir->hi_inode);
4a4d8108
AM
19507+}
19508+
19509+#endif /* __KERNEL__ */
19510+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
19511diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
19512--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 19513+++ linux/fs/aufs/ioctl.c 2019-03-05 12:13:00.142557771 +0100
062440b3 19514@@ -0,0 +1,220 @@
cd7a4cd9 19515+// SPDX-License-Identifier: GPL-2.0
4a4d8108 19516+/*
ba1aed25 19517+ * Copyright (C) 2005-2019 Junjiro R. Okajima
4a4d8108
AM
19518+ *
19519+ * This program, aufs is free software; you can redistribute it and/or modify
19520+ * it under the terms of the GNU General Public License as published by
19521+ * the Free Software Foundation; either version 2 of the License, or
19522+ * (at your option) any later version.
19523+ *
19524+ * This program is distributed in the hope that it will be useful,
19525+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19526+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19527+ * GNU General Public License for more details.
19528+ *
19529+ * You should have received a copy of the GNU General Public License
523b37e3 19530+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
19531+ */
19532+
19533+/*
19534+ * ioctl
19535+ * plink-management and readdir in userspace.
19536+ * assist the pathconf(3) wrapper library.
c2b27bf2 19537+ * move-down
076b876e 19538+ * File-based Hierarchical Storage Management.
4a4d8108
AM
19539+ */
19540+
c2b27bf2
AM
19541+#include <linux/compat.h>
19542+#include <linux/file.h>
4a4d8108
AM
19543+#include "aufs.h"
19544+
1e00d052 19545+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
19546+{
19547+ int err, fd;
5afbbe0d 19548+ aufs_bindex_t wbi, bindex, bbot;
4a4d8108
AM
19549+ struct file *h_file;
19550+ struct super_block *sb;
19551+ struct dentry *root;
1e00d052
AM
19552+ struct au_branch *br;
19553+ struct aufs_wbr_fd wbrfd = {
19554+ .oflags = au_dir_roflags,
19555+ .brid = -1
19556+ };
19557+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
19558+ | O_NOATIME | O_CLOEXEC;
4a4d8108 19559+
1e00d052
AM
19560+ AuDebugOn(wbrfd.oflags & ~valid);
19561+
19562+ if (arg) {
19563+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
19564+ if (unlikely(err)) {
19565+ err = -EFAULT;
19566+ goto out;
19567+ }
19568+
19569+ err = -EINVAL;
19570+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
19571+ wbrfd.oflags |= au_dir_roflags;
19572+ AuDbg("0%o\n", wbrfd.oflags);
19573+ if (unlikely(wbrfd.oflags & ~valid))
19574+ goto out;
19575+ }
19576+
2000de60 19577+ fd = get_unused_fd_flags(0);
1e00d052
AM
19578+ err = fd;
19579+ if (unlikely(fd < 0))
4a4d8108 19580+ goto out;
4a4d8108 19581+
1e00d052 19582+ h_file = ERR_PTR(-EINVAL);
4a4d8108 19583+ wbi = 0;
1e00d052 19584+ br = NULL;
4a4d8108
AM
19585+ sb = path->dentry->d_sb;
19586+ root = sb->s_root;
19587+ aufs_read_lock(root, AuLock_IR);
5afbbe0d 19588+ bbot = au_sbbot(sb);
1e00d052
AM
19589+ if (wbrfd.brid >= 0) {
19590+ wbi = au_br_index(sb, wbrfd.brid);
5afbbe0d 19591+ if (unlikely(wbi < 0 || wbi > bbot))
1e00d052
AM
19592+ goto out_unlock;
19593+ }
19594+
19595+ h_file = ERR_PTR(-ENOENT);
19596+ br = au_sbr(sb, wbi);
19597+ if (!au_br_writable(br->br_perm)) {
19598+ if (arg)
19599+ goto out_unlock;
19600+
19601+ bindex = wbi + 1;
19602+ wbi = -1;
5afbbe0d 19603+ for (; bindex <= bbot; bindex++) {
1e00d052
AM
19604+ br = au_sbr(sb, bindex);
19605+ if (au_br_writable(br->br_perm)) {
4a4d8108 19606+ wbi = bindex;
1e00d052 19607+ br = au_sbr(sb, wbi);
4a4d8108
AM
19608+ break;
19609+ }
19610+ }
4a4d8108
AM
19611+ }
19612+ AuDbg("wbi %d\n", wbi);
1e00d052 19613+ if (wbi >= 0)
392086de
AM
19614+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
19615+ /*force_wr*/0);
1e00d052
AM
19616+
19617+out_unlock:
4a4d8108
AM
19618+ aufs_read_unlock(root, AuLock_IR);
19619+ err = PTR_ERR(h_file);
19620+ if (IS_ERR(h_file))
19621+ goto out_fd;
19622+
acd2b654 19623+ au_lcnt_dec(&br->br_nfiles); /* cf. au_h_open() */
4a4d8108
AM
19624+ fd_install(fd, h_file);
19625+ err = fd;
19626+ goto out; /* success */
19627+
4f0767ce 19628+out_fd:
4a4d8108 19629+ put_unused_fd(fd);
4f0767ce 19630+out:
1e00d052 19631+ AuTraceErr(err);
4a4d8108
AM
19632+ return err;
19633+}
19634+
19635+/* ---------------------------------------------------------------------- */
19636+
19637+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
19638+{
19639+ long err;
c1595e42 19640+ struct dentry *dentry;
4a4d8108
AM
19641+
19642+ switch (cmd) {
4a4d8108
AM
19643+ case AUFS_CTL_RDU:
19644+ case AUFS_CTL_RDU_INO:
19645+ err = au_rdu_ioctl(file, cmd, arg);
19646+ break;
19647+
19648+ case AUFS_CTL_WBR_FD:
1e00d052 19649+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
19650+ break;
19651+
027c5e7a
AM
19652+ case AUFS_CTL_IBUSY:
19653+ err = au_ibusy_ioctl(file, arg);
19654+ break;
19655+
076b876e
AM
19656+ case AUFS_CTL_BRINFO:
19657+ err = au_brinfo_ioctl(file, arg);
19658+ break;
19659+
19660+ case AUFS_CTL_FHSM_FD:
2000de60 19661+ dentry = file->f_path.dentry;
c1595e42
JR
19662+ if (IS_ROOT(dentry))
19663+ err = au_fhsm_fd(dentry->d_sb, arg);
19664+ else
19665+ err = -ENOTTY;
076b876e
AM
19666+ break;
19667+
4a4d8108
AM
19668+ default:
19669+ /* do not call the lower */
19670+ AuDbg("0x%x\n", cmd);
19671+ err = -ENOTTY;
19672+ }
19673+
19674+ AuTraceErr(err);
19675+ return err;
19676+}
19677+
19678+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
19679+{
19680+ long err;
19681+
19682+ switch (cmd) {
c2b27bf2 19683+ case AUFS_CTL_MVDOWN:
2000de60 19684+ err = au_mvdown(file->f_path.dentry, (void __user *)arg);
c2b27bf2
AM
19685+ break;
19686+
4a4d8108 19687+ case AUFS_CTL_WBR_FD:
1e00d052 19688+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
19689+ break;
19690+
19691+ default:
19692+ /* do not call the lower */
19693+ AuDbg("0x%x\n", cmd);
19694+ err = -ENOTTY;
19695+ }
19696+
19697+ AuTraceErr(err);
19698+ return err;
19699+}
b752ccd1
AM
19700+
19701+#ifdef CONFIG_COMPAT
19702+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
19703+ unsigned long arg)
19704+{
19705+ long err;
19706+
19707+ switch (cmd) {
19708+ case AUFS_CTL_RDU:
19709+ case AUFS_CTL_RDU_INO:
19710+ err = au_rdu_compat_ioctl(file, cmd, arg);
19711+ break;
19712+
027c5e7a
AM
19713+ case AUFS_CTL_IBUSY:
19714+ err = au_ibusy_compat_ioctl(file, arg);
19715+ break;
19716+
076b876e
AM
19717+ case AUFS_CTL_BRINFO:
19718+ err = au_brinfo_compat_ioctl(file, arg);
19719+ break;
19720+
b752ccd1
AM
19721+ default:
19722+ err = aufs_ioctl_dir(file, cmd, arg);
19723+ }
19724+
19725+ AuTraceErr(err);
19726+ return err;
19727+}
19728+
b752ccd1
AM
19729+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
19730+ unsigned long arg)
19731+{
19732+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
19733+}
19734+#endif
7f207e10
AM
19735diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
19736--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
19737+++ linux/fs/aufs/i_op_add.c 2019-05-06 09:03:04.816810402 +0200
19738@@ -0,0 +1,936 @@
cd7a4cd9 19739+// SPDX-License-Identifier: GPL-2.0
4a4d8108 19740+/*
ba1aed25 19741+ * Copyright (C) 2005-2019 Junjiro R. Okajima
4a4d8108
AM
19742+ *
19743+ * This program, aufs is free software; you can redistribute it and/or modify
19744+ * it under the terms of the GNU General Public License as published by
19745+ * the Free Software Foundation; either version 2 of the License, or
19746+ * (at your option) any later version.
19747+ *
19748+ * This program is distributed in the hope that it will be useful,
19749+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19750+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19751+ * GNU General Public License for more details.
19752+ *
19753+ * You should have received a copy of the GNU General Public License
523b37e3 19754+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
19755+ */
19756+
19757+/*
19758+ * inode operations (add entry)
19759+ */
19760+
eca801bf 19761+#include <linux/iversion.h>
4a4d8108
AM
19762+#include "aufs.h"
19763+
19764+/*
19765+ * final procedure of adding a new entry, except link(2).
19766+ * remove whiteout, instantiate, copyup the parent dir's times and size
19767+ * and update version.
19768+ * if it failed, re-create the removed whiteout.
19769+ */
19770+static int epilog(struct inode *dir, aufs_bindex_t bindex,
19771+ struct dentry *wh_dentry, struct dentry *dentry)
19772+{
19773+ int err, rerr;
19774+ aufs_bindex_t bwh;
19775+ struct path h_path;
076b876e 19776+ struct super_block *sb;
4a4d8108
AM
19777+ struct inode *inode, *h_dir;
19778+ struct dentry *wh;
19779+
19780+ bwh = -1;
076b876e 19781+ sb = dir->i_sb;
4a4d8108 19782+ if (wh_dentry) {
5527c038 19783+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
4a4d8108
AM
19784+ IMustLock(h_dir);
19785+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
19786+ bwh = au_dbwh(dentry);
19787+ h_path.dentry = wh_dentry;
076b876e 19788+ h_path.mnt = au_sbr_mnt(sb, bindex);
4a4d8108
AM
19789+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
19790+ dentry);
19791+ if (unlikely(err))
19792+ goto out;
19793+ }
19794+
19795+ inode = au_new_inode(dentry, /*must_new*/1);
19796+ if (!IS_ERR(inode)) {
19797+ d_instantiate(dentry, inode);
5527c038 19798+ dir = d_inode(dentry->d_parent); /* dir inode is locked */
4a4d8108 19799+ IMustLock(dir);
b912730e 19800+ au_dir_ts(dir, bindex);
be118d29 19801+ inode_inc_iversion(dir);
076b876e 19802+ au_fhsm_wrote(sb, bindex, /*force*/0);
4a4d8108
AM
19803+ return 0; /* success */
19804+ }
19805+
19806+ err = PTR_ERR(inode);
19807+ if (!wh_dentry)
19808+ goto out;
19809+
19810+ /* revert */
19811+ /* dir inode is locked */
19812+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
19813+ rerr = PTR_ERR(wh);
19814+ if (IS_ERR(wh)) {
523b37e3
AM
19815+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
19816+ dentry, err, rerr);
4a4d8108
AM
19817+ err = -EIO;
19818+ } else
19819+ dput(wh);
19820+
4f0767ce 19821+out:
4a4d8108
AM
19822+ return err;
19823+}
19824+
027c5e7a
AM
19825+static int au_d_may_add(struct dentry *dentry)
19826+{
19827+ int err;
19828+
19829+ err = 0;
19830+ if (unlikely(d_unhashed(dentry)))
19831+ err = -ENOENT;
5527c038 19832+ if (unlikely(d_really_is_positive(dentry)))
027c5e7a
AM
19833+ err = -EEXIST;
19834+ return err;
19835+}
19836+
4a4d8108
AM
19837+/*
19838+ * simple tests for the adding inode operations.
19839+ * following the checks in vfs, plus the parent-child relationship.
19840+ */
19841+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
19842+ struct dentry *h_parent, int isdir)
19843+{
19844+ int err;
19845+ umode_t h_mode;
19846+ struct dentry *h_dentry;
19847+ struct inode *h_inode;
19848+
19849+ err = -ENAMETOOLONG;
19850+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
19851+ goto out;
19852+
19853+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 19854+ if (d_really_is_negative(dentry)) {
4a4d8108 19855+ err = -EEXIST;
5527c038 19856+ if (unlikely(d_is_positive(h_dentry)))
4a4d8108
AM
19857+ goto out;
19858+ } else {
19859+ /* rename(2) case */
19860+ err = -EIO;
5527c038
JR
19861+ if (unlikely(d_is_negative(h_dentry)))
19862+ goto out;
19863+ h_inode = d_inode(h_dentry);
19864+ if (unlikely(!h_inode->i_nlink))
4a4d8108
AM
19865+ goto out;
19866+
19867+ h_mode = h_inode->i_mode;
19868+ if (!isdir) {
19869+ err = -EISDIR;
19870+ if (unlikely(S_ISDIR(h_mode)))
19871+ goto out;
19872+ } else if (unlikely(!S_ISDIR(h_mode))) {
19873+ err = -ENOTDIR;
19874+ goto out;
19875+ }
19876+ }
19877+
19878+ err = 0;
19879+ /* expected parent dir is locked */
19880+ if (unlikely(h_parent != h_dentry->d_parent))
19881+ err = -EIO;
19882+
4f0767ce 19883+out:
4a4d8108
AM
19884+ AuTraceErr(err);
19885+ return err;
19886+}
19887+
19888+/*
19889+ * initial procedure of adding a new entry.
19890+ * prepare writable branch and the parent dir, lock it,
19891+ * and lookup whiteout for the new entry.
19892+ */
19893+static struct dentry*
19894+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
19895+ struct dentry *src_dentry, struct au_pin *pin,
19896+ struct au_wr_dir_args *wr_dir_args)
19897+{
19898+ struct dentry *wh_dentry, *h_parent;
19899+ struct super_block *sb;
19900+ struct au_branch *br;
19901+ int err;
19902+ unsigned int udba;
19903+ aufs_bindex_t bcpup;
19904+
523b37e3 19905+ AuDbg("%pd\n", dentry);
4a4d8108
AM
19906+
19907+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
19908+ bcpup = err;
19909+ wh_dentry = ERR_PTR(err);
19910+ if (unlikely(err < 0))
19911+ goto out;
19912+
19913+ sb = dentry->d_sb;
19914+ udba = au_opt_udba(sb);
19915+ err = au_pin(pin, dentry, bcpup, udba,
19916+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
19917+ wh_dentry = ERR_PTR(err);
19918+ if (unlikely(err))
19919+ goto out;
19920+
19921+ h_parent = au_pinned_h_parent(pin);
19922+ if (udba != AuOpt_UDBA_NONE
5afbbe0d 19923+ && au_dbtop(dentry) == bcpup)
4a4d8108
AM
19924+ err = au_may_add(dentry, bcpup, h_parent,
19925+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
19926+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
19927+ err = -ENAMETOOLONG;
19928+ wh_dentry = ERR_PTR(err);
19929+ if (unlikely(err))
19930+ goto out_unpin;
19931+
19932+ br = au_sbr(sb, bcpup);
19933+ if (dt) {
19934+ struct path tmp = {
19935+ .dentry = h_parent,
86dc4139 19936+ .mnt = au_br_mnt(br)
4a4d8108
AM
19937+ };
19938+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
19939+ }
19940+
19941+ wh_dentry = NULL;
19942+ if (bcpup != au_dbwh(dentry))
19943+ goto out; /* success */
19944+
2000de60
JR
19945+ /*
19946+ * ENAMETOOLONG here means that if we allowed create such name, then it
19947+ * would not be able to removed in the future. So we don't allow such
19948+ * name here and we don't handle ENAMETOOLONG differently here.
19949+ */
4a4d8108
AM
19950+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
19951+
4f0767ce 19952+out_unpin:
4a4d8108
AM
19953+ if (IS_ERR(wh_dentry))
19954+ au_unpin(pin);
4f0767ce 19955+out:
4a4d8108
AM
19956+ return wh_dentry;
19957+}
19958+
19959+/* ---------------------------------------------------------------------- */
19960+
19961+enum { Mknod, Symlink, Creat };
19962+struct simple_arg {
19963+ int type;
19964+ union {
19965+ struct {
b912730e
AM
19966+ umode_t mode;
19967+ bool want_excl;
19968+ bool try_aopen;
19969+ struct vfsub_aopen_args *aopen;
4a4d8108
AM
19970+ } c;
19971+ struct {
19972+ const char *symname;
19973+ } s;
19974+ struct {
7eafdf33 19975+ umode_t mode;
4a4d8108
AM
19976+ dev_t dev;
19977+ } m;
19978+ } u;
19979+};
19980+
19981+static int add_simple(struct inode *dir, struct dentry *dentry,
19982+ struct simple_arg *arg)
19983+{
076b876e 19984+ int err, rerr;
5afbbe0d 19985+ aufs_bindex_t btop;
4a4d8108 19986+ unsigned char created;
b912730e
AM
19987+ const unsigned char try_aopen
19988+ = (arg->type == Creat && arg->u.c.try_aopen);
acd2b654 19989+ struct vfsub_aopen_args *aopen = arg->u.c.aopen;
4a4d8108
AM
19990+ struct dentry *wh_dentry, *parent;
19991+ struct inode *h_dir;
b912730e
AM
19992+ struct super_block *sb;
19993+ struct au_branch *br;
acd2b654 19994+ /* to reduce stack size */
c2b27bf2
AM
19995+ struct {
19996+ struct au_dtime dt;
19997+ struct au_pin pin;
19998+ struct path h_path;
19999+ struct au_wr_dir_args wr_dir_args;
20000+ } *a;
4a4d8108 20001+
523b37e3 20002+ AuDbg("%pd\n", dentry);
4a4d8108
AM
20003+ IMustLock(dir);
20004+
c2b27bf2
AM
20005+ err = -ENOMEM;
20006+ a = kmalloc(sizeof(*a), GFP_NOFS);
20007+ if (unlikely(!a))
20008+ goto out;
20009+ a->wr_dir_args.force_btgt = -1;
20010+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
20011+
4a4d8108 20012+ parent = dentry->d_parent; /* dir inode is locked */
b912730e
AM
20013+ if (!try_aopen) {
20014+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
20015+ if (unlikely(err))
20016+ goto out_free;
20017+ }
027c5e7a
AM
20018+ err = au_d_may_add(dentry);
20019+ if (unlikely(err))
20020+ goto out_unlock;
b912730e
AM
20021+ if (!try_aopen)
20022+ di_write_lock_parent(parent);
c2b27bf2
AM
20023+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
20024+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
20025+ err = PTR_ERR(wh_dentry);
20026+ if (IS_ERR(wh_dentry))
027c5e7a 20027+ goto out_parent;
4a4d8108 20028+
5afbbe0d 20029+ btop = au_dbtop(dentry);
b912730e 20030+ sb = dentry->d_sb;
5afbbe0d
AM
20031+ br = au_sbr(sb, btop);
20032+ a->h_path.dentry = au_h_dptr(dentry, btop);
b912730e 20033+ a->h_path.mnt = au_br_mnt(br);
c2b27bf2 20034+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
20035+ switch (arg->type) {
20036+ case Creat:
acd2b654 20037+ if (!try_aopen || !h_dir->i_op->atomic_open) {
b912730e
AM
20038+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
20039+ arg->u.c.want_excl);
acd2b654
AM
20040+ created = !err;
20041+ if (!err && try_aopen)
20042+ aopen->file->f_mode |= FMODE_CREATED;
20043+ } else {
20044+ aopen->br = br;
20045+ err = vfsub_atomic_open(h_dir, a->h_path.dentry, aopen);
20046+ AuDbg("err %d\n", err);
20047+ AuDbgFile(aopen->file);
20048+ created = err >= 0
20049+ && !!(aopen->file->f_mode & FMODE_CREATED);
20050+ }
4a4d8108
AM
20051+ break;
20052+ case Symlink:
c2b27bf2 20053+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
acd2b654 20054+ created = !err;
4a4d8108
AM
20055+ break;
20056+ case Mknod:
c2b27bf2
AM
20057+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
20058+ arg->u.m.dev);
acd2b654 20059+ created = !err;
4a4d8108
AM
20060+ break;
20061+ default:
20062+ BUG();
20063+ }
acd2b654
AM
20064+ if (unlikely(err < 0))
20065+ goto out_unpin;
20066+
20067+ err = epilog(dir, btop, wh_dentry, dentry);
4a4d8108 20068+ if (!err)
acd2b654 20069+ goto out_unpin; /* success */
4a4d8108
AM
20070+
20071+ /* revert */
acd2b654 20072+ if (created /* && d_is_positive(a->h_path.dentry) */) {
523b37e3
AM
20073+ /* no delegation since it is just created */
20074+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
20075+ /*force*/0);
4a4d8108 20076+ if (rerr) {
523b37e3
AM
20077+ AuIOErr("%pd revert failure(%d, %d)\n",
20078+ dentry, err, rerr);
4a4d8108
AM
20079+ err = -EIO;
20080+ }
c2b27bf2 20081+ au_dtime_revert(&a->dt);
4a4d8108 20082+ }
acd2b654
AM
20083+ if (try_aopen && h_dir->i_op->atomic_open
20084+ && (aopen->file->f_mode & FMODE_OPENED))
20085+ /* aopen->file is still opened */
20086+ au_lcnt_dec(&aopen->br->br_nfiles);
4a4d8108 20087+
acd2b654 20088+out_unpin:
c2b27bf2 20089+ au_unpin(&a->pin);
4a4d8108 20090+ dput(wh_dentry);
027c5e7a 20091+out_parent:
b912730e
AM
20092+ if (!try_aopen)
20093+ di_write_unlock(parent);
027c5e7a 20094+out_unlock:
4a4d8108 20095+ if (unlikely(err)) {
5afbbe0d 20096+ au_update_dbtop(dentry);
4a4d8108
AM
20097+ d_drop(dentry);
20098+ }
b912730e
AM
20099+ if (!try_aopen)
20100+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 20101+out_free:
9f237c51 20102+ au_kfree_rcu(a);
027c5e7a 20103+out:
4a4d8108
AM
20104+ return err;
20105+}
20106+
7eafdf33
AM
20107+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
20108+ dev_t dev)
4a4d8108
AM
20109+{
20110+ struct simple_arg arg = {
20111+ .type = Mknod,
20112+ .u.m = {
20113+ .mode = mode,
20114+ .dev = dev
20115+ }
20116+ };
20117+ return add_simple(dir, dentry, &arg);
20118+}
20119+
20120+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
20121+{
20122+ struct simple_arg arg = {
20123+ .type = Symlink,
20124+ .u.s.symname = symname
20125+ };
20126+ return add_simple(dir, dentry, &arg);
20127+}
20128+
7eafdf33 20129+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 20130+ bool want_excl)
4a4d8108
AM
20131+{
20132+ struct simple_arg arg = {
20133+ .type = Creat,
20134+ .u.c = {
b4510431
AM
20135+ .mode = mode,
20136+ .want_excl = want_excl
4a4d8108
AM
20137+ }
20138+ };
20139+ return add_simple(dir, dentry, &arg);
20140+}
20141+
b912730e
AM
20142+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
20143+ struct vfsub_aopen_args *aopen_args)
20144+{
20145+ struct simple_arg arg = {
20146+ .type = Creat,
20147+ .u.c = {
20148+ .mode = aopen_args->create_mode,
20149+ .want_excl = aopen_args->open_flag & O_EXCL,
20150+ .try_aopen = true,
20151+ .aopen = aopen_args
20152+ }
20153+ };
20154+ return add_simple(dir, dentry, &arg);
20155+}
20156+
38d290e6
JR
20157+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
20158+{
20159+ int err;
20160+ aufs_bindex_t bindex;
20161+ struct super_block *sb;
20162+ struct dentry *parent, *h_parent, *h_dentry;
20163+ struct inode *h_dir, *inode;
20164+ struct vfsmount *h_mnt;
20165+ struct au_wr_dir_args wr_dir_args = {
20166+ .force_btgt = -1,
20167+ .flags = AuWrDir_TMPFILE
20168+ };
20169+
20170+ /* copy-up may happen */
febd17d6 20171+ inode_lock(dir);
38d290e6
JR
20172+
20173+ sb = dir->i_sb;
20174+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
20175+ if (unlikely(err))
20176+ goto out;
20177+
20178+ err = au_di_init(dentry);
20179+ if (unlikely(err))
20180+ goto out_si;
20181+
20182+ err = -EBUSY;
20183+ parent = d_find_any_alias(dir);
20184+ AuDebugOn(!parent);
20185+ di_write_lock_parent(parent);
5527c038 20186+ if (unlikely(d_inode(parent) != dir))
38d290e6
JR
20187+ goto out_parent;
20188+
20189+ err = au_digen_test(parent, au_sigen(sb));
20190+ if (unlikely(err))
20191+ goto out_parent;
20192+
5afbbe0d
AM
20193+ bindex = au_dbtop(parent);
20194+ au_set_dbtop(dentry, bindex);
20195+ au_set_dbbot(dentry, bindex);
38d290e6
JR
20196+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
20197+ bindex = err;
20198+ if (unlikely(err < 0))
20199+ goto out_parent;
20200+
20201+ err = -EOPNOTSUPP;
20202+ h_dir = au_h_iptr(dir, bindex);
20203+ if (unlikely(!h_dir->i_op->tmpfile))
20204+ goto out_parent;
20205+
20206+ h_mnt = au_sbr_mnt(sb, bindex);
20207+ err = vfsub_mnt_want_write(h_mnt);
20208+ if (unlikely(err))
20209+ goto out_parent;
20210+
20211+ h_parent = au_h_dptr(parent, bindex);
521ced18
JR
20212+ h_dentry = vfs_tmpfile(h_parent, mode, /*open_flag*/0);
20213+ if (IS_ERR(h_dentry)) {
20214+ err = PTR_ERR(h_dentry);
38d290e6 20215+ goto out_mnt;
521ced18 20216+ }
38d290e6 20217+
5afbbe0d
AM
20218+ au_set_dbtop(dentry, bindex);
20219+ au_set_dbbot(dentry, bindex);
38d290e6
JR
20220+ au_set_h_dptr(dentry, bindex, dget(h_dentry));
20221+ inode = au_new_inode(dentry, /*must_new*/1);
20222+ if (IS_ERR(inode)) {
20223+ err = PTR_ERR(inode);
20224+ au_set_h_dptr(dentry, bindex, NULL);
5afbbe0d
AM
20225+ au_set_dbtop(dentry, -1);
20226+ au_set_dbbot(dentry, -1);
38d290e6
JR
20227+ } else {
20228+ if (!inode->i_nlink)
20229+ set_nlink(inode, 1);
20230+ d_tmpfile(dentry, inode);
20231+ au_di(dentry)->di_tmpfile = 1;
20232+
20233+ /* update without i_mutex */
5afbbe0d 20234+ if (au_ibtop(dir) == au_dbtop(dentry))
38d290e6
JR
20235+ au_cpup_attr_timesizes(dir);
20236+ }
38d290e6 20237+ dput(h_dentry);
521ced18 20238+
38d290e6
JR
20239+out_mnt:
20240+ vfsub_mnt_drop_write(h_mnt);
20241+out_parent:
20242+ di_write_unlock(parent);
20243+ dput(parent);
20244+ di_write_unlock(dentry);
5afbbe0d 20245+ if (unlikely(err)) {
38d290e6
JR
20246+ au_di_fin(dentry);
20247+ dentry->d_fsdata = NULL;
20248+ }
20249+out_si:
20250+ si_read_unlock(sb);
20251+out:
febd17d6 20252+ inode_unlock(dir);
38d290e6
JR
20253+ return err;
20254+}
20255+
4a4d8108
AM
20256+/* ---------------------------------------------------------------------- */
20257+
20258+struct au_link_args {
20259+ aufs_bindex_t bdst, bsrc;
20260+ struct au_pin pin;
20261+ struct path h_path;
20262+ struct dentry *src_parent, *parent;
20263+};
20264+
20265+static int au_cpup_before_link(struct dentry *src_dentry,
20266+ struct au_link_args *a)
20267+{
20268+ int err;
20269+ struct dentry *h_src_dentry;
c2b27bf2
AM
20270+ struct au_cp_generic cpg = {
20271+ .dentry = src_dentry,
20272+ .bdst = a->bdst,
20273+ .bsrc = a->bsrc,
20274+ .len = -1,
20275+ .pin = &a->pin,
20276+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
20277+ };
4a4d8108
AM
20278+
20279+ di_read_lock_parent(a->src_parent, AuLock_IR);
20280+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
20281+ if (unlikely(err))
20282+ goto out;
20283+
20284+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
20285+ err = au_pin(&a->pin, src_dentry, a->bdst,
20286+ au_opt_udba(src_dentry->d_sb),
20287+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
20288+ if (unlikely(err))
20289+ goto out;
367653fa 20290+
c2b27bf2 20291+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
20292+ au_unpin(&a->pin);
20293+
4f0767ce 20294+out:
4a4d8108
AM
20295+ di_read_unlock(a->src_parent, AuLock_IR);
20296+ return err;
20297+}
20298+
86dc4139
AM
20299+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
20300+ struct au_link_args *a)
4a4d8108
AM
20301+{
20302+ int err;
20303+ unsigned char plink;
5afbbe0d 20304+ aufs_bindex_t bbot;
4a4d8108 20305+ struct dentry *h_src_dentry;
523b37e3 20306+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
20307+ struct super_block *sb;
20308+ struct file *h_file;
20309+
20310+ plink = 0;
20311+ h_inode = NULL;
20312+ sb = src_dentry->d_sb;
5527c038 20313+ inode = d_inode(src_dentry);
5afbbe0d 20314+ if (au_ibtop(inode) <= a->bdst)
4a4d8108
AM
20315+ h_inode = au_h_iptr(inode, a->bdst);
20316+ if (!h_inode || !h_inode->i_nlink) {
20317+ /* copyup src_dentry as the name of dentry. */
5afbbe0d
AM
20318+ bbot = au_dbbot(dentry);
20319+ if (bbot < a->bsrc)
20320+ au_set_dbbot(dentry, a->bsrc);
86dc4139
AM
20321+ au_set_h_dptr(dentry, a->bsrc,
20322+ dget(au_h_dptr(src_dentry, a->bsrc)));
20323+ dget(a->h_path.dentry);
20324+ au_set_h_dptr(dentry, a->bdst, NULL);
c1595e42
JR
20325+ AuDbg("temporary d_inode...\n");
20326+ spin_lock(&dentry->d_lock);
5527c038 20327+ dentry->d_inode = d_inode(src_dentry); /* tmp */
c1595e42 20328+ spin_unlock(&dentry->d_lock);
392086de 20329+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 20330+ if (IS_ERR(h_file))
4a4d8108 20331+ err = PTR_ERR(h_file);
86dc4139 20332+ else {
c2b27bf2
AM
20333+ struct au_cp_generic cpg = {
20334+ .dentry = dentry,
20335+ .bdst = a->bdst,
20336+ .bsrc = -1,
20337+ .len = -1,
20338+ .pin = &a->pin,
20339+ .flags = AuCpup_KEEPLINO
20340+ };
20341+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
20342+ au_h_open_post(dentry, a->bsrc, h_file);
20343+ if (!err) {
20344+ dput(a->h_path.dentry);
20345+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
20346+ } else
20347+ au_set_h_dptr(dentry, a->bdst,
20348+ a->h_path.dentry);
20349+ }
c1595e42 20350+ spin_lock(&dentry->d_lock);
86dc4139 20351+ dentry->d_inode = NULL; /* restore */
c1595e42
JR
20352+ spin_unlock(&dentry->d_lock);
20353+ AuDbg("temporary d_inode...done\n");
86dc4139 20354+ au_set_h_dptr(dentry, a->bsrc, NULL);
5afbbe0d 20355+ au_set_dbbot(dentry, bbot);
4a4d8108
AM
20356+ } else {
20357+ /* the inode of src_dentry already exists on a.bdst branch */
20358+ h_src_dentry = d_find_alias(h_inode);
20359+ if (!h_src_dentry && au_plink_test(inode)) {
20360+ plink = 1;
20361+ h_src_dentry = au_plink_lkup(inode, a->bdst);
20362+ err = PTR_ERR(h_src_dentry);
20363+ if (IS_ERR(h_src_dentry))
20364+ goto out;
20365+
5527c038 20366+ if (unlikely(d_is_negative(h_src_dentry))) {
4a4d8108
AM
20367+ dput(h_src_dentry);
20368+ h_src_dentry = NULL;
20369+ }
20370+
20371+ }
20372+ if (h_src_dentry) {
523b37e3 20373+ delegated = NULL;
4a4d8108 20374+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
20375+ &a->h_path, &delegated);
20376+ if (unlikely(err == -EWOULDBLOCK)) {
20377+ pr_warn("cannot retry for NFSv4 delegation"
20378+ " for an internal link\n");
20379+ iput(delegated);
20380+ }
4a4d8108
AM
20381+ dput(h_src_dentry);
20382+ } else {
20383+ AuIOErr("no dentry found for hi%lu on b%d\n",
20384+ h_inode->i_ino, a->bdst);
20385+ err = -EIO;
20386+ }
20387+ }
20388+
20389+ if (!err && !plink)
20390+ au_plink_append(inode, a->bdst, a->h_path.dentry);
20391+
20392+out:
2cbb1c4b 20393+ AuTraceErr(err);
4a4d8108
AM
20394+ return err;
20395+}
20396+
20397+int aufs_link(struct dentry *src_dentry, struct inode *dir,
20398+ struct dentry *dentry)
20399+{
20400+ int err, rerr;
20401+ struct au_dtime dt;
20402+ struct au_link_args *a;
20403+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 20404+ struct inode *inode, *delegated;
4a4d8108
AM
20405+ struct super_block *sb;
20406+ struct au_wr_dir_args wr_dir_args = {
20407+ /* .force_btgt = -1, */
20408+ .flags = AuWrDir_ADD_ENTRY
20409+ };
20410+
20411+ IMustLock(dir);
5527c038 20412+ inode = d_inode(src_dentry);
4a4d8108
AM
20413+ IMustLock(inode);
20414+
4a4d8108
AM
20415+ err = -ENOMEM;
20416+ a = kzalloc(sizeof(*a), GFP_NOFS);
20417+ if (unlikely(!a))
20418+ goto out;
20419+
20420+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
20421+ err = aufs_read_and_write_lock2(dentry, src_dentry,
20422+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
20423+ if (unlikely(err))
20424+ goto out_kfree;
38d290e6 20425+ err = au_d_linkable(src_dentry);
027c5e7a
AM
20426+ if (unlikely(err))
20427+ goto out_unlock;
20428+ err = au_d_may_add(dentry);
20429+ if (unlikely(err))
20430+ goto out_unlock;
e49829fe 20431+
4a4d8108 20432+ a->src_parent = dget_parent(src_dentry);
5afbbe0d 20433+ wr_dir_args.force_btgt = au_ibtop(inode);
4a4d8108
AM
20434+
20435+ di_write_lock_parent(a->parent);
20436+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
20437+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
20438+ &wr_dir_args);
20439+ err = PTR_ERR(wh_dentry);
20440+ if (IS_ERR(wh_dentry))
027c5e7a 20441+ goto out_parent;
4a4d8108
AM
20442+
20443+ err = 0;
20444+ sb = dentry->d_sb;
5afbbe0d 20445+ a->bdst = au_dbtop(dentry);
4a4d8108
AM
20446+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
20447+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
5afbbe0d 20448+ a->bsrc = au_ibtop(inode);
2cbb1c4b 20449+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
38d290e6
JR
20450+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
20451+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
2cbb1c4b 20452+ if (!h_src_dentry) {
5afbbe0d 20453+ a->bsrc = au_dbtop(src_dentry);
2cbb1c4b
JR
20454+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
20455+ AuDebugOn(!h_src_dentry);
38d290e6
JR
20456+ } else if (IS_ERR(h_src_dentry)) {
20457+ err = PTR_ERR(h_src_dentry);
2cbb1c4b 20458+ goto out_parent;
38d290e6 20459+ }
2cbb1c4b 20460+
f2c43d5f
AM
20461+ /*
20462+ * aufs doesn't touch the credential so
acd2b654 20463+ * security_dentry_create_files_as() is unnecessary.
f2c43d5f 20464+ */
4a4d8108
AM
20465+ if (au_opt_test(au_mntflags(sb), PLINK)) {
20466+ if (a->bdst < a->bsrc
20467+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 20468+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
20469+ else {
20470+ delegated = NULL;
4a4d8108 20471+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
20472+ &a->h_path, &delegated);
20473+ if (unlikely(err == -EWOULDBLOCK)) {
20474+ pr_warn("cannot retry for NFSv4 delegation"
20475+ " for an internal link\n");
20476+ iput(delegated);
20477+ }
20478+ }
2cbb1c4b 20479+ dput(h_src_dentry);
4a4d8108
AM
20480+ } else {
20481+ /*
20482+ * copyup src_dentry to the branch we process,
20483+ * and then link(2) to it.
20484+ */
2cbb1c4b 20485+ dput(h_src_dentry);
4a4d8108
AM
20486+ if (a->bdst < a->bsrc
20487+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
20488+ au_unpin(&a->pin);
20489+ di_write_unlock(a->parent);
20490+ err = au_cpup_before_link(src_dentry, a);
20491+ di_write_lock_parent(a->parent);
20492+ if (!err)
20493+ err = au_pin(&a->pin, dentry, a->bdst,
20494+ au_opt_udba(sb),
20495+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
20496+ if (unlikely(err))
20497+ goto out_wh;
20498+ }
20499+ if (!err) {
20500+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
20501+ err = -ENOENT;
5527c038 20502+ if (h_src_dentry && d_is_positive(h_src_dentry)) {
523b37e3 20503+ delegated = NULL;
4a4d8108
AM
20504+ err = vfsub_link(h_src_dentry,
20505+ au_pinned_h_dir(&a->pin),
523b37e3
AM
20506+ &a->h_path, &delegated);
20507+ if (unlikely(err == -EWOULDBLOCK)) {
20508+ pr_warn("cannot retry"
20509+ " for NFSv4 delegation"
20510+ " for an internal link\n");
20511+ iput(delegated);
20512+ }
20513+ }
4a4d8108
AM
20514+ }
20515+ }
20516+ if (unlikely(err))
20517+ goto out_unpin;
20518+
20519+ if (wh_dentry) {
20520+ a->h_path.dentry = wh_dentry;
20521+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
20522+ dentry);
20523+ if (unlikely(err))
20524+ goto out_revert;
20525+ }
20526+
b912730e 20527+ au_dir_ts(dir, a->bdst);
be118d29 20528+ inode_inc_iversion(dir);
4a4d8108
AM
20529+ inc_nlink(inode);
20530+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
20531+ d_instantiate(dentry, au_igrab(inode));
20532+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
20533+ /* some filesystem calls d_drop() */
20534+ d_drop(dentry);
076b876e
AM
20535+ /* some filesystems consume an inode even hardlink */
20536+ au_fhsm_wrote(sb, a->bdst, /*force*/0);
4a4d8108
AM
20537+ goto out_unpin; /* success */
20538+
4f0767ce 20539+out_revert:
523b37e3
AM
20540+ /* no delegation since it is just created */
20541+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
20542+ /*delegated*/NULL, /*force*/0);
027c5e7a 20543+ if (unlikely(rerr)) {
523b37e3 20544+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
20545+ err = -EIO;
20546+ }
4a4d8108 20547+ au_dtime_revert(&dt);
4f0767ce 20548+out_unpin:
4a4d8108 20549+ au_unpin(&a->pin);
4f0767ce 20550+out_wh:
4a4d8108 20551+ dput(wh_dentry);
027c5e7a
AM
20552+out_parent:
20553+ di_write_unlock(a->parent);
20554+ dput(a->src_parent);
4f0767ce 20555+out_unlock:
4a4d8108 20556+ if (unlikely(err)) {
5afbbe0d 20557+ au_update_dbtop(dentry);
4a4d8108
AM
20558+ d_drop(dentry);
20559+ }
4a4d8108 20560+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 20561+out_kfree:
9f237c51 20562+ au_kfree_rcu(a);
4f0767ce 20563+out:
86dc4139 20564+ AuTraceErr(err);
4a4d8108
AM
20565+ return err;
20566+}
20567+
7eafdf33 20568+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
20569+{
20570+ int err, rerr;
20571+ aufs_bindex_t bindex;
20572+ unsigned char diropq;
20573+ struct path h_path;
20574+ struct dentry *wh_dentry, *parent, *opq_dentry;
febd17d6 20575+ struct inode *h_inode;
4a4d8108
AM
20576+ struct super_block *sb;
20577+ struct {
20578+ struct au_pin pin;
20579+ struct au_dtime dt;
20580+ } *a; /* reduce the stack usage */
20581+ struct au_wr_dir_args wr_dir_args = {
20582+ .force_btgt = -1,
20583+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
20584+ };
20585+
20586+ IMustLock(dir);
20587+
20588+ err = -ENOMEM;
20589+ a = kmalloc(sizeof(*a), GFP_NOFS);
20590+ if (unlikely(!a))
20591+ goto out;
20592+
027c5e7a
AM
20593+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
20594+ if (unlikely(err))
20595+ goto out_free;
20596+ err = au_d_may_add(dentry);
20597+ if (unlikely(err))
20598+ goto out_unlock;
20599+
4a4d8108
AM
20600+ parent = dentry->d_parent; /* dir inode is locked */
20601+ di_write_lock_parent(parent);
20602+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
20603+ &a->pin, &wr_dir_args);
20604+ err = PTR_ERR(wh_dentry);
20605+ if (IS_ERR(wh_dentry))
027c5e7a 20606+ goto out_parent;
4a4d8108
AM
20607+
20608+ sb = dentry->d_sb;
5afbbe0d 20609+ bindex = au_dbtop(dentry);
4a4d8108
AM
20610+ h_path.dentry = au_h_dptr(dentry, bindex);
20611+ h_path.mnt = au_sbr_mnt(sb, bindex);
20612+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
20613+ if (unlikely(err))
027c5e7a 20614+ goto out_unpin;
4a4d8108
AM
20615+
20616+ /* make the dir opaque */
20617+ diropq = 0;
febd17d6 20618+ h_inode = d_inode(h_path.dentry);
4a4d8108
AM
20619+ if (wh_dentry
20620+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
febd17d6 20621+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 20622+ opq_dentry = au_diropq_create(dentry, bindex);
febd17d6 20623+ inode_unlock(h_inode);
4a4d8108
AM
20624+ err = PTR_ERR(opq_dentry);
20625+ if (IS_ERR(opq_dentry))
20626+ goto out_dir;
20627+ dput(opq_dentry);
20628+ diropq = 1;
20629+ }
20630+
20631+ err = epilog(dir, bindex, wh_dentry, dentry);
20632+ if (!err) {
20633+ inc_nlink(dir);
027c5e7a 20634+ goto out_unpin; /* success */
4a4d8108
AM
20635+ }
20636+
20637+ /* revert */
20638+ if (diropq) {
20639+ AuLabel(revert opq);
febd17d6 20640+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 20641+ rerr = au_diropq_remove(dentry, bindex);
febd17d6 20642+ inode_unlock(h_inode);
4a4d8108 20643+ if (rerr) {
523b37e3
AM
20644+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
20645+ dentry, err, rerr);
4a4d8108
AM
20646+ err = -EIO;
20647+ }
20648+ }
20649+
4f0767ce 20650+out_dir:
4a4d8108
AM
20651+ AuLabel(revert dir);
20652+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
20653+ if (rerr) {
523b37e3
AM
20654+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
20655+ dentry, err, rerr);
4a4d8108
AM
20656+ err = -EIO;
20657+ }
4a4d8108 20658+ au_dtime_revert(&a->dt);
027c5e7a 20659+out_unpin:
4a4d8108
AM
20660+ au_unpin(&a->pin);
20661+ dput(wh_dentry);
027c5e7a
AM
20662+out_parent:
20663+ di_write_unlock(parent);
20664+out_unlock:
4a4d8108 20665+ if (unlikely(err)) {
5afbbe0d 20666+ au_update_dbtop(dentry);
4a4d8108
AM
20667+ d_drop(dentry);
20668+ }
4a4d8108 20669+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 20670+out_free:
9f237c51 20671+ au_kfree_rcu(a);
4f0767ce 20672+out:
4a4d8108
AM
20673+ return err;
20674+}
7f207e10
AM
20675diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
20676--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
20677+++ linux/fs/aufs/i_op.c 2019-05-06 09:03:04.816810402 +0200
20678@@ -0,0 +1,1507 @@
cd7a4cd9 20679+// SPDX-License-Identifier: GPL-2.0
4a4d8108 20680+/*
ba1aed25 20681+ * Copyright (C) 2005-2019 Junjiro R. Okajima
4a4d8108
AM
20682+ *
20683+ * This program, aufs is free software; you can redistribute it and/or modify
20684+ * it under the terms of the GNU General Public License as published by
20685+ * the Free Software Foundation; either version 2 of the License, or
20686+ * (at your option) any later version.
20687+ *
20688+ * This program is distributed in the hope that it will be useful,
20689+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20690+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20691+ * GNU General Public License for more details.
20692+ *
20693+ * You should have received a copy of the GNU General Public License
523b37e3 20694+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 20695+ */
1facf9fc 20696+
1308ab2a 20697+/*
4a4d8108 20698+ * inode operations (except add/del/rename)
1308ab2a 20699+ */
4a4d8108
AM
20700+
20701+#include <linux/device_cgroup.h>
20702+#include <linux/fs_stack.h>
eca801bf 20703+#include <linux/iversion.h>
4a4d8108
AM
20704+#include <linux/namei.h>
20705+#include <linux/security.h>
4a4d8108
AM
20706+#include "aufs.h"
20707+
1e00d052 20708+static int h_permission(struct inode *h_inode, int mask,
79b8bda9 20709+ struct path *h_path, int brperm)
1facf9fc 20710+{
1308ab2a 20711+ int err;
4a4d8108 20712+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 20713+
e2f27e51
AM
20714+ err = -EPERM;
20715+ if (write_mask && IS_IMMUTABLE(h_inode))
20716+ goto out;
20717+
4a4d8108 20718+ err = -EACCES;
e2f27e51
AM
20719+ if (((mask & MAY_EXEC)
20720+ && S_ISREG(h_inode->i_mode)
20721+ && (path_noexec(h_path)
cd7a4cd9 20722+ || !(h_inode->i_mode & 0111))))
4a4d8108
AM
20723+ goto out;
20724+
20725+ /*
20726+ * - skip the lower fs test in the case of write to ro branch.
20727+ * - nfs dir permission write check is optimized, but a policy for
20728+ * link/rename requires a real check.
2121bcd9 20729+ * - nfs always sets SB_POSIXACL regardless its mount option 'noacl.'
b912730e 20730+ * in this case, generic_permission() returns -EOPNOTSUPP.
4a4d8108
AM
20731+ */
20732+ if ((write_mask && !au_br_writable(brperm))
20733+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
20734+ && write_mask && !(mask & MAY_READ))
20735+ || !h_inode->i_op->permission) {
20736+ /* AuLabel(generic_permission); */
062440b3 20737+ /* AuDbg("get_acl %ps\n", h_inode->i_op->get_acl); */
1e00d052 20738+ err = generic_permission(h_inode, mask);
b912730e
AM
20739+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode))
20740+ err = h_inode->i_op->permission(h_inode, mask);
20741+ AuTraceErr(err);
1308ab2a 20742+ } else {
4a4d8108 20743+ /* AuLabel(h_inode->permission); */
1e00d052 20744+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
20745+ AuTraceErr(err);
20746+ }
1facf9fc 20747+
4a4d8108
AM
20748+ if (!err)
20749+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 20750+ if (!err)
4a4d8108 20751+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
20752+
20753+#if 0
20754+ if (!err) {
20755+ /* todo: do we need to call ima_path_check()? */
20756+ struct path h_path = {
20757+ .dentry =
20758+ .mnt = h_mnt
20759+ };
20760+ err = ima_path_check(&h_path,
20761+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
20762+ IMA_COUNT_LEAVE);
1308ab2a 20763+ }
4a4d8108 20764+#endif
dece6358 20765+
4f0767ce 20766+out:
1308ab2a 20767+ return err;
20768+}
dece6358 20769+
1e00d052 20770+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 20771+{
20772+ int err;
5afbbe0d 20773+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
20774+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
20775+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
20776+ struct inode *h_inode;
20777+ struct super_block *sb;
20778+ struct au_branch *br;
1facf9fc 20779+
027c5e7a 20780+ /* todo: support rcu-walk? */
1e00d052 20781+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
20782+ return -ECHILD;
20783+
4a4d8108
AM
20784+ sb = inode->i_sb;
20785+ si_read_lock(sb, AuLock_FLUSH);
20786+ ii_read_lock_child(inode);
027c5e7a
AM
20787+#if 0
20788+ err = au_iigen_test(inode, au_sigen(sb));
20789+ if (unlikely(err))
20790+ goto out;
20791+#endif
dece6358 20792+
076b876e
AM
20793+ if (!isdir
20794+ || write_mask
20795+ || au_opt_test(au_mntflags(sb), DIRPERM1)) {
4a4d8108 20796+ err = au_busy_or_stale();
5afbbe0d 20797+ h_inode = au_h_iptr(inode, au_ibtop(inode));
4a4d8108
AM
20798+ if (unlikely(!h_inode
20799+ || (h_inode->i_mode & S_IFMT)
20800+ != (inode->i_mode & S_IFMT)))
20801+ goto out;
1facf9fc 20802+
4a4d8108 20803+ err = 0;
5afbbe0d 20804+ bindex = au_ibtop(inode);
4a4d8108 20805+ br = au_sbr(sb, bindex);
79b8bda9 20806+ err = h_permission(h_inode, mask, &br->br_path, br->br_perm);
4a4d8108
AM
20807+ if (write_mask
20808+ && !err
20809+ && !special_file(h_inode->i_mode)) {
20810+ /* test whether the upper writable branch exists */
20811+ err = -EROFS;
20812+ for (; bindex >= 0; bindex--)
20813+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
20814+ err = 0;
20815+ break;
20816+ }
20817+ }
20818+ goto out;
20819+ }
dece6358 20820+
4a4d8108 20821+ /* non-write to dir */
1308ab2a 20822+ err = 0;
5afbbe0d
AM
20823+ bbot = au_ibbot(inode);
20824+ for (bindex = au_ibtop(inode); !err && bindex <= bbot; bindex++) {
4a4d8108
AM
20825+ h_inode = au_h_iptr(inode, bindex);
20826+ if (h_inode) {
20827+ err = au_busy_or_stale();
20828+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
20829+ break;
20830+
20831+ br = au_sbr(sb, bindex);
79b8bda9 20832+ err = h_permission(h_inode, mask, &br->br_path,
4a4d8108
AM
20833+ br->br_perm);
20834+ }
20835+ }
1308ab2a 20836+
4f0767ce 20837+out:
4a4d8108
AM
20838+ ii_read_unlock(inode);
20839+ si_read_unlock(sb);
1308ab2a 20840+ return err;
20841+}
20842+
4a4d8108 20843+/* ---------------------------------------------------------------------- */
1facf9fc 20844+
4a4d8108 20845+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 20846+ unsigned int flags)
4a4d8108
AM
20847+{
20848+ struct dentry *ret, *parent;
b752ccd1 20849+ struct inode *inode;
4a4d8108 20850+ struct super_block *sb;
1716fcea 20851+ int err, npositive;
dece6358 20852+
4a4d8108 20853+ IMustLock(dir);
1308ab2a 20854+
537831f9
AM
20855+ /* todo: support rcu-walk? */
20856+ ret = ERR_PTR(-ECHILD);
20857+ if (flags & LOOKUP_RCU)
20858+ goto out;
20859+
20860+ ret = ERR_PTR(-ENAMETOOLONG);
20861+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
20862+ goto out;
20863+
4a4d8108 20864+ sb = dir->i_sb;
7f207e10
AM
20865+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
20866+ ret = ERR_PTR(err);
20867+ if (unlikely(err))
20868+ goto out;
20869+
4a4d8108
AM
20870+ err = au_di_init(dentry);
20871+ ret = ERR_PTR(err);
20872+ if (unlikely(err))
7f207e10 20873+ goto out_si;
1308ab2a 20874+
9dbd164d 20875+ inode = NULL;
027c5e7a 20876+ npositive = 0; /* suppress a warning */
4a4d8108
AM
20877+ parent = dentry->d_parent; /* dir inode is locked */
20878+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
20879+ err = au_alive_dir(parent);
20880+ if (!err)
20881+ err = au_digen_test(parent, au_sigen(sb));
20882+ if (!err) {
5afbbe0d
AM
20883+ /* regardless LOOKUP_CREATE, always ALLOW_NEG */
20884+ npositive = au_lkup_dentry(dentry, au_dbtop(parent),
20885+ AuLkup_ALLOW_NEG);
027c5e7a
AM
20886+ err = npositive;
20887+ }
4a4d8108 20888+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
20889+ ret = ERR_PTR(err);
20890+ if (unlikely(err < 0))
20891+ goto out_unlock;
1308ab2a 20892+
4a4d8108 20893+ if (npositive) {
b752ccd1 20894+ inode = au_new_inode(dentry, /*must_new*/0);
c1595e42
JR
20895+ if (IS_ERR(inode)) {
20896+ ret = (void *)inode;
20897+ inode = NULL;
20898+ goto out_unlock;
20899+ }
9dbd164d 20900+ }
4a4d8108 20901+
c1595e42
JR
20902+ if (inode)
20903+ atomic_inc(&inode->i_count);
4a4d8108 20904+ ret = d_splice_alias(inode, dentry);
537831f9
AM
20905+#if 0
20906+ if (unlikely(d_need_lookup(dentry))) {
20907+ spin_lock(&dentry->d_lock);
20908+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
20909+ spin_unlock(&dentry->d_lock);
20910+ } else
20911+#endif
c1595e42 20912+ if (inode) {
2000de60 20913+ if (!IS_ERR(ret)) {
c1595e42 20914+ iput(inode);
2000de60
JR
20915+ if (ret && ret != dentry)
20916+ ii_write_unlock(inode);
20917+ } else {
c1595e42
JR
20918+ ii_write_unlock(inode);
20919+ iput(inode);
20920+ inode = NULL;
20921+ }
7f207e10 20922+ }
1facf9fc 20923+
4f0767ce 20924+out_unlock:
4a4d8108 20925+ di_write_unlock(dentry);
7f207e10 20926+out_si:
4a4d8108 20927+ si_read_unlock(sb);
7f207e10 20928+out:
4a4d8108
AM
20929+ return ret;
20930+}
1facf9fc 20931+
4a4d8108 20932+/* ---------------------------------------------------------------------- */
1facf9fc 20933+
acd2b654
AM
20934+/*
20935+ * very dirty and complicated aufs ->atomic_open().
20936+ * aufs_atomic_open()
20937+ * + au_aopen_or_create()
20938+ * + add_simple()
20939+ * + vfsub_atomic_open()
20940+ * + branch fs ->atomic_open()
20941+ * may call the actual 'open' for h_file
20942+ * + inc br_nfiles only if opened
20943+ * + au_aopen_no_open() or au_aopen_do_open()
20944+ *
20945+ * au_aopen_do_open()
20946+ * + finish_open()
20947+ * + au_do_aopen()
20948+ * + au_do_open() the body of all 'open'
20949+ * + au_do_open_nondir()
20950+ * set the passed h_file
20951+ *
20952+ * au_aopen_no_open()
20953+ * + finish_no_open()
20954+ */
20955+
b912730e 20956+struct aopen_node {
8b6a4947 20957+ struct hlist_bl_node hblist;
b912730e
AM
20958+ struct file *file, *h_file;
20959+};
20960+
20961+static int au_do_aopen(struct inode *inode, struct file *file)
20962+{
8b6a4947
AM
20963+ struct hlist_bl_head *aopen;
20964+ struct hlist_bl_node *pos;
b912730e
AM
20965+ struct aopen_node *node;
20966+ struct au_do_open_args args = {
8b6a4947
AM
20967+ .aopen = 1,
20968+ .open = au_do_open_nondir
b912730e
AM
20969+ };
20970+
20971+ aopen = &au_sbi(inode->i_sb)->si_aopen;
8b6a4947
AM
20972+ hlist_bl_lock(aopen);
20973+ hlist_bl_for_each_entry(node, pos, aopen, hblist)
b912730e
AM
20974+ if (node->file == file) {
20975+ args.h_file = node->h_file;
20976+ break;
20977+ }
8b6a4947 20978+ hlist_bl_unlock(aopen);
b912730e
AM
20979+ /* AuDebugOn(!args.h_file); */
20980+
20981+ return au_do_open(file, &args);
20982+}
20983+
acd2b654
AM
20984+static int au_aopen_do_open(struct file *file, struct dentry *dentry,
20985+ struct aopen_node *aopen_node)
20986+{
20987+ int err;
20988+ struct hlist_bl_head *aopen;
20989+
20990+ AuLabel(here);
20991+ aopen = &au_sbi(dentry->d_sb)->si_aopen;
20992+ au_hbl_add(&aopen_node->hblist, aopen);
20993+ err = finish_open(file, dentry, au_do_aopen);
20994+ au_hbl_del(&aopen_node->hblist, aopen);
20995+ /* AuDbgFile(file); */
20996+ AuDbg("%pd%s%s\n", dentry,
20997+ (file->f_mode & FMODE_CREATED) ? " created" : "",
20998+ (file->f_mode & FMODE_OPENED) ? " opened" : "");
20999+
21000+ AuTraceErr(err);
21001+ return err;
21002+}
21003+
21004+static int au_aopen_no_open(struct file *file, struct dentry *dentry)
21005+{
21006+ int err;
21007+
21008+ AuLabel(here);
21009+ dget(dentry);
21010+ err = finish_no_open(file, dentry);
21011+
21012+ AuTraceErr(err);
21013+ return err;
21014+}
21015+
b912730e
AM
21016+static int aufs_atomic_open(struct inode *dir, struct dentry *dentry,
21017+ struct file *file, unsigned int open_flag,
acd2b654 21018+ umode_t create_mode)
b912730e 21019+{
acd2b654 21020+ int err, did_open;
5afbbe0d 21021+ unsigned int lkup_flags;
acd2b654
AM
21022+ aufs_bindex_t bindex;
21023+ struct super_block *sb;
f0c0a007 21024+ struct dentry *parent, *d;
b912730e
AM
21025+ struct vfsub_aopen_args args = {
21026+ .open_flag = open_flag,
acd2b654 21027+ .create_mode = create_mode
b912730e
AM
21028+ };
21029+ struct aopen_node aopen_node = {
21030+ .file = file
21031+ };
21032+
21033+ IMustLock(dir);
5afbbe0d 21034+ AuDbg("open_flag 0%o\n", open_flag);
b912730e
AM
21035+ AuDbgDentry(dentry);
21036+
21037+ err = 0;
21038+ if (!au_di(dentry)) {
5afbbe0d
AM
21039+ lkup_flags = LOOKUP_OPEN;
21040+ if (open_flag & O_CREAT)
21041+ lkup_flags |= LOOKUP_CREATE;
21042+ d = aufs_lookup(dir, dentry, lkup_flags);
b912730e
AM
21043+ if (IS_ERR(d)) {
21044+ err = PTR_ERR(d);
5afbbe0d 21045+ AuTraceErr(err);
b912730e
AM
21046+ goto out;
21047+ } else if (d) {
21048+ /*
21049+ * obsoleted dentry found.
21050+ * another error will be returned later.
21051+ */
21052+ d_drop(d);
b912730e 21053+ AuDbgDentry(d);
5afbbe0d 21054+ dput(d);
b912730e
AM
21055+ }
21056+ AuDbgDentry(dentry);
21057+ }
21058+
21059+ if (d_is_positive(dentry)
21060+ || d_unhashed(dentry)
21061+ || d_unlinked(dentry)
acd2b654
AM
21062+ || !(open_flag & O_CREAT)) {
21063+ err = au_aopen_no_open(file, dentry);
21064+ goto out; /* success */
21065+ }
b912730e
AM
21066+
21067+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
21068+ if (unlikely(err))
21069+ goto out;
21070+
acd2b654 21071+ sb = dentry->d_sb;
b912730e
AM
21072+ parent = dentry->d_parent; /* dir is locked */
21073+ di_write_lock_parent(parent);
5afbbe0d 21074+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG);
acd2b654
AM
21075+ if (unlikely(err < 0))
21076+ goto out_parent;
b912730e
AM
21077+
21078+ AuDbgDentry(dentry);
acd2b654
AM
21079+ if (d_is_positive(dentry)) {
21080+ err = au_aopen_no_open(file, dentry);
21081+ goto out_parent; /* success */
21082+ }
b912730e 21083+
acd2b654 21084+ args.file = alloc_empty_file(file->f_flags, current_cred());
b912730e
AM
21085+ err = PTR_ERR(args.file);
21086+ if (IS_ERR(args.file))
acd2b654 21087+ goto out_parent;
b912730e 21088+
acd2b654 21089+ bindex = au_dbtop(dentry);
b912730e
AM
21090+ err = au_aopen_or_create(dir, dentry, &args);
21091+ AuTraceErr(err);
21092+ AuDbgFile(args.file);
acd2b654
AM
21093+ file->f_mode = args.file->f_mode & ~FMODE_OPENED;
21094+ did_open = !!(args.file->f_mode & FMODE_OPENED);
21095+ if (!did_open) {
21096+ fput(args.file);
21097+ args.file = NULL;
b912730e 21098+ }
8b6a4947
AM
21099+ di_write_unlock(parent);
21100+ di_write_unlock(dentry);
acd2b654
AM
21101+ if (unlikely(err < 0)) {
21102+ if (args.file)
21103+ fput(args.file);
21104+ goto out_sb;
b912730e 21105+ }
b912730e 21106+
acd2b654
AM
21107+ if (!did_open)
21108+ err = au_aopen_no_open(file, dentry);
8b6a4947 21109+ else {
acd2b654
AM
21110+ aopen_node.h_file = args.file;
21111+ err = au_aopen_do_open(file, dentry, &aopen_node);
8b6a4947 21112+ }
acd2b654
AM
21113+ if (unlikely(err < 0)) {
21114+ if (args.file)
21115+ fput(args.file);
21116+ if (did_open)
21117+ au_lcnt_dec(&args.br->br_nfiles);
b912730e 21118+ }
acd2b654
AM
21119+ goto out_sb; /* success */
21120+
21121+out_parent:
21122+ di_write_unlock(parent);
21123+ di_write_unlock(dentry);
21124+out_sb:
21125+ si_read_unlock(sb);
b912730e 21126+out:
b912730e 21127+ AuTraceErr(err);
acd2b654 21128+ AuDbgFile(file);
b912730e
AM
21129+ return err;
21130+}
21131+
21132+
21133+/* ---------------------------------------------------------------------- */
21134+
4a4d8108
AM
21135+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
21136+ const unsigned char add_entry, aufs_bindex_t bcpup,
5afbbe0d 21137+ aufs_bindex_t btop)
4a4d8108
AM
21138+{
21139+ int err;
21140+ struct dentry *h_parent;
21141+ struct inode *h_dir;
1facf9fc 21142+
027c5e7a 21143+ if (add_entry)
5527c038 21144+ IMustLock(d_inode(parent));
027c5e7a 21145+ else
4a4d8108
AM
21146+ di_write_lock_parent(parent);
21147+
21148+ err = 0;
21149+ if (!au_h_dptr(parent, bcpup)) {
5afbbe0d 21150+ if (btop > bcpup)
c2b27bf2 21151+ err = au_cpup_dirs(dentry, bcpup);
5afbbe0d 21152+ else if (btop < bcpup)
4a4d8108
AM
21153+ err = au_cpdown_dirs(dentry, bcpup);
21154+ else
c2b27bf2 21155+ BUG();
4a4d8108 21156+ }
38d290e6 21157+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
4a4d8108 21158+ h_parent = au_h_dptr(parent, bcpup);
5527c038 21159+ h_dir = d_inode(h_parent);
be118d29 21160+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
7e9cd9fe 21161+ err = au_lkup_neg(dentry, bcpup, /*wh*/0);
4a4d8108 21162+ /* todo: no unlock here */
3c1bdaff 21163+ inode_unlock_shared(h_dir);
027c5e7a
AM
21164+
21165+ AuDbg("bcpup %d\n", bcpup);
21166+ if (!err) {
5527c038 21167+ if (d_really_is_negative(dentry))
5afbbe0d 21168+ au_set_h_dptr(dentry, btop, NULL);
4a4d8108
AM
21169+ au_update_dbrange(dentry, /*do_put_zero*/0);
21170+ }
1308ab2a 21171+ }
1facf9fc 21172+
4a4d8108
AM
21173+ if (!add_entry)
21174+ di_write_unlock(parent);
21175+ if (!err)
21176+ err = bcpup; /* success */
1308ab2a 21177+
027c5e7a 21178+ AuTraceErr(err);
4a4d8108
AM
21179+ return err;
21180+}
1facf9fc 21181+
4a4d8108
AM
21182+/*
21183+ * decide the branch and the parent dir where we will create a new entry.
21184+ * returns new bindex or an error.
21185+ * copyup the parent dir if needed.
21186+ */
21187+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
21188+ struct au_wr_dir_args *args)
21189+{
21190+ int err;
392086de 21191+ unsigned int flags;
5afbbe0d 21192+ aufs_bindex_t bcpup, btop, src_btop;
86dc4139
AM
21193+ const unsigned char add_entry
21194+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
38d290e6 21195+ | au_ftest_wrdir(args->flags, TMPFILE);
4a4d8108
AM
21196+ struct super_block *sb;
21197+ struct dentry *parent;
21198+ struct au_sbinfo *sbinfo;
1facf9fc 21199+
4a4d8108
AM
21200+ sb = dentry->d_sb;
21201+ sbinfo = au_sbi(sb);
21202+ parent = dget_parent(dentry);
5afbbe0d
AM
21203+ btop = au_dbtop(dentry);
21204+ bcpup = btop;
4a4d8108
AM
21205+ if (args->force_btgt < 0) {
21206+ if (src_dentry) {
5afbbe0d
AM
21207+ src_btop = au_dbtop(src_dentry);
21208+ if (src_btop < btop)
21209+ bcpup = src_btop;
4a4d8108 21210+ } else if (add_entry) {
392086de
AM
21211+ flags = 0;
21212+ if (au_ftest_wrdir(args->flags, ISDIR))
21213+ au_fset_wbr(flags, DIR);
21214+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
21215+ bcpup = err;
21216+ }
1facf9fc 21217+
5527c038 21218+ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) {
4a4d8108
AM
21219+ if (add_entry)
21220+ err = AuWbrCopyup(sbinfo, dentry);
21221+ else {
21222+ if (!IS_ROOT(dentry)) {
21223+ di_read_lock_parent(parent, !AuLock_IR);
21224+ err = AuWbrCopyup(sbinfo, dentry);
21225+ di_read_unlock(parent, !AuLock_IR);
21226+ } else
21227+ err = AuWbrCopyup(sbinfo, dentry);
21228+ }
21229+ bcpup = err;
21230+ if (unlikely(err < 0))
21231+ goto out;
21232+ }
21233+ } else {
21234+ bcpup = args->force_btgt;
5527c038 21235+ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry)));
1308ab2a 21236+ }
027c5e7a 21237+
5afbbe0d 21238+ AuDbg("btop %d, bcpup %d\n", btop, bcpup);
4a4d8108 21239+ err = bcpup;
5afbbe0d 21240+ if (bcpup == btop)
4a4d8108 21241+ goto out; /* success */
4a4d8108
AM
21242+
21243+ /* copyup the new parent into the branch we process */
5afbbe0d 21244+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, btop);
027c5e7a 21245+ if (err >= 0) {
5527c038 21246+ if (d_really_is_negative(dentry)) {
5afbbe0d
AM
21247+ au_set_h_dptr(dentry, btop, NULL);
21248+ au_set_dbtop(dentry, bcpup);
21249+ au_set_dbbot(dentry, bcpup);
027c5e7a 21250+ }
38d290e6
JR
21251+ AuDebugOn(add_entry
21252+ && !au_ftest_wrdir(args->flags, TMPFILE)
21253+ && !au_h_dptr(dentry, bcpup));
027c5e7a 21254+ }
86dc4139
AM
21255+
21256+out:
21257+ dput(parent);
21258+ return err;
21259+}
21260+
21261+/* ---------------------------------------------------------------------- */
21262+
21263+void au_pin_hdir_unlock(struct au_pin *p)
21264+{
21265+ if (p->hdir)
5afbbe0d 21266+ au_hn_inode_unlock(p->hdir);
86dc4139
AM
21267+}
21268+
c1595e42 21269+int au_pin_hdir_lock(struct au_pin *p)
86dc4139
AM
21270+{
21271+ int err;
21272+
21273+ err = 0;
21274+ if (!p->hdir)
21275+ goto out;
21276+
21277+ /* even if an error happens later, keep this lock */
5afbbe0d 21278+ au_hn_inode_lock_nested(p->hdir, p->lsc_hi);
86dc4139
AM
21279+
21280+ err = -EBUSY;
5527c038 21281+ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent)))
86dc4139
AM
21282+ goto out;
21283+
21284+ err = 0;
21285+ if (p->h_dentry)
21286+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
21287+ p->h_parent, p->br);
21288+
21289+out:
21290+ return err;
21291+}
21292+
21293+int au_pin_hdir_relock(struct au_pin *p)
21294+{
21295+ int err, i;
21296+ struct inode *h_i;
21297+ struct dentry *h_d[] = {
21298+ p->h_dentry,
21299+ p->h_parent
21300+ };
21301+
21302+ err = au_pin_hdir_lock(p);
21303+ if (unlikely(err))
21304+ goto out;
21305+
21306+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
21307+ if (!h_d[i])
21308+ continue;
5527c038
JR
21309+ if (d_is_positive(h_d[i])) {
21310+ h_i = d_inode(h_d[i]);
86dc4139 21311+ err = !h_i->i_nlink;
5527c038 21312+ }
86dc4139
AM
21313+ }
21314+
21315+out:
21316+ return err;
21317+}
21318+
5afbbe0d 21319+static void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
86dc4139 21320+{
5afbbe0d
AM
21321+#if !defined(CONFIG_RWSEM_GENERIC_SPINLOCK) && defined(CONFIG_RWSEM_SPIN_ON_OWNER)
21322+ p->hdir->hi_inode->i_rwsem.owner = task;
86dc4139
AM
21323+#endif
21324+}
21325+
21326+void au_pin_hdir_acquire_nest(struct au_pin *p)
21327+{
21328+ if (p->hdir) {
5afbbe0d 21329+ rwsem_acquire_nest(&p->hdir->hi_inode->i_rwsem.dep_map,
86dc4139
AM
21330+ p->lsc_hi, 0, NULL, _RET_IP_);
21331+ au_pin_hdir_set_owner(p, current);
21332+ }
dece6358 21333+}
1facf9fc 21334+
86dc4139
AM
21335+void au_pin_hdir_release(struct au_pin *p)
21336+{
21337+ if (p->hdir) {
21338+ au_pin_hdir_set_owner(p, p->task);
5afbbe0d 21339+ rwsem_release(&p->hdir->hi_inode->i_rwsem.dep_map, 1, _RET_IP_);
86dc4139
AM
21340+ }
21341+}
1308ab2a 21342+
4a4d8108 21343+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 21344+{
4a4d8108
AM
21345+ if (pin && pin->parent)
21346+ return au_h_dptr(pin->parent, pin->bindex);
21347+ return NULL;
dece6358 21348+}
1facf9fc 21349+
4a4d8108 21350+void au_unpin(struct au_pin *p)
dece6358 21351+{
86dc4139
AM
21352+ if (p->hdir)
21353+ au_pin_hdir_unlock(p);
e49829fe 21354+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 21355+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
21356+ if (!p->hdir)
21357+ return;
1facf9fc 21358+
4a4d8108
AM
21359+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21360+ di_read_unlock(p->parent, AuLock_IR);
21361+ iput(p->hdir->hi_inode);
21362+ dput(p->parent);
21363+ p->parent = NULL;
21364+ p->hdir = NULL;
21365+ p->h_mnt = NULL;
86dc4139 21366+ /* do not clear p->task */
4a4d8108 21367+}
1308ab2a 21368+
4a4d8108
AM
21369+int au_do_pin(struct au_pin *p)
21370+{
21371+ int err;
21372+ struct super_block *sb;
4a4d8108
AM
21373+ struct inode *h_dir;
21374+
21375+ err = 0;
21376+ sb = p->dentry->d_sb;
86dc4139 21377+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
21378+ if (IS_ROOT(p->dentry)) {
21379+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 21380+ p->h_mnt = au_br_mnt(p->br);
b4510431 21381+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
21382+ if (unlikely(err)) {
21383+ au_fclr_pin(p->flags, MNT_WRITE);
21384+ goto out_err;
21385+ }
21386+ }
dece6358 21387+ goto out;
1facf9fc 21388+ }
21389+
86dc4139 21390+ p->h_dentry = NULL;
5afbbe0d 21391+ if (p->bindex <= au_dbbot(p->dentry))
86dc4139 21392+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 21393+
4a4d8108
AM
21394+ p->parent = dget_parent(p->dentry);
21395+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21396+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 21397+
4a4d8108 21398+ h_dir = NULL;
86dc4139 21399+ p->h_parent = au_h_dptr(p->parent, p->bindex);
5527c038 21400+ p->hdir = au_hi(d_inode(p->parent), p->bindex);
4a4d8108
AM
21401+ if (p->hdir)
21402+ h_dir = p->hdir->hi_inode;
dece6358 21403+
b752ccd1
AM
21404+ /*
21405+ * udba case, or
21406+ * if DI_LOCKED is not set, then p->parent may be different
21407+ * and h_parent can be NULL.
21408+ */
86dc4139 21409+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 21410+ err = -EBUSY;
4a4d8108
AM
21411+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21412+ di_read_unlock(p->parent, AuLock_IR);
21413+ dput(p->parent);
21414+ p->parent = NULL;
21415+ goto out_err;
21416+ }
1308ab2a 21417+
4a4d8108 21418+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 21419+ p->h_mnt = au_br_mnt(p->br);
b4510431 21420+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 21421+ if (unlikely(err)) {
4a4d8108 21422+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
21423+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21424+ di_read_unlock(p->parent, AuLock_IR);
21425+ dput(p->parent);
21426+ p->parent = NULL;
21427+ goto out_err;
dece6358
AM
21428+ }
21429+ }
4a4d8108 21430+
86dc4139
AM
21431+ au_igrab(h_dir);
21432+ err = au_pin_hdir_lock(p);
21433+ if (!err)
21434+ goto out; /* success */
21435+
076b876e
AM
21436+ au_unpin(p);
21437+
4f0767ce 21438+out_err:
4a4d8108
AM
21439+ pr_err("err %d\n", err);
21440+ err = au_busy_or_stale();
4f0767ce 21441+out:
1facf9fc 21442+ return err;
21443+}
21444+
4a4d8108
AM
21445+void au_pin_init(struct au_pin *p, struct dentry *dentry,
21446+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
21447+ unsigned int udba, unsigned char flags)
21448+{
21449+ p->dentry = dentry;
21450+ p->udba = udba;
21451+ p->lsc_di = lsc_di;
21452+ p->lsc_hi = lsc_hi;
21453+ p->flags = flags;
21454+ p->bindex = bindex;
21455+
21456+ p->parent = NULL;
21457+ p->hdir = NULL;
21458+ p->h_mnt = NULL;
86dc4139
AM
21459+
21460+ p->h_dentry = NULL;
21461+ p->h_parent = NULL;
21462+ p->br = NULL;
21463+ p->task = current;
4a4d8108
AM
21464+}
21465+
21466+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
21467+ unsigned int udba, unsigned char flags)
21468+{
21469+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
21470+ udba, flags);
21471+ return au_do_pin(pin);
21472+}
21473+
dece6358
AM
21474+/* ---------------------------------------------------------------------- */
21475+
1308ab2a 21476+/*
4a4d8108
AM
21477+ * ->setattr() and ->getattr() are called in various cases.
21478+ * chmod, stat: dentry is revalidated.
21479+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
21480+ * unhashed.
21481+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 21482+ */
027c5e7a 21483+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
c1595e42 21484+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 21485+{
4a4d8108 21486+ int err;
4a4d8108 21487+ struct dentry *parent;
1facf9fc 21488+
1308ab2a 21489+ err = 0;
027c5e7a 21490+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
21491+ parent = dget_parent(dentry);
21492+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 21493+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
21494+ di_read_unlock(parent, AuLock_IR);
21495+ dput(parent);
dece6358 21496+ }
1facf9fc 21497+
4a4d8108 21498+ AuTraceErr(err);
1308ab2a 21499+ return err;
21500+}
dece6358 21501+
c1595e42
JR
21502+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
21503+ struct au_icpup_args *a)
1308ab2a 21504+{
21505+ int err;
4a4d8108 21506+ loff_t sz;
5afbbe0d 21507+ aufs_bindex_t btop, ibtop;
4a4d8108
AM
21508+ struct dentry *hi_wh, *parent;
21509+ struct inode *inode;
4a4d8108
AM
21510+ struct au_wr_dir_args wr_dir_args = {
21511+ .force_btgt = -1,
21512+ .flags = 0
21513+ };
21514+
2000de60 21515+ if (d_is_dir(dentry))
4a4d8108
AM
21516+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
21517+ /* plink or hi_wh() case */
5afbbe0d 21518+ btop = au_dbtop(dentry);
5527c038 21519+ inode = d_inode(dentry);
5afbbe0d
AM
21520+ ibtop = au_ibtop(inode);
21521+ if (btop != ibtop && !au_test_ro(inode->i_sb, ibtop, inode))
21522+ wr_dir_args.force_btgt = ibtop;
4a4d8108
AM
21523+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
21524+ if (unlikely(err < 0))
21525+ goto out;
21526+ a->btgt = err;
5afbbe0d 21527+ if (err != btop)
4a4d8108
AM
21528+ au_fset_icpup(a->flags, DID_CPUP);
21529+
21530+ err = 0;
21531+ a->pin_flags = AuPin_MNT_WRITE;
21532+ parent = NULL;
21533+ if (!IS_ROOT(dentry)) {
21534+ au_fset_pin(a->pin_flags, DI_LOCKED);
21535+ parent = dget_parent(dentry);
21536+ di_write_lock_parent(parent);
21537+ }
21538+
21539+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
21540+ if (unlikely(err))
21541+ goto out_parent;
21542+
4a4d8108 21543+ sz = -1;
5afbbe0d 21544+ a->h_path.dentry = au_h_dptr(dentry, btop);
5527c038 21545+ a->h_inode = d_inode(a->h_path.dentry);
c1595e42 21546+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
be118d29 21547+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
c1595e42
JR
21548+ if (ia->ia_size < i_size_read(a->h_inode))
21549+ sz = ia->ia_size;
3c1bdaff 21550+ inode_unlock_shared(a->h_inode);
c1595e42 21551+ }
4a4d8108 21552+
4a4d8108 21553+ hi_wh = NULL;
027c5e7a 21554+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
21555+ hi_wh = au_hi_wh(inode, a->btgt);
21556+ if (!hi_wh) {
c2b27bf2
AM
21557+ struct au_cp_generic cpg = {
21558+ .dentry = dentry,
21559+ .bdst = a->btgt,
21560+ .bsrc = -1,
21561+ .len = sz,
21562+ .pin = &a->pin
21563+ };
21564+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
21565+ if (unlikely(err))
21566+ goto out_unlock;
21567+ hi_wh = au_hi_wh(inode, a->btgt);
21568+ /* todo: revalidate hi_wh? */
21569+ }
21570+ }
21571+
21572+ if (parent) {
21573+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
21574+ di_downgrade_lock(parent, AuLock_IR);
21575+ dput(parent);
21576+ parent = NULL;
21577+ }
21578+ if (!au_ftest_icpup(a->flags, DID_CPUP))
21579+ goto out; /* success */
21580+
21581+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
21582+ struct au_cp_generic cpg = {
21583+ .dentry = dentry,
21584+ .bdst = a->btgt,
5afbbe0d 21585+ .bsrc = btop,
c2b27bf2
AM
21586+ .len = sz,
21587+ .pin = &a->pin,
21588+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21589+ };
21590+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
21591+ if (!err)
21592+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
21593+ } else if (!hi_wh)
21594+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
21595+ else
21596+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 21597+
4f0767ce 21598+out_unlock:
5527c038 21599+ a->h_inode = d_inode(a->h_path.dentry);
86dc4139 21600+ if (!err)
dece6358 21601+ goto out; /* success */
4a4d8108 21602+ au_unpin(&a->pin);
4f0767ce 21603+out_parent:
4a4d8108
AM
21604+ if (parent) {
21605+ di_write_unlock(parent);
21606+ dput(parent);
21607+ }
4f0767ce 21608+out:
86dc4139 21609+ if (!err)
febd17d6 21610+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
1facf9fc 21611+ return err;
21612+}
21613+
4a4d8108 21614+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 21615+{
4a4d8108 21616+ int err;
523b37e3 21617+ struct inode *inode, *delegated;
4a4d8108
AM
21618+ struct super_block *sb;
21619+ struct file *file;
21620+ struct au_icpup_args *a;
1facf9fc 21621+
5527c038 21622+ inode = d_inode(dentry);
4a4d8108 21623+ IMustLock(inode);
dece6358 21624+
f2c43d5f
AM
21625+ err = setattr_prepare(dentry, ia);
21626+ if (unlikely(err))
21627+ goto out;
21628+
4a4d8108
AM
21629+ err = -ENOMEM;
21630+ a = kzalloc(sizeof(*a), GFP_NOFS);
21631+ if (unlikely(!a))
21632+ goto out;
1facf9fc 21633+
4a4d8108
AM
21634+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
21635+ ia->ia_valid &= ~ATTR_MODE;
dece6358 21636+
4a4d8108
AM
21637+ file = NULL;
21638+ sb = dentry->d_sb;
e49829fe
JR
21639+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21640+ if (unlikely(err))
21641+ goto out_kfree;
21642+
4a4d8108
AM
21643+ if (ia->ia_valid & ATTR_FILE) {
21644+ /* currently ftruncate(2) only */
7e9cd9fe 21645+ AuDebugOn(!d_is_reg(dentry));
4a4d8108 21646+ file = ia->ia_file;
521ced18
JR
21647+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1,
21648+ /*fi_lsc*/0);
4a4d8108
AM
21649+ if (unlikely(err))
21650+ goto out_si;
21651+ ia->ia_file = au_hf_top(file);
21652+ a->udba = AuOpt_UDBA_NONE;
21653+ } else {
21654+ /* fchmod() doesn't pass ia_file */
21655+ a->udba = au_opt_udba(sb);
027c5e7a
AM
21656+ di_write_lock_child(dentry);
21657+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
21658+ if (d_unhashed(dentry))
21659+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
21660+ if (a->udba != AuOpt_UDBA_NONE) {
21661+ AuDebugOn(IS_ROOT(dentry));
21662+ err = au_reval_for_attr(dentry, au_sigen(sb));
21663+ if (unlikely(err))
21664+ goto out_dentry;
21665+ }
dece6358 21666+ }
dece6358 21667+
4a4d8108
AM
21668+ err = au_pin_and_icpup(dentry, ia, a);
21669+ if (unlikely(err < 0))
21670+ goto out_dentry;
21671+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
21672+ ia->ia_file = NULL;
21673+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 21674+ }
dece6358 21675+
4a4d8108
AM
21676+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
21677+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
21678+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 21679+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
21680+ if (unlikely(err))
21681+ goto out_unlock;
21682+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
21683+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 21684+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
21685+ if (unlikely(err))
21686+ goto out_unlock;
21687+ }
dece6358 21688+
4a4d8108
AM
21689+ if (ia->ia_valid & ATTR_SIZE) {
21690+ struct file *f;
1308ab2a 21691+
953406b4 21692+ if (ia->ia_size < i_size_read(inode))
4a4d8108 21693+ /* unmap only */
953406b4 21694+ truncate_setsize(inode, ia->ia_size);
1308ab2a 21695+
4a4d8108
AM
21696+ f = NULL;
21697+ if (ia->ia_valid & ATTR_FILE)
21698+ f = ia->ia_file;
febd17d6 21699+ inode_unlock(a->h_inode);
4a4d8108 21700+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
febd17d6 21701+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
523b37e3
AM
21702+ } else {
21703+ delegated = NULL;
21704+ while (1) {
21705+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
21706+ if (delegated) {
21707+ err = break_deleg_wait(&delegated);
21708+ if (!err)
21709+ continue;
21710+ }
21711+ break;
21712+ }
21713+ }
8cdd5066
JR
21714+ /*
21715+ * regardless aufs 'acl' option setting.
21716+ * why don't all acl-aware fs call this func from their ->setattr()?
21717+ */
21718+ if (!err && (ia->ia_valid & ATTR_MODE))
21719+ err = vfsub_acl_chmod(a->h_inode, ia->ia_mode);
4a4d8108
AM
21720+ if (!err)
21721+ au_cpup_attr_changeable(inode);
1308ab2a 21722+
4f0767ce 21723+out_unlock:
febd17d6 21724+ inode_unlock(a->h_inode);
4a4d8108 21725+ au_unpin(&a->pin);
027c5e7a 21726+ if (unlikely(err))
5afbbe0d 21727+ au_update_dbtop(dentry);
4f0767ce 21728+out_dentry:
4a4d8108
AM
21729+ di_write_unlock(dentry);
21730+ if (file) {
21731+ fi_write_unlock(file);
21732+ ia->ia_file = file;
21733+ ia->ia_valid |= ATTR_FILE;
21734+ }
4f0767ce 21735+out_si:
4a4d8108 21736+ si_read_unlock(sb);
e49829fe 21737+out_kfree:
9f237c51 21738+ au_kfree_rcu(a);
4f0767ce 21739+out:
4a4d8108
AM
21740+ AuTraceErr(err);
21741+ return err;
1facf9fc 21742+}
21743+
c1595e42
JR
21744+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
21745+static int au_h_path_to_set_attr(struct dentry *dentry,
21746+ struct au_icpup_args *a, struct path *h_path)
21747+{
21748+ int err;
21749+ struct super_block *sb;
21750+
21751+ sb = dentry->d_sb;
21752+ a->udba = au_opt_udba(sb);
21753+ /* no d_unlinked(), to set UDBA_NONE for root */
21754+ if (d_unhashed(dentry))
21755+ a->udba = AuOpt_UDBA_NONE;
21756+ if (a->udba != AuOpt_UDBA_NONE) {
21757+ AuDebugOn(IS_ROOT(dentry));
21758+ err = au_reval_for_attr(dentry, au_sigen(sb));
21759+ if (unlikely(err))
21760+ goto out;
21761+ }
21762+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a);
21763+ if (unlikely(err < 0))
21764+ goto out;
21765+
21766+ h_path->dentry = a->h_path.dentry;
21767+ h_path->mnt = au_sbr_mnt(sb, a->btgt);
21768+
21769+out:
21770+ return err;
21771+}
21772+
f2c43d5f
AM
21773+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
21774+ struct au_sxattr *arg)
c1595e42
JR
21775+{
21776+ int err;
21777+ struct path h_path;
21778+ struct super_block *sb;
21779+ struct au_icpup_args *a;
5afbbe0d 21780+ struct inode *h_inode;
c1595e42 21781+
c1595e42
JR
21782+ IMustLock(inode);
21783+
21784+ err = -ENOMEM;
21785+ a = kzalloc(sizeof(*a), GFP_NOFS);
21786+ if (unlikely(!a))
21787+ goto out;
21788+
21789+ sb = dentry->d_sb;
21790+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21791+ if (unlikely(err))
21792+ goto out_kfree;
21793+
21794+ h_path.dentry = NULL; /* silence gcc */
21795+ di_write_lock_child(dentry);
21796+ err = au_h_path_to_set_attr(dentry, a, &h_path);
21797+ if (unlikely(err))
21798+ goto out_di;
21799+
febd17d6 21800+ inode_unlock(a->h_inode);
c1595e42
JR
21801+ switch (arg->type) {
21802+ case AU_XATTR_SET:
5afbbe0d 21803+ AuDebugOn(d_is_negative(h_path.dentry));
c1595e42
JR
21804+ err = vfsub_setxattr(h_path.dentry,
21805+ arg->u.set.name, arg->u.set.value,
21806+ arg->u.set.size, arg->u.set.flags);
21807+ break;
c1595e42
JR
21808+ case AU_ACL_SET:
21809+ err = -EOPNOTSUPP;
5527c038 21810+ h_inode = d_inode(h_path.dentry);
c1595e42 21811+ if (h_inode->i_op->set_acl)
f2c43d5f 21812+ /* this will call posix_acl_update_mode */
c1595e42
JR
21813+ err = h_inode->i_op->set_acl(h_inode,
21814+ arg->u.acl_set.acl,
21815+ arg->u.acl_set.type);
21816+ break;
21817+ }
21818+ if (!err)
21819+ au_cpup_attr_timesizes(inode);
21820+
21821+ au_unpin(&a->pin);
21822+ if (unlikely(err))
5afbbe0d 21823+ au_update_dbtop(dentry);
c1595e42
JR
21824+
21825+out_di:
21826+ di_write_unlock(dentry);
21827+ si_read_unlock(sb);
21828+out_kfree:
9f237c51 21829+ au_kfree_rcu(a);
c1595e42
JR
21830+out:
21831+ AuTraceErr(err);
21832+ return err;
21833+}
21834+#endif
21835+
4a4d8108
AM
21836+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
21837+ unsigned int nlink)
1facf9fc 21838+{
9dbd164d
AM
21839+ unsigned int n;
21840+
4a4d8108 21841+ inode->i_mode = st->mode;
86dc4139
AM
21842+ /* don't i_[ug]id_write() here */
21843+ inode->i_uid = st->uid;
21844+ inode->i_gid = st->gid;
4a4d8108
AM
21845+ inode->i_atime = st->atime;
21846+ inode->i_mtime = st->mtime;
21847+ inode->i_ctime = st->ctime;
1facf9fc 21848+
4a4d8108
AM
21849+ au_cpup_attr_nlink(inode, /*force*/0);
21850+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
21851+ n = inode->i_nlink;
21852+ n -= nlink;
21853+ n += st->nlink;
f6b6e03d 21854+ smp_mb(); /* for i_nlink */
7eafdf33 21855+ /* 0 can happen */
92d182d2 21856+ set_nlink(inode, n);
4a4d8108 21857+ }
1facf9fc 21858+
4a4d8108
AM
21859+ spin_lock(&inode->i_lock);
21860+ inode->i_blocks = st->blocks;
21861+ i_size_write(inode, st->size);
21862+ spin_unlock(&inode->i_lock);
1facf9fc 21863+}
21864+
c1595e42 21865+/*
f2c43d5f 21866+ * common routine for aufs_getattr() and au_getxattr().
c1595e42
JR
21867+ * returns zero or negative (an error).
21868+ * @dentry will be read-locked in success.
21869+ */
a2654f78
AM
21870+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
21871+ int locked)
1facf9fc 21872+{
4a4d8108 21873+ int err;
076b876e 21874+ unsigned int mnt_flags, sigen;
c1595e42 21875+ unsigned char udba_none;
4a4d8108 21876+ aufs_bindex_t bindex;
4a4d8108
AM
21877+ struct super_block *sb, *h_sb;
21878+ struct inode *inode;
1facf9fc 21879+
c1595e42
JR
21880+ h_path->mnt = NULL;
21881+ h_path->dentry = NULL;
21882+
21883+ err = 0;
4a4d8108 21884+ sb = dentry->d_sb;
4a4d8108
AM
21885+ mnt_flags = au_mntflags(sb);
21886+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 21887+
a2654f78
AM
21888+ if (unlikely(locked))
21889+ goto body; /* skip locking dinfo */
21890+
4a4d8108 21891+ /* support fstat(2) */
027c5e7a 21892+ if (!d_unlinked(dentry) && !udba_none) {
076b876e 21893+ sigen = au_sigen(sb);
027c5e7a
AM
21894+ err = au_digen_test(dentry, sigen);
21895+ if (!err) {
4a4d8108 21896+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a 21897+ err = au_dbrange_test(dentry);
c1595e42
JR
21898+ if (unlikely(err)) {
21899+ di_read_unlock(dentry, AuLock_IR);
21900+ goto out;
21901+ }
027c5e7a 21902+ } else {
4a4d8108
AM
21903+ AuDebugOn(IS_ROOT(dentry));
21904+ di_write_lock_child(dentry);
027c5e7a
AM
21905+ err = au_dbrange_test(dentry);
21906+ if (!err)
21907+ err = au_reval_for_attr(dentry, sigen);
c1595e42
JR
21908+ if (!err)
21909+ di_downgrade_lock(dentry, AuLock_IR);
21910+ else {
21911+ di_write_unlock(dentry);
21912+ goto out;
21913+ }
4a4d8108
AM
21914+ }
21915+ } else
21916+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 21917+
a2654f78 21918+body:
5527c038 21919+ inode = d_inode(dentry);
5afbbe0d 21920+ bindex = au_ibtop(inode);
c1595e42
JR
21921+ h_path->mnt = au_sbr_mnt(sb, bindex);
21922+ h_sb = h_path->mnt->mnt_sb;
21923+ if (!force
21924+ && !au_test_fs_bad_iattr(h_sb)
21925+ && udba_none)
21926+ goto out; /* success */
1facf9fc 21927+
5afbbe0d 21928+ if (au_dbtop(dentry) == bindex)
c1595e42 21929+ h_path->dentry = au_h_dptr(dentry, bindex);
4a4d8108 21930+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c1595e42
JR
21931+ h_path->dentry = au_plink_lkup(inode, bindex);
21932+ if (IS_ERR(h_path->dentry))
21933+ /* pretending success */
21934+ h_path->dentry = NULL;
21935+ else
21936+ dput(h_path->dentry);
4a4d8108 21937+ }
c1595e42
JR
21938+
21939+out:
21940+ return err;
21941+}
21942+
521ced18
JR
21943+static int aufs_getattr(const struct path *path, struct kstat *st,
21944+ u32 request, unsigned int query)
c1595e42
JR
21945+{
21946+ int err;
21947+ unsigned char positive;
21948+ struct path h_path;
521ced18 21949+ struct dentry *dentry;
c1595e42
JR
21950+ struct inode *inode;
21951+ struct super_block *sb;
21952+
521ced18 21953+ dentry = path->dentry;
5527c038 21954+ inode = d_inode(dentry);
c1595e42
JR
21955+ sb = dentry->d_sb;
21956+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21957+ if (unlikely(err))
21958+ goto out;
a2654f78 21959+ err = au_h_path_getattr(dentry, /*force*/0, &h_path, /*locked*/0);
c1595e42
JR
21960+ if (unlikely(err))
21961+ goto out_si;
c06a8ce3 21962+ if (unlikely(!h_path.dentry))
c1595e42 21963+ /* illegally overlapped or something */
4a4d8108
AM
21964+ goto out_fill; /* pretending success */
21965+
5527c038 21966+ positive = d_is_positive(h_path.dentry);
4a4d8108 21967+ if (positive)
521ced18
JR
21968+ /* no vfsub version */
21969+ err = vfs_getattr(&h_path, st, request, query);
4a4d8108
AM
21970+ if (!err) {
21971+ if (positive)
c06a8ce3 21972+ au_refresh_iattr(inode, st,
5527c038 21973+ d_inode(h_path.dentry)->i_nlink);
4a4d8108 21974+ goto out_fill; /* success */
1facf9fc 21975+ }
7f207e10 21976+ AuTraceErr(err);
c1595e42 21977+ goto out_di;
4a4d8108 21978+
4f0767ce 21979+out_fill:
4a4d8108 21980+ generic_fillattr(inode, st);
c1595e42 21981+out_di:
4a4d8108 21982+ di_read_unlock(dentry, AuLock_IR);
c1595e42 21983+out_si:
4a4d8108 21984+ si_read_unlock(sb);
7f207e10
AM
21985+out:
21986+ AuTraceErr(err);
4a4d8108 21987+ return err;
1facf9fc 21988+}
21989+
21990+/* ---------------------------------------------------------------------- */
21991+
febd17d6
JR
21992+static const char *aufs_get_link(struct dentry *dentry, struct inode *inode,
21993+ struct delayed_call *done)
4a4d8108 21994+{
c2c0f25c 21995+ const char *ret;
c2c0f25c 21996+ struct dentry *h_dentry;
febd17d6 21997+ struct inode *h_inode;
4a4d8108 21998+ int err;
c2c0f25c 21999+ aufs_bindex_t bindex;
1facf9fc 22000+
79b8bda9 22001+ ret = NULL; /* suppress a warning */
febd17d6
JR
22002+ err = -ECHILD;
22003+ if (!dentry)
22004+ goto out;
22005+
027c5e7a
AM
22006+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
22007+ if (unlikely(err))
c2c0f25c 22008+ goto out;
027c5e7a
AM
22009+
22010+ err = au_d_hashed_positive(dentry);
c2c0f25c
AM
22011+ if (unlikely(err))
22012+ goto out_unlock;
22013+
22014+ err = -EINVAL;
22015+ inode = d_inode(dentry);
5afbbe0d 22016+ bindex = au_ibtop(inode);
c2c0f25c 22017+ h_inode = au_h_iptr(inode, bindex);
febd17d6 22018+ if (unlikely(!h_inode->i_op->get_link))
c2c0f25c
AM
22019+ goto out_unlock;
22020+
22021+ err = -EBUSY;
22022+ h_dentry = NULL;
5afbbe0d 22023+ if (au_dbtop(dentry) <= bindex) {
c2c0f25c
AM
22024+ h_dentry = au_h_dptr(dentry, bindex);
22025+ if (h_dentry)
22026+ dget(h_dentry);
027c5e7a 22027+ }
c2c0f25c
AM
22028+ if (!h_dentry) {
22029+ h_dentry = d_find_any_alias(h_inode);
22030+ if (IS_ERR(h_dentry)) {
22031+ err = PTR_ERR(h_dentry);
febd17d6 22032+ goto out_unlock;
c2c0f25c
AM
22033+ }
22034+ }
22035+ if (unlikely(!h_dentry))
febd17d6 22036+ goto out_unlock;
1facf9fc 22037+
c2c0f25c 22038+ err = 0;
062440b3 22039+ AuDbg("%ps\n", h_inode->i_op->get_link);
c2c0f25c 22040+ AuDbgDentry(h_dentry);
f2c43d5f 22041+ ret = vfs_get_link(h_dentry, done);
c2c0f25c 22042+ dput(h_dentry);
febd17d6
JR
22043+ if (IS_ERR(ret))
22044+ err = PTR_ERR(ret);
c2c0f25c 22045+
c2c0f25c
AM
22046+out_unlock:
22047+ aufs_read_unlock(dentry, AuLock_IR);
4f0767ce 22048+out:
c2c0f25c
AM
22049+ if (unlikely(err))
22050+ ret = ERR_PTR(err);
22051+ AuTraceErrPtr(ret);
22052+ return ret;
4a4d8108 22053+}
1facf9fc 22054+
4a4d8108 22055+/* ---------------------------------------------------------------------- */
1facf9fc 22056+
e2f27e51
AM
22057+static int au_is_special(struct inode *inode)
22058+{
22059+ return (inode->i_mode & (S_IFBLK | S_IFCHR | S_IFIFO | S_IFSOCK));
22060+}
22061+
acd2b654
AM
22062+static int aufs_update_time(struct inode *inode, struct timespec64 *ts,
22063+ int flags)
4a4d8108 22064+{
0c3ec466 22065+ int err;
e2f27e51 22066+ aufs_bindex_t bindex;
0c3ec466
AM
22067+ struct super_block *sb;
22068+ struct inode *h_inode;
e2f27e51 22069+ struct vfsmount *h_mnt;
0c3ec466
AM
22070+
22071+ sb = inode->i_sb;
e2f27e51
AM
22072+ WARN_ONCE((flags & S_ATIME) && !IS_NOATIME(inode),
22073+ "unexpected s_flags 0x%lx", sb->s_flags);
22074+
0c3ec466
AM
22075+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
22076+ lockdep_off();
22077+ si_read_lock(sb, AuLock_FLUSH);
22078+ ii_write_lock_child(inode);
e2f27e51
AM
22079+
22080+ err = 0;
22081+ bindex = au_ibtop(inode);
22082+ h_inode = au_h_iptr(inode, bindex);
22083+ if (!au_test_ro(sb, bindex, inode)) {
22084+ h_mnt = au_sbr_mnt(sb, bindex);
22085+ err = vfsub_mnt_want_write(h_mnt);
22086+ if (!err) {
22087+ err = vfsub_update_time(h_inode, ts, flags);
22088+ vfsub_mnt_drop_write(h_mnt);
22089+ }
22090+ } else if (au_is_special(h_inode)) {
22091+ /*
22092+ * Never copy-up here.
22093+ * These special files may already be opened and used for
22094+ * communicating. If we copied it up, then the communication
22095+ * would be corrupted.
22096+ */
22097+ AuWarn1("timestamps for i%lu are ignored "
22098+ "since it is on readonly branch (hi%lu).\n",
22099+ inode->i_ino, h_inode->i_ino);
22100+ } else if (flags & ~S_ATIME) {
22101+ err = -EIO;
22102+ AuIOErr1("unexpected flags 0x%x\n", flags);
22103+ AuDebugOn(1);
22104+ }
22105+
38d290e6
JR
22106+ if (!err)
22107+ au_cpup_attr_timesizes(inode);
0c3ec466
AM
22108+ ii_write_unlock(inode);
22109+ si_read_unlock(sb);
22110+ lockdep_on();
38d290e6
JR
22111+
22112+ if (!err && (flags & S_VERSION))
22113+ inode_inc_iversion(inode);
22114+
0c3ec466 22115+ return err;
4a4d8108 22116+}
1facf9fc 22117+
4a4d8108 22118+/* ---------------------------------------------------------------------- */
1308ab2a 22119+
b95c5147
AM
22120+/* no getattr version will be set by module.c:aufs_init() */
22121+struct inode_operations aufs_iop_nogetattr[AuIop_Last],
22122+ aufs_iop[] = {
22123+ [AuIop_SYMLINK] = {
22124+ .permission = aufs_permission,
c1595e42 22125+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
22126+ .get_acl = aufs_get_acl,
22127+ .set_acl = aufs_set_acl, /* unsupport for symlink? */
c1595e42
JR
22128+#endif
22129+
b95c5147
AM
22130+ .setattr = aufs_setattr,
22131+ .getattr = aufs_getattr,
0c3ec466 22132+
c1595e42 22133+#ifdef CONFIG_AUFS_XATTR
b95c5147 22134+ .listxattr = aufs_listxattr,
c1595e42
JR
22135+#endif
22136+
febd17d6 22137+ .get_link = aufs_get_link,
0c3ec466 22138+
b95c5147
AM
22139+ /* .update_time = aufs_update_time */
22140+ },
22141+ [AuIop_DIR] = {
22142+ .create = aufs_create,
22143+ .lookup = aufs_lookup,
22144+ .link = aufs_link,
22145+ .unlink = aufs_unlink,
22146+ .symlink = aufs_symlink,
22147+ .mkdir = aufs_mkdir,
22148+ .rmdir = aufs_rmdir,
22149+ .mknod = aufs_mknod,
22150+ .rename = aufs_rename,
22151+
22152+ .permission = aufs_permission,
c1595e42 22153+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
22154+ .get_acl = aufs_get_acl,
22155+ .set_acl = aufs_set_acl,
c1595e42
JR
22156+#endif
22157+
b95c5147
AM
22158+ .setattr = aufs_setattr,
22159+ .getattr = aufs_getattr,
0c3ec466 22160+
c1595e42 22161+#ifdef CONFIG_AUFS_XATTR
b95c5147 22162+ .listxattr = aufs_listxattr,
c1595e42
JR
22163+#endif
22164+
b95c5147
AM
22165+ .update_time = aufs_update_time,
22166+ .atomic_open = aufs_atomic_open,
22167+ .tmpfile = aufs_tmpfile
22168+ },
22169+ [AuIop_OTHER] = {
22170+ .permission = aufs_permission,
c1595e42 22171+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
22172+ .get_acl = aufs_get_acl,
22173+ .set_acl = aufs_set_acl,
c1595e42
JR
22174+#endif
22175+
b95c5147
AM
22176+ .setattr = aufs_setattr,
22177+ .getattr = aufs_getattr,
0c3ec466 22178+
c1595e42 22179+#ifdef CONFIG_AUFS_XATTR
b95c5147 22180+ .listxattr = aufs_listxattr,
c1595e42
JR
22181+#endif
22182+
b95c5147
AM
22183+ .update_time = aufs_update_time
22184+ }
4a4d8108 22185+};
7f207e10
AM
22186diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
22187--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
22188+++ linux/fs/aufs/i_op_del.c 2019-05-06 09:03:04.816810402 +0200
22189@@ -0,0 +1,513 @@
cd7a4cd9 22190+// SPDX-License-Identifier: GPL-2.0
1facf9fc 22191+/*
ba1aed25 22192+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 22193+ *
22194+ * This program, aufs is free software; you can redistribute it and/or modify
22195+ * it under the terms of the GNU General Public License as published by
22196+ * the Free Software Foundation; either version 2 of the License, or
22197+ * (at your option) any later version.
dece6358
AM
22198+ *
22199+ * This program is distributed in the hope that it will be useful,
22200+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22201+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22202+ * GNU General Public License for more details.
22203+ *
22204+ * You should have received a copy of the GNU General Public License
523b37e3 22205+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22206+ */
22207+
22208+/*
4a4d8108 22209+ * inode operations (del entry)
1308ab2a 22210+ */
dece6358 22211+
eca801bf 22212+#include <linux/iversion.h>
1308ab2a 22213+#include "aufs.h"
dece6358 22214+
4a4d8108
AM
22215+/*
22216+ * decide if a new whiteout for @dentry is necessary or not.
22217+ * when it is necessary, prepare the parent dir for the upper branch whose
22218+ * branch index is @bcpup for creation. the actual creation of the whiteout will
22219+ * be done by caller.
22220+ * return value:
22221+ * 0: wh is unnecessary
22222+ * plus: wh is necessary
22223+ * minus: error
22224+ */
22225+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 22226+{
4a4d8108 22227+ int need_wh, err;
5afbbe0d 22228+ aufs_bindex_t btop;
4a4d8108 22229+ struct super_block *sb;
dece6358 22230+
4a4d8108 22231+ sb = dentry->d_sb;
5afbbe0d 22232+ btop = au_dbtop(dentry);
4a4d8108 22233+ if (*bcpup < 0) {
5afbbe0d
AM
22234+ *bcpup = btop;
22235+ if (au_test_ro(sb, btop, d_inode(dentry))) {
4a4d8108
AM
22236+ err = AuWbrCopyup(au_sbi(sb), dentry);
22237+ *bcpup = err;
22238+ if (unlikely(err < 0))
22239+ goto out;
22240+ }
22241+ } else
5afbbe0d 22242+ AuDebugOn(btop < *bcpup
5527c038 22243+ || au_test_ro(sb, *bcpup, d_inode(dentry)));
5afbbe0d 22244+ AuDbg("bcpup %d, btop %d\n", *bcpup, btop);
1308ab2a 22245+
5afbbe0d 22246+ if (*bcpup != btop) {
4a4d8108
AM
22247+ err = au_cpup_dirs(dentry, *bcpup);
22248+ if (unlikely(err))
22249+ goto out;
22250+ need_wh = 1;
22251+ } else {
027c5e7a 22252+ struct au_dinfo *dinfo, *tmp;
4a4d8108 22253+
027c5e7a
AM
22254+ need_wh = -ENOMEM;
22255+ dinfo = au_di(dentry);
22256+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
22257+ if (tmp) {
22258+ au_di_cp(tmp, dinfo);
22259+ au_di_swap(tmp, dinfo);
22260+ /* returns the number of positive dentries */
5afbbe0d
AM
22261+ need_wh = au_lkup_dentry(dentry, btop + 1,
22262+ /* AuLkup_IGNORE_PERM */ 0);
027c5e7a
AM
22263+ au_di_swap(tmp, dinfo);
22264+ au_rw_write_unlock(&tmp->di_rwsem);
22265+ au_di_free(tmp);
4a4d8108
AM
22266+ }
22267+ }
22268+ AuDbg("need_wh %d\n", need_wh);
22269+ err = need_wh;
22270+
4f0767ce 22271+out:
4a4d8108 22272+ return err;
1facf9fc 22273+}
22274+
4a4d8108
AM
22275+/*
22276+ * simple tests for the del-entry operations.
22277+ * following the checks in vfs, plus the parent-child relationship.
22278+ */
22279+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
22280+ struct dentry *h_parent, int isdir)
1facf9fc 22281+{
4a4d8108
AM
22282+ int err;
22283+ umode_t h_mode;
22284+ struct dentry *h_dentry, *h_latest;
1308ab2a 22285+ struct inode *h_inode;
1facf9fc 22286+
4a4d8108 22287+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 22288+ if (d_really_is_positive(dentry)) {
4a4d8108 22289+ err = -ENOENT;
5527c038
JR
22290+ if (unlikely(d_is_negative(h_dentry)))
22291+ goto out;
22292+ h_inode = d_inode(h_dentry);
22293+ if (unlikely(!h_inode->i_nlink))
4a4d8108 22294+ goto out;
1facf9fc 22295+
4a4d8108
AM
22296+ h_mode = h_inode->i_mode;
22297+ if (!isdir) {
22298+ err = -EISDIR;
22299+ if (unlikely(S_ISDIR(h_mode)))
22300+ goto out;
22301+ } else if (unlikely(!S_ISDIR(h_mode))) {
22302+ err = -ENOTDIR;
22303+ goto out;
22304+ }
22305+ } else {
22306+ /* rename(2) case */
22307+ err = -EIO;
5527c038 22308+ if (unlikely(d_is_positive(h_dentry)))
4a4d8108
AM
22309+ goto out;
22310+ }
1facf9fc 22311+
4a4d8108
AM
22312+ err = -ENOENT;
22313+ /* expected parent dir is locked */
22314+ if (unlikely(h_parent != h_dentry->d_parent))
22315+ goto out;
22316+ err = 0;
22317+
22318+ /*
22319+ * rmdir a dir may break the consistency on some filesystem.
22320+ * let's try heavy test.
22321+ */
22322+ err = -EACCES;
076b876e 22323+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
5527c038 22324+ && au_test_h_perm(d_inode(h_parent),
076b876e 22325+ MAY_EXEC | MAY_WRITE)))
4a4d8108
AM
22326+ goto out;
22327+
076b876e 22328+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
4a4d8108
AM
22329+ err = -EIO;
22330+ if (IS_ERR(h_latest))
22331+ goto out;
22332+ if (h_latest == h_dentry)
22333+ err = 0;
22334+ dput(h_latest);
22335+
4f0767ce 22336+out:
4a4d8108 22337+ return err;
1308ab2a 22338+}
1facf9fc 22339+
4a4d8108
AM
22340+/*
22341+ * decide the branch where we operate for @dentry. the branch index will be set
acd2b654 22342+ * @rbcpup. after deciding it, 'pin' it and store the timestamps of the parent
4a4d8108
AM
22343+ * dir for reverting.
22344+ * when a new whiteout is necessary, create it.
22345+ */
22346+static struct dentry*
22347+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
22348+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 22349+{
4a4d8108
AM
22350+ struct dentry *wh_dentry;
22351+ struct super_block *sb;
22352+ struct path h_path;
22353+ int err, need_wh;
22354+ unsigned int udba;
22355+ aufs_bindex_t bcpup;
dece6358 22356+
4a4d8108
AM
22357+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
22358+ wh_dentry = ERR_PTR(need_wh);
22359+ if (unlikely(need_wh < 0))
22360+ goto out;
22361+
22362+ sb = dentry->d_sb;
22363+ udba = au_opt_udba(sb);
22364+ bcpup = *rbcpup;
22365+ err = au_pin(pin, dentry, bcpup, udba,
22366+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
22367+ wh_dentry = ERR_PTR(err);
22368+ if (unlikely(err))
22369+ goto out;
22370+
22371+ h_path.dentry = au_pinned_h_parent(pin);
22372+ if (udba != AuOpt_UDBA_NONE
5afbbe0d 22373+ && au_dbtop(dentry) == bcpup) {
4a4d8108
AM
22374+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
22375+ wh_dentry = ERR_PTR(err);
22376+ if (unlikely(err))
22377+ goto out_unpin;
22378+ }
22379+
22380+ h_path.mnt = au_sbr_mnt(sb, bcpup);
22381+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
22382+ wh_dentry = NULL;
22383+ if (!need_wh)
22384+ goto out; /* success, no need to create whiteout */
22385+
22386+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
22387+ if (IS_ERR(wh_dentry))
22388+ goto out_unpin;
22389+
22390+ /* returns with the parent is locked and wh_dentry is dget-ed */
22391+ goto out; /* success */
22392+
4f0767ce 22393+out_unpin:
4a4d8108 22394+ au_unpin(pin);
4f0767ce 22395+out:
4a4d8108 22396+ return wh_dentry;
1facf9fc 22397+}
22398+
4a4d8108
AM
22399+/*
22400+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
22401+ * in order to be revertible and save time for removing many child whiteouts
22402+ * under the dir.
22403+ * returns 1 when there are too many child whiteout and caller should remove
22404+ * them asynchronously. returns 0 when the number of children is enough small to
22405+ * remove now or the branch fs is a remote fs.
22406+ * otherwise return an error.
22407+ */
22408+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
22409+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 22410+{
4a4d8108
AM
22411+ int rmdir_later, err, dirwh;
22412+ struct dentry *h_dentry;
22413+ struct super_block *sb;
5527c038 22414+ struct inode *inode;
4a4d8108
AM
22415+
22416+ sb = dentry->d_sb;
22417+ SiMustAnyLock(sb);
22418+ h_dentry = au_h_dptr(dentry, bindex);
22419+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
22420+ if (unlikely(err))
22421+ goto out;
22422+
22423+ /* stop monitoring */
5527c038
JR
22424+ inode = d_inode(dentry);
22425+ au_hn_free(au_hi(inode, bindex));
4a4d8108
AM
22426+
22427+ if (!au_test_fs_remote(h_dentry->d_sb)) {
22428+ dirwh = au_sbi(sb)->si_dirwh;
22429+ rmdir_later = (dirwh <= 1);
22430+ if (!rmdir_later)
22431+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
22432+ dirwh);
22433+ if (rmdir_later)
22434+ return rmdir_later;
22435+ }
1facf9fc 22436+
4a4d8108
AM
22437+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
22438+ if (unlikely(err)) {
523b37e3
AM
22439+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
22440+ h_dentry, bindex, err);
4a4d8108
AM
22441+ err = 0;
22442+ }
dece6358 22443+
4f0767ce 22444+out:
4a4d8108
AM
22445+ AuTraceErr(err);
22446+ return err;
22447+}
1308ab2a 22448+
4a4d8108
AM
22449+/*
22450+ * final procedure for deleting a entry.
22451+ * maintain dentry and iattr.
22452+ */
22453+static void epilog(struct inode *dir, struct dentry *dentry,
22454+ aufs_bindex_t bindex)
22455+{
22456+ struct inode *inode;
1308ab2a 22457+
5527c038 22458+ inode = d_inode(dentry);
4a4d8108
AM
22459+ d_drop(dentry);
22460+ inode->i_ctime = dir->i_ctime;
1308ab2a 22461+
b912730e 22462+ au_dir_ts(dir, bindex);
be118d29 22463+ inode_inc_iversion(dir);
1facf9fc 22464+}
22465+
4a4d8108
AM
22466+/*
22467+ * when an error happened, remove the created whiteout and revert everything.
22468+ */
7f207e10
AM
22469+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
22470+ aufs_bindex_t bwh, struct dentry *wh_dentry,
22471+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 22472+{
4a4d8108
AM
22473+ int rerr;
22474+ struct path h_path = {
22475+ .dentry = wh_dentry,
7f207e10 22476+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 22477+ };
dece6358 22478+
7f207e10 22479+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
22480+ if (!rerr) {
22481+ au_set_dbwh(dentry, bwh);
22482+ au_dtime_revert(dt);
22483+ return 0;
22484+ }
dece6358 22485+
523b37e3 22486+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 22487+ return -EIO;
1facf9fc 22488+}
22489+
4a4d8108 22490+/* ---------------------------------------------------------------------- */
1facf9fc 22491+
4a4d8108 22492+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 22493+{
4a4d8108 22494+ int err;
5afbbe0d 22495+ aufs_bindex_t bwh, bindex, btop;
523b37e3 22496+ struct inode *inode, *h_dir, *delegated;
4a4d8108 22497+ struct dentry *parent, *wh_dentry;
acd2b654 22498+ /* to reduce stack size */
c2b27bf2
AM
22499+ struct {
22500+ struct au_dtime dt;
22501+ struct au_pin pin;
22502+ struct path h_path;
22503+ } *a;
1facf9fc 22504+
4a4d8108 22505+ IMustLock(dir);
027c5e7a 22506+
c2b27bf2
AM
22507+ err = -ENOMEM;
22508+ a = kmalloc(sizeof(*a), GFP_NOFS);
22509+ if (unlikely(!a))
22510+ goto out;
22511+
027c5e7a
AM
22512+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
22513+ if (unlikely(err))
c2b27bf2 22514+ goto out_free;
027c5e7a
AM
22515+ err = au_d_hashed_positive(dentry);
22516+ if (unlikely(err))
22517+ goto out_unlock;
5527c038 22518+ inode = d_inode(dentry);
4a4d8108 22519+ IMustLock(inode);
027c5e7a 22520+ err = -EISDIR;
2000de60 22521+ if (unlikely(d_is_dir(dentry)))
027c5e7a 22522+ goto out_unlock; /* possible? */
1facf9fc 22523+
5afbbe0d 22524+ btop = au_dbtop(dentry);
4a4d8108
AM
22525+ bwh = au_dbwh(dentry);
22526+ bindex = -1;
027c5e7a
AM
22527+ parent = dentry->d_parent; /* dir inode is locked */
22528+ di_write_lock_parent(parent);
c2b27bf2
AM
22529+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
22530+ &a->pin);
4a4d8108
AM
22531+ err = PTR_ERR(wh_dentry);
22532+ if (IS_ERR(wh_dentry))
027c5e7a 22533+ goto out_parent;
1facf9fc 22534+
5afbbe0d
AM
22535+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, btop);
22536+ a->h_path.dentry = au_h_dptr(dentry, btop);
c2b27bf2 22537+ dget(a->h_path.dentry);
5afbbe0d 22538+ if (bindex == btop) {
c2b27bf2 22539+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
22540+ delegated = NULL;
22541+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
22542+ if (unlikely(err == -EWOULDBLOCK)) {
22543+ pr_warn("cannot retry for NFSv4 delegation"
22544+ " for an internal unlink\n");
22545+ iput(delegated);
22546+ }
4a4d8108
AM
22547+ } else {
22548+ /* dir inode is locked */
5527c038 22549+ h_dir = d_inode(wh_dentry->d_parent);
4a4d8108
AM
22550+ IMustLock(h_dir);
22551+ err = 0;
22552+ }
dece6358 22553+
4a4d8108 22554+ if (!err) {
7f207e10 22555+ vfsub_drop_nlink(inode);
4a4d8108
AM
22556+ epilog(dir, dentry, bindex);
22557+
22558+ /* update target timestamps */
5afbbe0d 22559+ if (bindex == btop) {
c2b27bf2
AM
22560+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
22561+ /*ignore*/
5527c038 22562+ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
4a4d8108
AM
22563+ } else
22564+ /* todo: this timestamp may be reverted later */
22565+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 22566+ goto out_unpin; /* success */
1facf9fc 22567+ }
22568+
4a4d8108
AM
22569+ /* revert */
22570+ if (wh_dentry) {
22571+ int rerr;
22572+
c2b27bf2
AM
22573+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
22574+ &a->dt);
4a4d8108
AM
22575+ if (rerr)
22576+ err = rerr;
dece6358 22577+ }
1facf9fc 22578+
027c5e7a 22579+out_unpin:
c2b27bf2 22580+ au_unpin(&a->pin);
4a4d8108 22581+ dput(wh_dentry);
c2b27bf2 22582+ dput(a->h_path.dentry);
027c5e7a 22583+out_parent:
4a4d8108 22584+ di_write_unlock(parent);
027c5e7a 22585+out_unlock:
4a4d8108 22586+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 22587+out_free:
9f237c51 22588+ au_kfree_rcu(a);
027c5e7a 22589+out:
4a4d8108 22590+ return err;
dece6358
AM
22591+}
22592+
4a4d8108 22593+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 22594+{
4a4d8108 22595+ int err, rmdir_later;
5afbbe0d 22596+ aufs_bindex_t bwh, bindex, btop;
4a4d8108
AM
22597+ struct inode *inode;
22598+ struct dentry *parent, *wh_dentry, *h_dentry;
22599+ struct au_whtmp_rmdir *args;
acd2b654 22600+ /* to reduce stack size */
c2b27bf2
AM
22601+ struct {
22602+ struct au_dtime dt;
22603+ struct au_pin pin;
22604+ } *a;
1facf9fc 22605+
4a4d8108 22606+ IMustLock(dir);
027c5e7a 22607+
c2b27bf2
AM
22608+ err = -ENOMEM;
22609+ a = kmalloc(sizeof(*a), GFP_NOFS);
22610+ if (unlikely(!a))
22611+ goto out;
22612+
027c5e7a
AM
22613+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
22614+ if (unlikely(err))
c2b27bf2 22615+ goto out_free;
53392da6
AM
22616+ err = au_alive_dir(dentry);
22617+ if (unlikely(err))
027c5e7a 22618+ goto out_unlock;
5527c038 22619+ inode = d_inode(dentry);
4a4d8108 22620+ IMustLock(inode);
027c5e7a 22621+ err = -ENOTDIR;
2000de60 22622+ if (unlikely(!d_is_dir(dentry)))
027c5e7a 22623+ goto out_unlock; /* possible? */
dece6358 22624+
4a4d8108
AM
22625+ err = -ENOMEM;
22626+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
22627+ if (unlikely(!args))
22628+ goto out_unlock;
dece6358 22629+
4a4d8108
AM
22630+ parent = dentry->d_parent; /* dir inode is locked */
22631+ di_write_lock_parent(parent);
22632+ err = au_test_empty(dentry, &args->whlist);
22633+ if (unlikely(err))
027c5e7a 22634+ goto out_parent;
1facf9fc 22635+
5afbbe0d 22636+ btop = au_dbtop(dentry);
4a4d8108
AM
22637+ bwh = au_dbwh(dentry);
22638+ bindex = -1;
c2b27bf2
AM
22639+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
22640+ &a->pin);
4a4d8108
AM
22641+ err = PTR_ERR(wh_dentry);
22642+ if (IS_ERR(wh_dentry))
027c5e7a 22643+ goto out_parent;
1facf9fc 22644+
5afbbe0d 22645+ h_dentry = au_h_dptr(dentry, btop);
4a4d8108
AM
22646+ dget(h_dentry);
22647+ rmdir_later = 0;
5afbbe0d
AM
22648+ if (bindex == btop) {
22649+ err = renwh_and_rmdir(dentry, btop, &args->whlist, dir);
4a4d8108
AM
22650+ if (err > 0) {
22651+ rmdir_later = err;
22652+ err = 0;
22653+ }
22654+ } else {
22655+ /* stop monitoring */
5afbbe0d 22656+ au_hn_free(au_hi(inode, btop));
4a4d8108
AM
22657+
22658+ /* dir inode is locked */
5527c038 22659+ IMustLock(d_inode(wh_dentry->d_parent));
1facf9fc 22660+ err = 0;
22661+ }
22662+
4a4d8108 22663+ if (!err) {
027c5e7a 22664+ vfsub_dead_dir(inode);
4a4d8108
AM
22665+ au_set_dbdiropq(dentry, -1);
22666+ epilog(dir, dentry, bindex);
1308ab2a 22667+
4a4d8108 22668+ if (rmdir_later) {
5afbbe0d 22669+ au_whtmp_kick_rmdir(dir, btop, h_dentry, args);
4a4d8108
AM
22670+ args = NULL;
22671+ }
1308ab2a 22672+
4a4d8108 22673+ goto out_unpin; /* success */
1facf9fc 22674+ }
22675+
4a4d8108
AM
22676+ /* revert */
22677+ AuLabel(revert);
22678+ if (wh_dentry) {
22679+ int rerr;
1308ab2a 22680+
c2b27bf2
AM
22681+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
22682+ &a->dt);
4a4d8108
AM
22683+ if (rerr)
22684+ err = rerr;
1facf9fc 22685+ }
22686+
4f0767ce 22687+out_unpin:
c2b27bf2 22688+ au_unpin(&a->pin);
4a4d8108
AM
22689+ dput(wh_dentry);
22690+ dput(h_dentry);
027c5e7a 22691+out_parent:
4a4d8108
AM
22692+ di_write_unlock(parent);
22693+ if (args)
22694+ au_whtmp_rmdir_free(args);
4f0767ce 22695+out_unlock:
4a4d8108 22696+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 22697+out_free:
9f237c51 22698+ au_kfree_rcu(a);
4f0767ce 22699+out:
4a4d8108
AM
22700+ AuTraceErr(err);
22701+ return err;
dece6358 22702+}
7f207e10
AM
22703diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
22704--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
22705+++ linux/fs/aufs/i_op_ren.c 2019-05-06 09:03:04.820143837 +0200
22706@@ -0,0 +1,1250 @@
cd7a4cd9 22707+// SPDX-License-Identifier: GPL-2.0
1facf9fc 22708+/*
ba1aed25 22709+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 22710+ *
22711+ * This program, aufs is free software; you can redistribute it and/or modify
22712+ * it under the terms of the GNU General Public License as published by
22713+ * the Free Software Foundation; either version 2 of the License, or
22714+ * (at your option) any later version.
dece6358
AM
22715+ *
22716+ * This program is distributed in the hope that it will be useful,
22717+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22718+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22719+ * GNU General Public License for more details.
22720+ *
22721+ * You should have received a copy of the GNU General Public License
523b37e3 22722+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22723+ */
22724+
22725+/*
4a4d8108
AM
22726+ * inode operation (rename entry)
22727+ * todo: this is crazy monster
1facf9fc 22728+ */
22729+
eca801bf 22730+#include <linux/iversion.h>
1facf9fc 22731+#include "aufs.h"
22732+
4a4d8108
AM
22733+enum { AuSRC, AuDST, AuSrcDst };
22734+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 22735+
f2c43d5f
AM
22736+#define AuRen_ISDIR_SRC 1
22737+#define AuRen_ISDIR_DST (1 << 1)
22738+#define AuRen_ISSAMEDIR (1 << 2)
22739+#define AuRen_WHSRC (1 << 3)
22740+#define AuRen_WHDST (1 << 4)
22741+#define AuRen_MNT_WRITE (1 << 5)
22742+#define AuRen_DT_DSTDIR (1 << 6)
22743+#define AuRen_DIROPQ_SRC (1 << 7)
22744+#define AuRen_DIROPQ_DST (1 << 8)
8b6a4947
AM
22745+#define AuRen_DIRREN (1 << 9)
22746+#define AuRen_DROPPED_SRC (1 << 10)
22747+#define AuRen_DROPPED_DST (1 << 11)
4a4d8108 22748+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
22749+#define au_fset_ren(flags, name) \
22750+ do { (flags) |= AuRen_##name; } while (0)
22751+#define au_fclr_ren(flags, name) \
22752+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 22753+
8b6a4947
AM
22754+#ifndef CONFIG_AUFS_DIRREN
22755+#undef AuRen_DIRREN
22756+#define AuRen_DIRREN 0
22757+#endif
22758+
4a4d8108
AM
22759+struct au_ren_args {
22760+ struct {
22761+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
22762+ *wh_dentry;
22763+ struct inode *dir, *inode;
f2c43d5f 22764+ struct au_hinode *hdir, *hinode;
4a4d8108 22765+ struct au_dtime dt[AuParentChild];
f2c43d5f 22766+ aufs_bindex_t btop, bdiropq;
4a4d8108 22767+ } sd[AuSrcDst];
1facf9fc 22768+
4a4d8108
AM
22769+#define src_dentry sd[AuSRC].dentry
22770+#define src_dir sd[AuSRC].dir
22771+#define src_inode sd[AuSRC].inode
22772+#define src_h_dentry sd[AuSRC].h_dentry
22773+#define src_parent sd[AuSRC].parent
22774+#define src_h_parent sd[AuSRC].h_parent
22775+#define src_wh_dentry sd[AuSRC].wh_dentry
22776+#define src_hdir sd[AuSRC].hdir
f2c43d5f 22777+#define src_hinode sd[AuSRC].hinode
4a4d8108
AM
22778+#define src_h_dir sd[AuSRC].hdir->hi_inode
22779+#define src_dt sd[AuSRC].dt
5afbbe0d 22780+#define src_btop sd[AuSRC].btop
f2c43d5f 22781+#define src_bdiropq sd[AuSRC].bdiropq
1facf9fc 22782+
4a4d8108
AM
22783+#define dst_dentry sd[AuDST].dentry
22784+#define dst_dir sd[AuDST].dir
22785+#define dst_inode sd[AuDST].inode
22786+#define dst_h_dentry sd[AuDST].h_dentry
22787+#define dst_parent sd[AuDST].parent
22788+#define dst_h_parent sd[AuDST].h_parent
22789+#define dst_wh_dentry sd[AuDST].wh_dentry
22790+#define dst_hdir sd[AuDST].hdir
f2c43d5f 22791+#define dst_hinode sd[AuDST].hinode
4a4d8108
AM
22792+#define dst_h_dir sd[AuDST].hdir->hi_inode
22793+#define dst_dt sd[AuDST].dt
5afbbe0d 22794+#define dst_btop sd[AuDST].btop
f2c43d5f 22795+#define dst_bdiropq sd[AuDST].bdiropq
4a4d8108
AM
22796+
22797+ struct dentry *h_trap;
22798+ struct au_branch *br;
4a4d8108
AM
22799+ struct path h_path;
22800+ struct au_nhash whlist;
f2c43d5f 22801+ aufs_bindex_t btgt, src_bwh;
1facf9fc 22802+
f2c43d5f
AM
22803+ struct {
22804+ unsigned short auren_flags;
22805+ unsigned char flags; /* syscall parameter */
22806+ unsigned char exchange;
22807+ } __packed;
1facf9fc 22808+
4a4d8108
AM
22809+ struct au_whtmp_rmdir *thargs;
22810+ struct dentry *h_dst;
8b6a4947 22811+ struct au_hinode *h_root;
4a4d8108 22812+};
1308ab2a 22813+
4a4d8108 22814+/* ---------------------------------------------------------------------- */
1308ab2a 22815+
4a4d8108
AM
22816+/*
22817+ * functions for reverting.
22818+ * when an error happened in a single rename systemcall, we should revert
79b8bda9 22819+ * everything as if nothing happened.
4a4d8108
AM
22820+ * we don't need to revert the copied-up/down the parent dir since they are
22821+ * harmless.
22822+ */
1facf9fc 22823+
4a4d8108
AM
22824+#define RevertFailure(fmt, ...) do { \
22825+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
22826+ ##__VA_ARGS__, err, rerr); \
22827+ err = -EIO; \
22828+} while (0)
1facf9fc 22829+
f2c43d5f 22830+static void au_ren_do_rev_diropq(int err, struct au_ren_args *a, int idx)
1facf9fc 22831+{
4a4d8108 22832+ int rerr;
f2c43d5f
AM
22833+ struct dentry *d;
22834+#define src_or_dst(member) a->sd[idx].member
1facf9fc 22835+
f2c43d5f
AM
22836+ d = src_or_dst(dentry); /* {src,dst}_dentry */
22837+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD);
22838+ rerr = au_diropq_remove(d, a->btgt);
22839+ au_hn_inode_unlock(src_or_dst(hinode));
22840+ au_set_dbdiropq(d, src_or_dst(bdiropq));
4a4d8108 22841+ if (rerr)
f2c43d5f
AM
22842+ RevertFailure("remove diropq %pd", d);
22843+
22844+#undef src_or_dst_
22845+}
22846+
22847+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
22848+{
22849+ if (au_ftest_ren(a->auren_flags, DIROPQ_SRC))
22850+ au_ren_do_rev_diropq(err, a, AuSRC);
22851+ if (au_ftest_ren(a->auren_flags, DIROPQ_DST))
22852+ au_ren_do_rev_diropq(err, a, AuDST);
4a4d8108 22853+}
1facf9fc 22854+
4a4d8108
AM
22855+static void au_ren_rev_rename(int err, struct au_ren_args *a)
22856+{
22857+ int rerr;
523b37e3 22858+ struct inode *delegated;
1facf9fc 22859+
b4510431
AM
22860+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
22861+ a->src_h_parent);
4a4d8108
AM
22862+ rerr = PTR_ERR(a->h_path.dentry);
22863+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 22864+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 22865+ return;
1facf9fc 22866+ }
22867+
523b37e3 22868+ delegated = NULL;
4a4d8108
AM
22869+ rerr = vfsub_rename(a->dst_h_dir,
22870+ au_h_dptr(a->src_dentry, a->btgt),
f2c43d5f 22871+ a->src_h_dir, &a->h_path, &delegated, a->flags);
523b37e3
AM
22872+ if (unlikely(rerr == -EWOULDBLOCK)) {
22873+ pr_warn("cannot retry for NFSv4 delegation"
22874+ " for an internal rename\n");
22875+ iput(delegated);
22876+ }
4a4d8108
AM
22877+ d_drop(a->h_path.dentry);
22878+ dput(a->h_path.dentry);
22879+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
22880+ if (rerr)
523b37e3 22881+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 22882+}
22883+
4a4d8108 22884+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 22885+{
4a4d8108 22886+ int rerr;
523b37e3 22887+ struct inode *delegated;
dece6358 22888+
b4510431
AM
22889+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
22890+ a->dst_h_parent);
4a4d8108
AM
22891+ rerr = PTR_ERR(a->h_path.dentry);
22892+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 22893+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
22894+ return;
22895+ }
5527c038 22896+ if (d_is_positive(a->h_path.dentry)) {
4a4d8108
AM
22897+ d_drop(a->h_path.dentry);
22898+ dput(a->h_path.dentry);
22899+ return;
dece6358
AM
22900+ }
22901+
523b37e3
AM
22902+ delegated = NULL;
22903+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
f2c43d5f 22904+ &delegated, a->flags);
523b37e3
AM
22905+ if (unlikely(rerr == -EWOULDBLOCK)) {
22906+ pr_warn("cannot retry for NFSv4 delegation"
22907+ " for an internal rename\n");
22908+ iput(delegated);
22909+ }
4a4d8108
AM
22910+ d_drop(a->h_path.dentry);
22911+ dput(a->h_path.dentry);
22912+ if (!rerr)
22913+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
22914+ else
523b37e3 22915+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 22916+}
1308ab2a 22917+
4a4d8108
AM
22918+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
22919+{
22920+ int rerr;
1308ab2a 22921+
4a4d8108
AM
22922+ a->h_path.dentry = a->src_wh_dentry;
22923+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 22924+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 22925+ if (rerr)
523b37e3 22926+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 22927+}
4a4d8108 22928+#undef RevertFailure
1facf9fc 22929+
1308ab2a 22930+/* ---------------------------------------------------------------------- */
22931+
4a4d8108
AM
22932+/*
22933+ * when we have to copyup the renaming entry, do it with the rename-target name
22934+ * in order to minimize the cost (the later actual rename is unnecessary).
22935+ * otherwise rename it on the target branch.
22936+ */
22937+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 22938+{
dece6358 22939+ int err;
4a4d8108 22940+ struct dentry *d;
523b37e3 22941+ struct inode *delegated;
1facf9fc 22942+
4a4d8108 22943+ d = a->src_dentry;
5afbbe0d 22944+ if (au_dbtop(d) == a->btgt) {
4a4d8108 22945+ a->h_path.dentry = a->dst_h_dentry;
5afbbe0d 22946+ AuDebugOn(au_dbtop(d) != a->btgt);
523b37e3 22947+ delegated = NULL;
4a4d8108 22948+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
f2c43d5f
AM
22949+ a->dst_h_dir, &a->h_path, &delegated,
22950+ a->flags);
523b37e3
AM
22951+ if (unlikely(err == -EWOULDBLOCK)) {
22952+ pr_warn("cannot retry for NFSv4 delegation"
22953+ " for an internal rename\n");
22954+ iput(delegated);
22955+ }
c2b27bf2 22956+ } else
86dc4139 22957+ BUG();
1308ab2a 22958+
027c5e7a
AM
22959+ if (!err && a->h_dst)
22960+ /* it will be set to dinfo later */
22961+ dget(a->h_dst);
1facf9fc 22962+
dece6358
AM
22963+ return err;
22964+}
1facf9fc 22965+
4a4d8108
AM
22966+/* cf. aufs_rmdir() */
22967+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 22968+{
4a4d8108
AM
22969+ int err;
22970+ struct inode *dir;
1facf9fc 22971+
4a4d8108
AM
22972+ dir = a->dst_dir;
22973+ SiMustAnyLock(dir->i_sb);
22974+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
22975+ au_sbi(dir->i_sb)->si_dirwh)
22976+ || au_test_fs_remote(a->h_dst->d_sb)) {
22977+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
22978+ if (unlikely(err))
523b37e3
AM
22979+ pr_warn("failed removing whtmp dir %pd (%d), "
22980+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
22981+ } else {
22982+ au_nhash_wh_free(&a->thargs->whlist);
22983+ a->thargs->whlist = a->whlist;
22984+ a->whlist.nh_num = 0;
22985+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
22986+ dput(a->h_dst);
22987+ a->thargs = NULL;
22988+ }
22989+
22990+ return 0;
1308ab2a 22991+}
1facf9fc 22992+
4a4d8108 22993+/* make it 'opaque' dir. */
f2c43d5f 22994+static int au_ren_do_diropq(struct au_ren_args *a, int idx)
4a4d8108
AM
22995+{
22996+ int err;
f2c43d5f
AM
22997+ struct dentry *d, *diropq;
22998+#define src_or_dst(member) a->sd[idx].member
1facf9fc 22999+
4a4d8108 23000+ err = 0;
f2c43d5f
AM
23001+ d = src_or_dst(dentry); /* {src,dst}_dentry */
23002+ src_or_dst(bdiropq) = au_dbdiropq(d);
23003+ src_or_dst(hinode) = au_hi(src_or_dst(inode), a->btgt);
23004+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD);
23005+ diropq = au_diropq_create(d, a->btgt);
23006+ au_hn_inode_unlock(src_or_dst(hinode));
4a4d8108
AM
23007+ if (IS_ERR(diropq))
23008+ err = PTR_ERR(diropq);
076b876e
AM
23009+ else
23010+ dput(diropq);
1facf9fc 23011+
f2c43d5f 23012+#undef src_or_dst_
4a4d8108
AM
23013+ return err;
23014+}
1facf9fc 23015+
f2c43d5f 23016+static int au_ren_diropq(struct au_ren_args *a)
4a4d8108
AM
23017+{
23018+ int err;
f2c43d5f
AM
23019+ unsigned char always;
23020+ struct dentry *d;
1facf9fc 23021+
f2c43d5f
AM
23022+ err = 0;
23023+ d = a->dst_dentry; /* already renamed on the branch */
23024+ always = !!au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ);
23025+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)
8b6a4947 23026+ && !au_ftest_ren(a->auren_flags, DIRREN)
f2c43d5f
AM
23027+ && a->btgt != au_dbdiropq(a->src_dentry)
23028+ && (a->dst_wh_dentry
23029+ || a->btgt <= au_dbdiropq(d)
23030+ /* hide the lower to keep xino */
23031+ /* the lowers may not be a dir, but we hide them anyway */
23032+ || a->btgt < au_dbbot(d)
23033+ || always)) {
23034+ AuDbg("here\n");
23035+ err = au_ren_do_diropq(a, AuSRC);
23036+ if (unlikely(err))
4a4d8108 23037+ goto out;
f2c43d5f 23038+ au_fset_ren(a->auren_flags, DIROPQ_SRC);
4a4d8108 23039+ }
f2c43d5f
AM
23040+ if (!a->exchange)
23041+ goto out; /* success */
1facf9fc 23042+
f2c43d5f
AM
23043+ d = a->src_dentry; /* already renamed on the branch */
23044+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)
23045+ && a->btgt != au_dbdiropq(a->dst_dentry)
23046+ && (a->btgt < au_dbdiropq(d)
23047+ || a->btgt < au_dbbot(d)
23048+ || always)) {
23049+ AuDbgDentry(a->src_dentry);
23050+ AuDbgDentry(a->dst_dentry);
23051+ err = au_ren_do_diropq(a, AuDST);
4a4d8108 23052+ if (unlikely(err))
f2c43d5f
AM
23053+ goto out_rev_src;
23054+ au_fset_ren(a->auren_flags, DIROPQ_DST);
23055+ }
23056+ goto out; /* success */
dece6358 23057+
f2c43d5f
AM
23058+out_rev_src:
23059+ AuDbg("err %d, reverting src\n", err);
23060+ au_ren_rev_diropq(err, a);
23061+out:
23062+ return err;
23063+}
23064+
23065+static int do_rename(struct au_ren_args *a)
23066+{
23067+ int err;
23068+ struct dentry *d, *h_d;
23069+
23070+ if (!a->exchange) {
23071+ /* prepare workqueue args for asynchronous rmdir */
23072+ h_d = a->dst_h_dentry;
23073+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)
8b6a4947 23074+ /* && !au_ftest_ren(a->auren_flags, DIRREN) */
f2c43d5f
AM
23075+ && d_is_positive(h_d)) {
23076+ err = -ENOMEM;
23077+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb,
23078+ GFP_NOFS);
23079+ if (unlikely(!a->thargs))
23080+ goto out;
23081+ a->h_dst = dget(h_d);
23082+ }
23083+
23084+ /* create whiteout for src_dentry */
23085+ if (au_ftest_ren(a->auren_flags, WHSRC)) {
23086+ a->src_bwh = au_dbwh(a->src_dentry);
23087+ AuDebugOn(a->src_bwh >= 0);
23088+ a->src_wh_dentry = au_wh_create(a->src_dentry, a->btgt,
23089+ a->src_h_parent);
23090+ err = PTR_ERR(a->src_wh_dentry);
23091+ if (IS_ERR(a->src_wh_dentry))
23092+ goto out_thargs;
23093+ }
23094+
23095+ /* lookup whiteout for dentry */
23096+ if (au_ftest_ren(a->auren_flags, WHDST)) {
23097+ h_d = au_wh_lkup(a->dst_h_parent,
23098+ &a->dst_dentry->d_name, a->br);
23099+ err = PTR_ERR(h_d);
23100+ if (IS_ERR(h_d))
23101+ goto out_whsrc;
23102+ if (d_is_negative(h_d))
23103+ dput(h_d);
23104+ else
23105+ a->dst_wh_dentry = h_d;
23106+ }
23107+
23108+ /* rename dentry to tmpwh */
23109+ if (a->thargs) {
23110+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
23111+ if (unlikely(err))
23112+ goto out_whdst;
23113+
23114+ d = a->dst_dentry;
23115+ au_set_h_dptr(d, a->btgt, NULL);
23116+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
23117+ if (unlikely(err))
23118+ goto out_whtmp;
23119+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
23120+ }
4a4d8108 23121+ }
1facf9fc 23122+
5afbbe0d 23123+ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_btop != a->btgt);
8b6a4947
AM
23124+#if 0
23125+ BUG_ON(!au_ftest_ren(a->auren_flags, DIRREN)
23126+ && d_is_positive(a->dst_h_dentry)
23127+ && a->src_btop != a->btgt);
23128+#endif
1facf9fc 23129+
4a4d8108 23130+ /* rename by vfs_rename or cpup */
4a4d8108
AM
23131+ err = au_ren_or_cpup(a);
23132+ if (unlikely(err))
23133+ /* leave the copied-up one */
23134+ goto out_whtmp;
1308ab2a 23135+
4a4d8108 23136+ /* make dir opaque */
f2c43d5f
AM
23137+ err = au_ren_diropq(a);
23138+ if (unlikely(err))
23139+ goto out_rename;
1308ab2a 23140+
4a4d8108 23141+ /* update target timestamps */
f2c43d5f
AM
23142+ if (a->exchange) {
23143+ AuDebugOn(au_dbtop(a->dst_dentry) != a->btgt);
23144+ a->h_path.dentry = au_h_dptr(a->dst_dentry, a->btgt);
23145+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
23146+ a->dst_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
23147+ }
5afbbe0d 23148+ AuDebugOn(au_dbtop(a->src_dentry) != a->btgt);
4a4d8108
AM
23149+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
23150+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
5527c038 23151+ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
1facf9fc 23152+
f2c43d5f
AM
23153+ if (!a->exchange) {
23154+ /* remove whiteout for dentry */
23155+ if (a->dst_wh_dentry) {
23156+ a->h_path.dentry = a->dst_wh_dentry;
23157+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
23158+ a->dst_dentry);
23159+ if (unlikely(err))
23160+ goto out_diropq;
23161+ }
1facf9fc 23162+
f2c43d5f
AM
23163+ /* remove whtmp */
23164+ if (a->thargs)
23165+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 23166+
f2c43d5f
AM
23167+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
23168+ }
4a4d8108
AM
23169+ err = 0;
23170+ goto out_success;
23171+
4f0767ce 23172+out_diropq:
f2c43d5f 23173+ au_ren_rev_diropq(err, a);
4f0767ce 23174+out_rename:
7e9cd9fe 23175+ au_ren_rev_rename(err, a);
027c5e7a 23176+ dput(a->h_dst);
4f0767ce 23177+out_whtmp:
4a4d8108
AM
23178+ if (a->thargs)
23179+ au_ren_rev_whtmp(err, a);
4f0767ce 23180+out_whdst:
4a4d8108
AM
23181+ dput(a->dst_wh_dentry);
23182+ a->dst_wh_dentry = NULL;
4f0767ce 23183+out_whsrc:
4a4d8108
AM
23184+ if (a->src_wh_dentry)
23185+ au_ren_rev_whsrc(err, a);
4f0767ce 23186+out_success:
4a4d8108
AM
23187+ dput(a->src_wh_dentry);
23188+ dput(a->dst_wh_dentry);
4f0767ce 23189+out_thargs:
4a4d8108
AM
23190+ if (a->thargs) {
23191+ dput(a->h_dst);
23192+ au_whtmp_rmdir_free(a->thargs);
23193+ a->thargs = NULL;
23194+ }
4f0767ce 23195+out:
4a4d8108 23196+ return err;
dece6358 23197+}
1facf9fc 23198+
1308ab2a 23199+/* ---------------------------------------------------------------------- */
1facf9fc 23200+
4a4d8108
AM
23201+/*
23202+ * test if @dentry dir can be rename destination or not.
23203+ * success means, it is a logically empty dir.
23204+ */
23205+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 23206+{
4a4d8108 23207+ return au_test_empty(dentry, whlist);
1308ab2a 23208+}
1facf9fc 23209+
4a4d8108 23210+/*
8b6a4947
AM
23211+ * test if @a->src_dentry dir can be rename source or not.
23212+ * if it can, return 0.
4a4d8108
AM
23213+ * success means,
23214+ * - it is a logically empty dir.
23215+ * - or, it exists on writable branch and has no children including whiteouts
8b6a4947 23216+ * on the lower branch unless DIRREN is on.
4a4d8108 23217+ */
8b6a4947 23218+static int may_rename_srcdir(struct au_ren_args *a)
4a4d8108
AM
23219+{
23220+ int err;
23221+ unsigned int rdhash;
8b6a4947
AM
23222+ aufs_bindex_t btop, btgt;
23223+ struct dentry *dentry;
23224+ struct super_block *sb;
23225+ struct au_sbinfo *sbinfo;
1facf9fc 23226+
8b6a4947
AM
23227+ dentry = a->src_dentry;
23228+ sb = dentry->d_sb;
23229+ sbinfo = au_sbi(sb);
23230+ if (au_opt_test(sbinfo->si_mntflags, DIRREN))
23231+ au_fset_ren(a->auren_flags, DIRREN);
23232+
23233+ btgt = a->btgt;
5afbbe0d
AM
23234+ btop = au_dbtop(dentry);
23235+ if (btop != btgt) {
4a4d8108 23236+ struct au_nhash whlist;
dece6358 23237+
8b6a4947
AM
23238+ SiMustAnyLock(sb);
23239+ rdhash = sbinfo->si_rdhash;
4a4d8108
AM
23240+ if (!rdhash)
23241+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
23242+ dentry));
23243+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
23244+ if (unlikely(err))
23245+ goto out;
23246+ err = au_test_empty(dentry, &whlist);
23247+ au_nhash_wh_free(&whlist);
23248+ goto out;
23249+ }
dece6358 23250+
5afbbe0d 23251+ if (btop == au_dbtaildir(dentry))
4a4d8108 23252+ return 0; /* success */
dece6358 23253+
4a4d8108 23254+ err = au_test_empty_lower(dentry);
1facf9fc 23255+
4f0767ce 23256+out:
4a4d8108 23257+ if (err == -ENOTEMPTY) {
8b6a4947
AM
23258+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23259+ err = 0;
23260+ } else {
23261+ AuWarn1("renaming dir who has child(ren) on multiple "
23262+ "branches, is not supported\n");
23263+ err = -EXDEV;
23264+ }
4a4d8108
AM
23265+ }
23266+ return err;
23267+}
1308ab2a 23268+
4a4d8108
AM
23269+/* side effect: sets whlist and h_dentry */
23270+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 23271+{
4a4d8108
AM
23272+ int err;
23273+ unsigned int rdhash;
23274+ struct dentry *d;
1facf9fc 23275+
4a4d8108
AM
23276+ d = a->dst_dentry;
23277+ SiMustAnyLock(d->d_sb);
1facf9fc 23278+
4a4d8108 23279+ err = 0;
f2c43d5f 23280+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) && a->dst_inode) {
4a4d8108
AM
23281+ rdhash = au_sbi(d->d_sb)->si_rdhash;
23282+ if (!rdhash)
23283+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
23284+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
23285+ if (unlikely(err))
23286+ goto out;
1308ab2a 23287+
f2c43d5f
AM
23288+ if (!a->exchange) {
23289+ au_set_dbtop(d, a->dst_btop);
23290+ err = may_rename_dstdir(d, &a->whlist);
23291+ au_set_dbtop(d, a->btgt);
23292+ } else
8b6a4947 23293+ err = may_rename_srcdir(a);
4a4d8108 23294+ }
5afbbe0d 23295+ a->dst_h_dentry = au_h_dptr(d, au_dbtop(d));
4a4d8108
AM
23296+ if (unlikely(err))
23297+ goto out;
23298+
23299+ d = a->src_dentry;
5afbbe0d 23300+ a->src_h_dentry = au_h_dptr(d, au_dbtop(d));
f2c43d5f 23301+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) {
8b6a4947 23302+ err = may_rename_srcdir(a);
4a4d8108
AM
23303+ if (unlikely(err)) {
23304+ au_nhash_wh_free(&a->whlist);
23305+ a->whlist.nh_num = 0;
23306+ }
23307+ }
4f0767ce 23308+out:
4a4d8108 23309+ return err;
1facf9fc 23310+}
23311+
4a4d8108 23312+/* ---------------------------------------------------------------------- */
1facf9fc 23313+
4a4d8108
AM
23314+/*
23315+ * simple tests for rename.
23316+ * following the checks in vfs, plus the parent-child relationship.
23317+ */
23318+static int au_may_ren(struct au_ren_args *a)
23319+{
23320+ int err, isdir;
23321+ struct inode *h_inode;
1facf9fc 23322+
5afbbe0d 23323+ if (a->src_btop == a->btgt) {
4a4d8108 23324+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
f2c43d5f 23325+ au_ftest_ren(a->auren_flags, ISDIR_SRC));
4a4d8108
AM
23326+ if (unlikely(err))
23327+ goto out;
23328+ err = -EINVAL;
23329+ if (unlikely(a->src_h_dentry == a->h_trap))
23330+ goto out;
23331+ }
1facf9fc 23332+
4a4d8108 23333+ err = 0;
5afbbe0d 23334+ if (a->dst_btop != a->btgt)
4a4d8108 23335+ goto out;
1facf9fc 23336+
027c5e7a
AM
23337+ err = -ENOTEMPTY;
23338+ if (unlikely(a->dst_h_dentry == a->h_trap))
23339+ goto out;
23340+
4a4d8108 23341+ err = -EIO;
f2c43d5f 23342+ isdir = !!au_ftest_ren(a->auren_flags, ISDIR_DST);
5527c038
JR
23343+ if (d_really_is_negative(a->dst_dentry)) {
23344+ if (d_is_negative(a->dst_h_dentry))
23345+ err = au_may_add(a->dst_dentry, a->btgt,
23346+ a->dst_h_parent, isdir);
4a4d8108 23347+ } else {
5527c038 23348+ if (unlikely(d_is_negative(a->dst_h_dentry)))
4a4d8108 23349+ goto out;
5527c038
JR
23350+ h_inode = d_inode(a->dst_h_dentry);
23351+ if (h_inode->i_nlink)
23352+ err = au_may_del(a->dst_dentry, a->btgt,
23353+ a->dst_h_parent, isdir);
4a4d8108 23354+ }
1facf9fc 23355+
4f0767ce 23356+out:
4a4d8108
AM
23357+ if (unlikely(err == -ENOENT || err == -EEXIST))
23358+ err = -EIO;
23359+ AuTraceErr(err);
23360+ return err;
23361+}
1facf9fc 23362+
1308ab2a 23363+/* ---------------------------------------------------------------------- */
1facf9fc 23364+
4a4d8108
AM
23365+/*
23366+ * locking order
23367+ * (VFS)
23368+ * - src_dir and dir by lock_rename()
acd2b654 23369+ * - inode if exists
4a4d8108
AM
23370+ * (aufs)
23371+ * - lock all
23372+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
23373+ * + si_read_lock
23374+ * + di_write_lock2_child()
23375+ * + di_write_lock_child()
23376+ * + ii_write_lock_child()
23377+ * + di_write_lock_child2()
23378+ * + ii_write_lock_child2()
23379+ * + src_parent and parent
23380+ * + di_write_lock_parent()
23381+ * + ii_write_lock_parent()
23382+ * + di_write_lock_parent2()
23383+ * + ii_write_lock_parent2()
23384+ * + lower src_dir and dir by vfsub_lock_rename()
23385+ * + verify the every relationships between child and parent. if any
23386+ * of them failed, unlock all and return -EBUSY.
23387+ */
23388+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 23389+{
4a4d8108
AM
23390+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
23391+ a->dst_h_parent, a->dst_hdir);
8b6a4947
AM
23392+ if (au_ftest_ren(a->auren_flags, DIRREN)
23393+ && a->h_root)
23394+ au_hn_inode_unlock(a->h_root);
f2c43d5f 23395+ if (au_ftest_ren(a->auren_flags, MNT_WRITE))
86dc4139 23396+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 23397+}
23398+
4a4d8108 23399+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 23400+{
4a4d8108
AM
23401+ int err;
23402+ unsigned int udba;
1308ab2a 23403+
4a4d8108
AM
23404+ err = 0;
23405+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
23406+ a->src_hdir = au_hi(a->src_dir, a->btgt);
23407+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
23408+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
23409+
23410+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
23411+ if (unlikely(err))
23412+ goto out;
f2c43d5f 23413+ au_fset_ren(a->auren_flags, MNT_WRITE);
8b6a4947
AM
23414+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23415+ struct dentry *root;
23416+ struct inode *dir;
23417+
23418+ /*
23419+ * sbinfo is already locked, so this ii_read_lock is
23420+ * unnecessary. but our debugging feature checks it.
23421+ */
23422+ root = a->src_inode->i_sb->s_root;
23423+ if (root != a->src_parent && root != a->dst_parent) {
23424+ dir = d_inode(root);
23425+ ii_read_lock_parent3(dir);
23426+ a->h_root = au_hi(dir, a->btgt);
23427+ ii_read_unlock(dir);
23428+ au_hn_inode_lock_nested(a->h_root, AuLsc_I_PARENT3);
23429+ }
23430+ }
4a4d8108
AM
23431+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
23432+ a->dst_h_parent, a->dst_hdir);
23433+ udba = au_opt_udba(a->src_dentry->d_sb);
5527c038
JR
23434+ if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent)
23435+ || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent)))
4a4d8108 23436+ err = au_busy_or_stale();
5afbbe0d 23437+ if (!err && au_dbtop(a->src_dentry) == a->btgt)
4a4d8108 23438+ err = au_h_verify(a->src_h_dentry, udba,
5527c038 23439+ d_inode(a->src_h_parent), a->src_h_parent,
4a4d8108 23440+ a->br);
5afbbe0d 23441+ if (!err && au_dbtop(a->dst_dentry) == a->btgt)
4a4d8108 23442+ err = au_h_verify(a->dst_h_dentry, udba,
5527c038 23443+ d_inode(a->dst_h_parent), a->dst_h_parent,
4a4d8108 23444+ a->br);
86dc4139 23445+ if (!err)
4a4d8108 23446+ goto out; /* success */
4a4d8108
AM
23447+
23448+ err = au_busy_or_stale();
4a4d8108 23449+ au_ren_unlock(a);
86dc4139 23450+
4f0767ce 23451+out:
4a4d8108 23452+ return err;
1facf9fc 23453+}
23454+
23455+/* ---------------------------------------------------------------------- */
23456+
4a4d8108 23457+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 23458+{
4a4d8108 23459+ struct inode *dir;
dece6358 23460+
4a4d8108 23461+ dir = a->dst_dir;
be118d29 23462+ inode_inc_iversion(dir);
f2c43d5f 23463+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) {
4a4d8108
AM
23464+ /* is this updating defined in POSIX? */
23465+ au_cpup_attr_timesizes(a->src_inode);
23466+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 23467+ }
b912730e 23468+ au_dir_ts(dir, a->btgt);
dece6358 23469+
f2c43d5f
AM
23470+ if (a->exchange) {
23471+ dir = a->src_dir;
be118d29 23472+ inode_inc_iversion(dir);
f2c43d5f
AM
23473+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)) {
23474+ /* is this updating defined in POSIX? */
23475+ au_cpup_attr_timesizes(a->dst_inode);
23476+ au_cpup_attr_nlink(dir, /*force*/1);
23477+ }
23478+ au_dir_ts(dir, a->btgt);
23479+ }
23480+
23481+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108 23482+ return;
dece6358 23483+
4a4d8108 23484+ dir = a->src_dir;
be118d29 23485+ inode_inc_iversion(dir);
f2c43d5f 23486+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC))
4a4d8108 23487+ au_cpup_attr_nlink(dir, /*force*/1);
b912730e 23488+ au_dir_ts(dir, a->btgt);
1facf9fc 23489+}
23490+
4a4d8108 23491+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 23492+{
5afbbe0d 23493+ aufs_bindex_t bbot, bindex;
4a4d8108
AM
23494+ struct dentry *d, *h_d;
23495+ struct inode *i, *h_i;
23496+ struct super_block *sb;
dece6358 23497+
027c5e7a
AM
23498+ d = a->dst_dentry;
23499+ d_drop(d);
23500+ if (a->h_dst)
23501+ /* already dget-ed by au_ren_or_cpup() */
23502+ au_set_h_dptr(d, a->btgt, a->h_dst);
23503+
23504+ i = a->dst_inode;
23505+ if (i) {
f2c43d5f
AM
23506+ if (!a->exchange) {
23507+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST))
23508+ vfsub_drop_nlink(i);
23509+ else {
23510+ vfsub_dead_dir(i);
23511+ au_cpup_attr_timesizes(i);
23512+ }
23513+ au_update_dbrange(d, /*do_put_zero*/1);
23514+ } else
23515+ au_cpup_attr_nlink(i, /*force*/1);
027c5e7a 23516+ } else {
5afbbe0d
AM
23517+ bbot = a->btgt;
23518+ for (bindex = au_dbtop(d); bindex < bbot; bindex++)
027c5e7a 23519+ au_set_h_dptr(d, bindex, NULL);
5afbbe0d
AM
23520+ bbot = au_dbbot(d);
23521+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++)
027c5e7a
AM
23522+ au_set_h_dptr(d, bindex, NULL);
23523+ au_update_dbrange(d, /*do_put_zero*/0);
23524+ }
23525+
8b6a4947
AM
23526+ if (a->exchange
23527+ || au_ftest_ren(a->auren_flags, DIRREN)) {
23528+ d_drop(a->src_dentry);
23529+ if (au_ftest_ren(a->auren_flags, DIRREN))
23530+ au_set_dbwh(a->src_dentry, -1);
23531+ return;
23532+ }
23533+
4a4d8108 23534+ d = a->src_dentry;
8b6a4947
AM
23535+ au_set_dbwh(d, -1);
23536+ bbot = au_dbbot(d);
23537+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) {
23538+ h_d = au_h_dptr(d, bindex);
23539+ if (h_d)
23540+ au_set_h_dptr(d, bindex, NULL);
23541+ }
23542+ au_set_dbbot(d, a->btgt);
4a4d8108 23543+
8b6a4947
AM
23544+ sb = d->d_sb;
23545+ i = a->src_inode;
23546+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
23547+ return; /* success */
4a4d8108 23548+
8b6a4947
AM
23549+ bbot = au_ibbot(i);
23550+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) {
23551+ h_i = au_h_iptr(i, bindex);
23552+ if (h_i) {
23553+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
23554+ /* ignore this error */
23555+ au_set_h_iptr(i, bindex, NULL, 0);
4a4d8108
AM
23556+ }
23557+ }
8b6a4947 23558+ au_set_ibbot(i, a->btgt);
1308ab2a 23559+}
dece6358 23560+
4a4d8108
AM
23561+/* ---------------------------------------------------------------------- */
23562+
23563+/* mainly for link(2) and rename(2) */
23564+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 23565+{
4a4d8108
AM
23566+ aufs_bindex_t bdiropq, bwh;
23567+ struct dentry *parent;
23568+ struct au_branch *br;
23569+
23570+ parent = dentry->d_parent;
5527c038 23571+ IMustLock(d_inode(parent)); /* dir is locked */
4a4d8108
AM
23572+
23573+ bdiropq = au_dbdiropq(parent);
23574+ bwh = au_dbwh(dentry);
23575+ br = au_sbr(dentry->d_sb, btgt);
23576+ if (au_br_rdonly(br)
23577+ || (0 <= bdiropq && bdiropq < btgt)
23578+ || (0 <= bwh && bwh < btgt))
23579+ btgt = -1;
23580+
23581+ AuDbg("btgt %d\n", btgt);
23582+ return btgt;
1facf9fc 23583+}
23584+
5afbbe0d 23585+/* sets src_btop, dst_btop and btgt */
4a4d8108 23586+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 23587+{
4a4d8108
AM
23588+ int err;
23589+ struct au_wr_dir_args wr_dir_args = {
23590+ /* .force_btgt = -1, */
23591+ .flags = AuWrDir_ADD_ENTRY
23592+ };
dece6358 23593+
5afbbe0d
AM
23594+ a->src_btop = au_dbtop(a->src_dentry);
23595+ a->dst_btop = au_dbtop(a->dst_dentry);
f2c43d5f
AM
23596+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)
23597+ || au_ftest_ren(a->auren_flags, ISDIR_DST))
4a4d8108 23598+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
5afbbe0d
AM
23599+ wr_dir_args.force_btgt = a->src_btop;
23600+ if (a->dst_inode && a->dst_btop < a->src_btop)
23601+ wr_dir_args.force_btgt = a->dst_btop;
4a4d8108
AM
23602+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
23603+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
23604+ a->btgt = err;
f2c43d5f
AM
23605+ if (a->exchange)
23606+ au_update_dbtop(a->dst_dentry);
dece6358 23607+
4a4d8108 23608+ return err;
1facf9fc 23609+}
23610+
4a4d8108 23611+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 23612+{
4a4d8108
AM
23613+ a->h_path.dentry = a->src_h_parent;
23614+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
f2c43d5f 23615+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) {
4a4d8108
AM
23616+ a->h_path.dentry = a->dst_h_parent;
23617+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
23618+ }
1facf9fc 23619+
f2c43d5f
AM
23620+ au_fclr_ren(a->auren_flags, DT_DSTDIR);
23621+ if (!au_ftest_ren(a->auren_flags, ISDIR_SRC)
23622+ && !a->exchange)
4a4d8108 23623+ return;
dece6358 23624+
4a4d8108
AM
23625+ a->h_path.dentry = a->src_h_dentry;
23626+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
5527c038 23627+ if (d_is_positive(a->dst_h_dentry)) {
f2c43d5f 23628+ au_fset_ren(a->auren_flags, DT_DSTDIR);
4a4d8108
AM
23629+ a->h_path.dentry = a->dst_h_dentry;
23630+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
23631+ }
1308ab2a 23632+}
dece6358 23633+
4a4d8108 23634+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 23635+{
4a4d8108 23636+ struct dentry *h_d;
febd17d6 23637+ struct inode *h_inode;
4a4d8108
AM
23638+
23639+ au_dtime_revert(a->src_dt + AuPARENT);
f2c43d5f 23640+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108
AM
23641+ au_dtime_revert(a->dst_dt + AuPARENT);
23642+
f2c43d5f 23643+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) && err != -EIO) {
4a4d8108 23644+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
febd17d6
JR
23645+ h_inode = d_inode(h_d);
23646+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 23647+ au_dtime_revert(a->src_dt + AuCHILD);
febd17d6 23648+ inode_unlock(h_inode);
4a4d8108 23649+
f2c43d5f 23650+ if (au_ftest_ren(a->auren_flags, DT_DSTDIR)) {
4a4d8108 23651+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
febd17d6
JR
23652+ h_inode = d_inode(h_d);
23653+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 23654+ au_dtime_revert(a->dst_dt + AuCHILD);
febd17d6 23655+ inode_unlock(h_inode);
1facf9fc 23656+ }
23657+ }
23658+}
23659+
4a4d8108
AM
23660+/* ---------------------------------------------------------------------- */
23661+
23662+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
f2c43d5f
AM
23663+ struct inode *_dst_dir, struct dentry *_dst_dentry,
23664+ unsigned int _flags)
1facf9fc 23665+{
f2c43d5f 23666+ int err, lock_flags;
8b6a4947 23667+ void *rev;
4a4d8108
AM
23668+ /* reduce stack space */
23669+ struct au_ren_args *a;
f2c43d5f 23670+ struct au_pin pin;
4a4d8108 23671+
f2c43d5f 23672+ AuDbg("%pd, %pd, 0x%x\n", _src_dentry, _dst_dentry, _flags);
4a4d8108
AM
23673+ IMustLock(_src_dir);
23674+ IMustLock(_dst_dir);
23675+
f2c43d5f
AM
23676+ err = -EINVAL;
23677+ if (unlikely(_flags & RENAME_WHITEOUT))
23678+ goto out;
23679+
4a4d8108
AM
23680+ err = -ENOMEM;
23681+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
23682+ a = kzalloc(sizeof(*a), GFP_NOFS);
23683+ if (unlikely(!a))
23684+ goto out;
23685+
f2c43d5f 23686+ a->flags = _flags;
acd2b654
AM
23687+ BUILD_BUG_ON(sizeof(a->exchange) == sizeof(u8)
23688+ && RENAME_EXCHANGE > U8_MAX);
f2c43d5f 23689+ a->exchange = _flags & RENAME_EXCHANGE;
4a4d8108
AM
23690+ a->src_dir = _src_dir;
23691+ a->src_dentry = _src_dentry;
5527c038
JR
23692+ a->src_inode = NULL;
23693+ if (d_really_is_positive(a->src_dentry))
23694+ a->src_inode = d_inode(a->src_dentry);
4a4d8108
AM
23695+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
23696+ a->dst_dir = _dst_dir;
23697+ a->dst_dentry = _dst_dentry;
5527c038
JR
23698+ a->dst_inode = NULL;
23699+ if (d_really_is_positive(a->dst_dentry))
23700+ a->dst_inode = d_inode(a->dst_dentry);
4a4d8108
AM
23701+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
23702+ if (a->dst_inode) {
f2c43d5f
AM
23703+ /*
23704+ * if EXCHANGE && src is non-dir && dst is dir,
23705+ * dst is not locked.
23706+ */
23707+ /* IMustLock(a->dst_inode); */
4a4d8108 23708+ au_igrab(a->dst_inode);
1facf9fc 23709+ }
1facf9fc 23710+
4a4d8108 23711+ err = -ENOTDIR;
f2c43d5f 23712+ lock_flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
2000de60 23713+ if (d_is_dir(a->src_dentry)) {
f2c43d5f
AM
23714+ au_fset_ren(a->auren_flags, ISDIR_SRC);
23715+ if (unlikely(!a->exchange
23716+ && d_really_is_positive(a->dst_dentry)
2000de60 23717+ && !d_is_dir(a->dst_dentry)))
4a4d8108 23718+ goto out_free;
f2c43d5f
AM
23719+ lock_flags |= AuLock_DIRS;
23720+ }
23721+ if (a->dst_inode && d_is_dir(a->dst_dentry)) {
23722+ au_fset_ren(a->auren_flags, ISDIR_DST);
23723+ if (unlikely(!a->exchange
23724+ && d_really_is_positive(a->src_dentry)
23725+ && !d_is_dir(a->src_dentry)))
23726+ goto out_free;
23727+ lock_flags |= AuLock_DIRS;
b95c5147 23728+ }
8b6a4947
AM
23729+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
23730+ lock_flags);
e49829fe
JR
23731+ if (unlikely(err))
23732+ goto out_free;
1facf9fc 23733+
027c5e7a
AM
23734+ err = au_d_hashed_positive(a->src_dentry);
23735+ if (unlikely(err))
23736+ goto out_unlock;
23737+ err = -ENOENT;
23738+ if (a->dst_inode) {
23739+ /*
f2c43d5f 23740+ * If it is a dir, VFS unhash it before this
027c5e7a
AM
23741+ * function. It means we cannot rely upon d_unhashed().
23742+ */
23743+ if (unlikely(!a->dst_inode->i_nlink))
23744+ goto out_unlock;
f2c43d5f 23745+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) {
027c5e7a 23746+ err = au_d_hashed_positive(a->dst_dentry);
f2c43d5f 23747+ if (unlikely(err && !a->exchange))
027c5e7a
AM
23748+ goto out_unlock;
23749+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
23750+ goto out_unlock;
23751+ } else if (unlikely(d_unhashed(a->dst_dentry)))
23752+ goto out_unlock;
23753+
7eafdf33
AM
23754+ /*
23755+ * is it possible?
79b8bda9 23756+ * yes, it happened (in linux-3.3-rcN) but I don't know why.
7eafdf33
AM
23757+ * there may exist a problem somewhere else.
23758+ */
23759+ err = -EINVAL;
5527c038 23760+ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry)))
7eafdf33
AM
23761+ goto out_unlock;
23762+
f2c43d5f 23763+ au_fset_ren(a->auren_flags, ISSAMEDIR); /* temporary */
4a4d8108 23764+ di_write_lock_parent(a->dst_parent);
1facf9fc 23765+
4a4d8108
AM
23766+ /* which branch we process */
23767+ err = au_ren_wbr(a);
23768+ if (unlikely(err < 0))
027c5e7a 23769+ goto out_parent;
4a4d8108 23770+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 23771+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 23772+
4a4d8108
AM
23773+ /* are they available to be renamed */
23774+ err = au_ren_may_dir(a);
23775+ if (unlikely(err))
23776+ goto out_children;
1facf9fc 23777+
4a4d8108 23778+ /* prepare the writable parent dir on the same branch */
5afbbe0d 23779+ if (a->dst_btop == a->btgt) {
f2c43d5f 23780+ au_fset_ren(a->auren_flags, WHDST);
4a4d8108
AM
23781+ } else {
23782+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
23783+ if (unlikely(err))
23784+ goto out_children;
23785+ }
1facf9fc 23786+
f2c43d5f
AM
23787+ err = 0;
23788+ if (!a->exchange) {
23789+ if (a->src_dir != a->dst_dir) {
23790+ /*
23791+ * this temporary unlock is safe,
23792+ * because both dir->i_mutex are locked.
23793+ */
23794+ di_write_unlock(a->dst_parent);
23795+ di_write_lock_parent(a->src_parent);
23796+ err = au_wr_dir_need_wh(a->src_dentry,
23797+ au_ftest_ren(a->auren_flags,
23798+ ISDIR_SRC),
23799+ &a->btgt);
23800+ di_write_unlock(a->src_parent);
23801+ di_write_lock2_parent(a->src_parent, a->dst_parent,
23802+ /*isdir*/1);
23803+ au_fclr_ren(a->auren_flags, ISSAMEDIR);
23804+ } else
23805+ err = au_wr_dir_need_wh(a->src_dentry,
23806+ au_ftest_ren(a->auren_flags,
23807+ ISDIR_SRC),
23808+ &a->btgt);
23809+ }
4a4d8108
AM
23810+ if (unlikely(err < 0))
23811+ goto out_children;
23812+ if (err)
f2c43d5f 23813+ au_fset_ren(a->auren_flags, WHSRC);
1facf9fc 23814+
86dc4139 23815+ /* cpup src */
5afbbe0d 23816+ if (a->src_btop != a->btgt) {
86dc4139
AM
23817+ err = au_pin(&pin, a->src_dentry, a->btgt,
23818+ au_opt_udba(a->src_dentry->d_sb),
23819+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 23820+ if (!err) {
c2b27bf2
AM
23821+ struct au_cp_generic cpg = {
23822+ .dentry = a->src_dentry,
23823+ .bdst = a->btgt,
5afbbe0d 23824+ .bsrc = a->src_btop,
c2b27bf2
AM
23825+ .len = -1,
23826+ .pin = &pin,
23827+ .flags = AuCpup_DTIME | AuCpup_HOPEN
23828+ };
5afbbe0d 23829+ AuDebugOn(au_dbtop(a->src_dentry) != a->src_btop);
c2b27bf2 23830+ err = au_sio_cpup_simple(&cpg);
367653fa 23831+ au_unpin(&pin);
86dc4139 23832+ }
86dc4139
AM
23833+ if (unlikely(err))
23834+ goto out_children;
5afbbe0d 23835+ a->src_btop = a->btgt;
86dc4139 23836+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
f2c43d5f
AM
23837+ if (!a->exchange)
23838+ au_fset_ren(a->auren_flags, WHSRC);
23839+ }
23840+
23841+ /* cpup dst */
23842+ if (a->exchange && a->dst_inode
23843+ && a->dst_btop != a->btgt) {
23844+ err = au_pin(&pin, a->dst_dentry, a->btgt,
23845+ au_opt_udba(a->dst_dentry->d_sb),
23846+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
23847+ if (!err) {
23848+ struct au_cp_generic cpg = {
23849+ .dentry = a->dst_dentry,
23850+ .bdst = a->btgt,
23851+ .bsrc = a->dst_btop,
23852+ .len = -1,
23853+ .pin = &pin,
23854+ .flags = AuCpup_DTIME | AuCpup_HOPEN
23855+ };
23856+ err = au_sio_cpup_simple(&cpg);
23857+ au_unpin(&pin);
23858+ }
23859+ if (unlikely(err))
23860+ goto out_children;
23861+ a->dst_btop = a->btgt;
23862+ a->dst_h_dentry = au_h_dptr(a->dst_dentry, a->btgt);
86dc4139
AM
23863+ }
23864+
4a4d8108
AM
23865+ /* lock them all */
23866+ err = au_ren_lock(a);
23867+ if (unlikely(err))
86dc4139 23868+ /* leave the copied-up one */
4a4d8108 23869+ goto out_children;
1facf9fc 23870+
f2c43d5f
AM
23871+ if (!a->exchange) {
23872+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
23873+ err = au_may_ren(a);
23874+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
23875+ err = -ENAMETOOLONG;
23876+ if (unlikely(err))
23877+ goto out_hdir;
23878+ }
1facf9fc 23879+
4a4d8108
AM
23880+ /* store timestamps to be revertible */
23881+ au_ren_dt(a);
1facf9fc 23882+
8b6a4947
AM
23883+ /* store dirren info */
23884+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23885+ err = au_dr_rename(a->src_dentry, a->btgt,
23886+ &a->dst_dentry->d_name, &rev);
23887+ AuTraceErr(err);
23888+ if (unlikely(err))
23889+ goto out_dt;
23890+ }
23891+
4a4d8108
AM
23892+ /* here we go */
23893+ err = do_rename(a);
23894+ if (unlikely(err))
8b6a4947
AM
23895+ goto out_dirren;
23896+
23897+ if (au_ftest_ren(a->auren_flags, DIRREN))
23898+ au_dr_rename_fin(a->src_dentry, a->btgt, rev);
4a4d8108
AM
23899+
23900+ /* update dir attributes */
23901+ au_ren_refresh_dir(a);
23902+
23903+ /* dput/iput all lower dentries */
23904+ au_ren_refresh(a);
23905+
23906+ goto out_hdir; /* success */
23907+
8b6a4947
AM
23908+out_dirren:
23909+ if (au_ftest_ren(a->auren_flags, DIRREN))
23910+ au_dr_rename_rev(a->src_dentry, a->btgt, rev);
4f0767ce 23911+out_dt:
4a4d8108 23912+ au_ren_rev_dt(err, a);
4f0767ce 23913+out_hdir:
4a4d8108 23914+ au_ren_unlock(a);
4f0767ce 23915+out_children:
4a4d8108 23916+ au_nhash_wh_free(&a->whlist);
5afbbe0d
AM
23917+ if (err && a->dst_inode && a->dst_btop != a->btgt) {
23918+ AuDbg("btop %d, btgt %d\n", a->dst_btop, a->btgt);
027c5e7a 23919+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
5afbbe0d 23920+ au_set_dbtop(a->dst_dentry, a->dst_btop);
4a4d8108 23921+ }
027c5e7a 23922+out_parent:
f2c43d5f 23923+ if (!err) {
8b6a4947
AM
23924+ if (d_unhashed(a->src_dentry))
23925+ au_fset_ren(a->auren_flags, DROPPED_SRC);
23926+ if (d_unhashed(a->dst_dentry))
23927+ au_fset_ren(a->auren_flags, DROPPED_DST);
f2c43d5f
AM
23928+ if (!a->exchange)
23929+ d_move(a->src_dentry, a->dst_dentry);
8b6a4947 23930+ else {
f2c43d5f 23931+ d_exchange(a->src_dentry, a->dst_dentry);
8b6a4947
AM
23932+ if (au_ftest_ren(a->auren_flags, DROPPED_DST))
23933+ d_drop(a->dst_dentry);
23934+ }
23935+ if (au_ftest_ren(a->auren_flags, DROPPED_SRC))
23936+ d_drop(a->src_dentry);
f2c43d5f 23937+ } else {
5afbbe0d 23938+ au_update_dbtop(a->dst_dentry);
027c5e7a
AM
23939+ if (!a->dst_inode)
23940+ d_drop(a->dst_dentry);
23941+ }
f2c43d5f 23942+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108
AM
23943+ di_write_unlock(a->dst_parent);
23944+ else
23945+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 23946+out_unlock:
4a4d8108 23947+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 23948+out_free:
4a4d8108
AM
23949+ iput(a->dst_inode);
23950+ if (a->thargs)
23951+ au_whtmp_rmdir_free(a->thargs);
9f237c51 23952+ au_kfree_rcu(a);
4f0767ce 23953+out:
4a4d8108
AM
23954+ AuTraceErr(err);
23955+ return err;
1308ab2a 23956+}
7f207e10
AM
23957diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
23958--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
b00004a5 23959+++ linux/fs/aufs/Kconfig 2018-06-04 09:08:09.181412645 +0200
2121bcd9
AM
23960@@ -0,0 +1,199 @@
23961+# SPDX-License-Identifier: GPL-2.0
4a4d8108
AM
23962+config AUFS_FS
23963+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
23964+ help
23965+ Aufs is a stackable unification filesystem such as Unionfs,
23966+ which unifies several directories and provides a merged single
23967+ directory.
23968+ In the early days, aufs was entirely re-designed and
23969+ re-implemented Unionfs Version 1.x series. Introducing many
23970+ original ideas, approaches and improvements, it becomes totally
23971+ different from Unionfs while keeping the basic features.
1facf9fc 23972+
4a4d8108
AM
23973+if AUFS_FS
23974+choice
23975+ prompt "Maximum number of branches"
23976+ default AUFS_BRANCH_MAX_127
23977+ help
23978+ Specifies the maximum number of branches (or member directories)
23979+ in a single aufs. The larger value consumes more system
23980+ resources and has a minor impact to performance.
23981+config AUFS_BRANCH_MAX_127
23982+ bool "127"
23983+ help
23984+ Specifies the maximum number of branches (or member directories)
23985+ in a single aufs. The larger value consumes more system
23986+ resources and has a minor impact to performance.
23987+config AUFS_BRANCH_MAX_511
23988+ bool "511"
23989+ help
23990+ Specifies the maximum number of branches (or member directories)
23991+ in a single aufs. The larger value consumes more system
23992+ resources and has a minor impact to performance.
23993+config AUFS_BRANCH_MAX_1023
23994+ bool "1023"
23995+ help
23996+ Specifies the maximum number of branches (or member directories)
23997+ in a single aufs. The larger value consumes more system
23998+ resources and has a minor impact to performance.
23999+config AUFS_BRANCH_MAX_32767
24000+ bool "32767"
24001+ help
24002+ Specifies the maximum number of branches (or member directories)
24003+ in a single aufs. The larger value consumes more system
24004+ resources and has a minor impact to performance.
24005+endchoice
1facf9fc 24006+
e49829fe
JR
24007+config AUFS_SBILIST
24008+ bool
24009+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
24010+ default y
24011+ help
24012+ Automatic configuration for internal use.
24013+ When aufs supports Magic SysRq or /proc, enabled automatically.
24014+
4a4d8108
AM
24015+config AUFS_HNOTIFY
24016+ bool "Detect direct branch access (bypassing aufs)"
24017+ help
24018+ If you want to modify files on branches directly, eg. bypassing aufs,
24019+ and want aufs to detect the changes of them fully, then enable this
24020+ option and use 'udba=notify' mount option.
7f207e10 24021+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
24022+ It will have a negative impact to the performance.
24023+ See detail in aufs.5.
dece6358 24024+
4a4d8108
AM
24025+choice
24026+ prompt "method" if AUFS_HNOTIFY
24027+ default AUFS_HFSNOTIFY
24028+config AUFS_HFSNOTIFY
24029+ bool "fsnotify"
24030+ select FSNOTIFY
4a4d8108 24031+endchoice
1facf9fc 24032+
4a4d8108
AM
24033+config AUFS_EXPORT
24034+ bool "NFS-exportable aufs"
2cbb1c4b 24035+ depends on EXPORTFS
4a4d8108
AM
24036+ help
24037+ If you want to export your mounted aufs via NFS, then enable this
24038+ option. There are several requirements for this configuration.
24039+ See detail in aufs.5.
1facf9fc 24040+
4a4d8108
AM
24041+config AUFS_INO_T_64
24042+ bool
24043+ depends on AUFS_EXPORT
24044+ depends on 64BIT && !(ALPHA || S390)
24045+ default y
24046+ help
24047+ Automatic configuration for internal use.
24048+ /* typedef unsigned long/int __kernel_ino_t */
24049+ /* alpha and s390x are int */
1facf9fc 24050+
c1595e42
JR
24051+config AUFS_XATTR
24052+ bool "support for XATTR/EA (including Security Labels)"
24053+ help
24054+ If your branch fs supports XATTR/EA and you want to make them
24055+ available in aufs too, then enable this opsion and specify the
24056+ branch attributes for EA.
24057+ See detail in aufs.5.
24058+
076b876e
AM
24059+config AUFS_FHSM
24060+ bool "File-based Hierarchical Storage Management"
24061+ help
24062+ Hierarchical Storage Management (or HSM) is a well-known feature
24063+ in the storage world. Aufs provides this feature as file-based.
24064+ with multiple branches.
24065+ These multiple branches are prioritized, ie. the topmost one
24066+ should be the fastest drive and be used heavily.
24067+
4a4d8108
AM
24068+config AUFS_RDU
24069+ bool "Readdir in userspace"
24070+ help
24071+ Aufs has two methods to provide a merged view for a directory,
24072+ by a user-space library and by kernel-space natively. The latter
24073+ is always enabled but sometimes large and slow.
24074+ If you enable this option, install the library in aufs2-util
24075+ package, and set some environment variables for your readdir(3),
24076+ then the work will be handled in user-space which generally
24077+ shows better performance in most cases.
24078+ See detail in aufs.5.
1facf9fc 24079+
8b6a4947
AM
24080+config AUFS_DIRREN
24081+ bool "Workaround for rename(2)-ing a directory"
24082+ help
24083+ By default, aufs returns EXDEV error in renameing a dir who has
24084+ his child on the lower branch, since it is a bad idea to issue
24085+ rename(2) internally for every lower branch. But user may not
24086+ accept this behaviour. So here is a workaround to allow such
24087+ rename(2) and store some extra infromation on the writable
24088+ branch. Obviously this costs high (and I don't like it).
24089+ To use this feature, you need to enable this configuration AND
24090+ to specify the mount option `dirren.'
24091+ See details in aufs.5 and the design documents.
24092+
4a4d8108
AM
24093+config AUFS_SHWH
24094+ bool "Show whiteouts"
24095+ help
24096+ If you want to make the whiteouts in aufs visible, then enable
24097+ this option and specify 'shwh' mount option. Although it may
24098+ sounds like philosophy or something, but in technically it
24099+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 24100+
4a4d8108
AM
24101+config AUFS_BR_RAMFS
24102+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
24103+ help
24104+ If you want to use ramfs as an aufs branch fs, then enable this
24105+ option. Generally tmpfs is recommended.
24106+ Aufs prohibited them to be a branch fs by default, because
24107+ initramfs becomes unusable after switch_root or something
24108+ generally. If you sets initramfs as an aufs branch and boot your
24109+ system by switch_root, you will meet a problem easily since the
24110+ files in initramfs may be inaccessible.
24111+ Unless you are going to use ramfs as an aufs branch fs without
24112+ switch_root or something, leave it N.
1facf9fc 24113+
4a4d8108
AM
24114+config AUFS_BR_FUSE
24115+ bool "Fuse fs as an aufs branch"
24116+ depends on FUSE_FS
24117+ select AUFS_POLL
24118+ help
24119+ If you want to use fuse-based userspace filesystem as an aufs
24120+ branch fs, then enable this option.
24121+ It implements the internal poll(2) operation which is
24122+ implemented by fuse only (curretnly).
1facf9fc 24123+
4a4d8108
AM
24124+config AUFS_POLL
24125+ bool
24126+ help
24127+ Automatic configuration for internal use.
1facf9fc 24128+
4a4d8108
AM
24129+config AUFS_BR_HFSPLUS
24130+ bool "Hfsplus as an aufs branch"
24131+ depends on HFSPLUS_FS
24132+ default y
24133+ help
24134+ If you want to use hfsplus fs as an aufs branch fs, then enable
24135+ this option. This option introduces a small overhead at
24136+ copying-up a file on hfsplus.
1facf9fc 24137+
4a4d8108
AM
24138+config AUFS_BDEV_LOOP
24139+ bool
24140+ depends on BLK_DEV_LOOP
24141+ default y
24142+ help
24143+ Automatic configuration for internal use.
24144+ Convert =[ym] into =y.
1308ab2a 24145+
4a4d8108
AM
24146+config AUFS_DEBUG
24147+ bool "Debug aufs"
24148+ help
24149+ Enable this to compile aufs internal debug code.
24150+ It will have a negative impact to the performance.
24151+
24152+config AUFS_MAGIC_SYSRQ
24153+ bool
24154+ depends on AUFS_DEBUG && MAGIC_SYSRQ
24155+ default y
24156+ help
24157+ Automatic configuration for internal use.
24158+ When aufs supports Magic SysRq, enabled automatically.
24159+endif
acd2b654
AM
24160diff -urN /usr/share/empty/fs/aufs/lcnt.h linux/fs/aufs/lcnt.h
24161--- /usr/share/empty/fs/aufs/lcnt.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 24162+++ linux/fs/aufs/lcnt.h 2019-03-05 12:13:00.142557771 +0100
acd2b654
AM
24163@@ -0,0 +1,186 @@
24164+/* SPDX-License-Identifier: GPL-2.0 */
24165+/*
ba1aed25 24166+ * Copyright (C) 2018-2019 Junjiro R. Okajima
acd2b654
AM
24167+ *
24168+ * This program, aufs is free software; you can redistribute it and/or modify
24169+ * it under the terms of the GNU General Public License as published by
24170+ * the Free Software Foundation; either version 2 of the License, or
24171+ * (at your option) any later version.
24172+ *
24173+ * This program is distributed in the hope that it will be useful,
24174+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24175+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24176+ * GNU General Public License for more details.
24177+ *
24178+ * You should have received a copy of the GNU General Public License
24179+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24180+ */
24181+
24182+/*
24183+ * simple long counter wrapper
24184+ */
24185+
24186+#ifndef __AUFS_LCNT_H__
24187+#define __AUFS_LCNT_H__
24188+
24189+#ifdef __KERNEL__
24190+
24191+#include "debug.h"
24192+
24193+#define AuLCntATOMIC 1
24194+#define AuLCntPCPUCNT 2
24195+/*
24196+ * why does percpu_refcount require extra synchronize_rcu()s in
24197+ * au_br_do_free()
24198+ */
24199+#define AuLCntPCPUREF 3
24200+
24201+/* #define AuLCntChosen AuLCntATOMIC */
24202+#define AuLCntChosen AuLCntPCPUCNT
24203+/* #define AuLCntChosen AuLCntPCPUREF */
24204+
24205+#if AuLCntChosen == AuLCntATOMIC
24206+#include <linux/atomic.h>
24207+
24208+typedef atomic_long_t au_lcnt_t;
24209+
24210+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused)
24211+{
24212+ atomic_long_set(cnt, 0);
24213+ return 0;
24214+}
24215+
24216+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused)
24217+{
24218+ /* empty */
24219+}
24220+
24221+static inline void au_lcnt_fin(au_lcnt_t *cnt __maybe_unused,
24222+ int do_sync __maybe_unused)
24223+{
24224+ /* empty */
24225+}
24226+
24227+static inline void au_lcnt_inc(au_lcnt_t *cnt)
24228+{
24229+ atomic_long_inc(cnt);
24230+}
24231+
24232+static inline void au_lcnt_dec(au_lcnt_t *cnt)
24233+{
24234+ atomic_long_dec(cnt);
24235+}
24236+
24237+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused)
24238+{
24239+ return atomic_long_read(cnt);
24240+}
24241+#endif
24242+
24243+#if AuLCntChosen == AuLCntPCPUCNT
24244+#include <linux/percpu_counter.h>
24245+
24246+typedef struct percpu_counter au_lcnt_t;
24247+
24248+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused)
24249+{
24250+ return percpu_counter_init(cnt, 0, GFP_NOFS);
24251+}
24252+
24253+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused)
24254+{
24255+ /* empty */
24256+}
24257+
24258+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync __maybe_unused)
24259+{
24260+ percpu_counter_destroy(cnt);
24261+}
24262+
24263+static inline void au_lcnt_inc(au_lcnt_t *cnt)
24264+{
24265+ percpu_counter_inc(cnt);
24266+}
24267+
24268+static inline void au_lcnt_dec(au_lcnt_t *cnt)
24269+{
24270+ percpu_counter_dec(cnt);
24271+}
24272+
24273+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused)
24274+{
24275+ s64 n;
24276+
24277+ n = percpu_counter_sum(cnt);
24278+ BUG_ON(n < 0);
24279+ if (LONG_MAX != LLONG_MAX
24280+ && n > LONG_MAX)
24281+ AuWarn1("%s\n", "wrap-around");
24282+
24283+ return n;
24284+}
24285+#endif
24286+
24287+#if AuLCntChosen == AuLCntPCPUREF
24288+#include <linux/percpu-refcount.h>
24289+
24290+typedef struct percpu_ref au_lcnt_t;
24291+
24292+static inline int au_lcnt_init(au_lcnt_t *cnt, percpu_ref_func_t *release)
24293+{
24294+ if (!release)
24295+ release = percpu_ref_exit;
24296+ return percpu_ref_init(cnt, release, /*percpu mode*/0, GFP_NOFS);
24297+}
24298+
24299+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused)
24300+{
24301+ synchronize_rcu();
24302+}
24303+
24304+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync)
24305+{
24306+ percpu_ref_kill(cnt);
24307+ if (do_sync)
24308+ au_lcnt_wait_for_fin(cnt);
24309+}
24310+
24311+static inline void au_lcnt_inc(au_lcnt_t *cnt)
24312+{
24313+ percpu_ref_get(cnt);
24314+}
24315+
24316+static inline void au_lcnt_dec(au_lcnt_t *cnt)
24317+{
24318+ percpu_ref_put(cnt);
24319+}
24320+
24321+/*
24322+ * avoid calling this func as possible.
24323+ */
24324+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev)
24325+{
24326+ long l;
24327+
24328+ percpu_ref_switch_to_atomic_sync(cnt);
24329+ l = atomic_long_read(&cnt->count);
24330+ if (do_rev)
24331+ percpu_ref_switch_to_percpu(cnt);
24332+
24333+ /* percpu_ref is initialized by 1 instead of 0 */
24334+ return l - 1;
24335+}
24336+#endif
24337+
24338+#ifdef CONFIG_AUFS_DEBUG
24339+#define AuLCntZero(val) do { \
24340+ long l = val; \
24341+ if (l) \
24342+ AuDbg("%s = %ld\n", #val, l); \
24343+} while (0)
24344+#else
24345+#define AuLCntZero(val) do {} while (0)
24346+#endif
24347+
24348+#endif /* __KERNEL__ */
24349+#endif /* __AUFS_LCNT_H__ */
7f207e10
AM
24350diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
24351--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 24352+++ linux/fs/aufs/loop.c 2019-03-05 12:13:00.142557771 +0100
062440b3 24353@@ -0,0 +1,148 @@
cd7a4cd9 24354+// SPDX-License-Identifier: GPL-2.0
1facf9fc 24355+/*
ba1aed25 24356+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 24357+ *
24358+ * This program, aufs is free software; you can redistribute it and/or modify
24359+ * it under the terms of the GNU General Public License as published by
24360+ * the Free Software Foundation; either version 2 of the License, or
24361+ * (at your option) any later version.
dece6358
AM
24362+ *
24363+ * This program is distributed in the hope that it will be useful,
24364+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24365+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24366+ * GNU General Public License for more details.
24367+ *
24368+ * You should have received a copy of the GNU General Public License
523b37e3 24369+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24370+ */
24371+
24372+/*
24373+ * support for loopback block device as a branch
24374+ */
24375+
1facf9fc 24376+#include "aufs.h"
24377+
392086de
AM
24378+/* added into drivers/block/loop.c */
24379+static struct file *(*backing_file_func)(struct super_block *sb);
24380+
1facf9fc 24381+/*
24382+ * test if two lower dentries have overlapping branches.
24383+ */
b752ccd1 24384+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 24385+{
b752ccd1 24386+ struct super_block *h_sb;
392086de
AM
24387+ struct file *backing_file;
24388+
24389+ if (unlikely(!backing_file_func)) {
24390+ /* don't load "loop" module here */
24391+ backing_file_func = symbol_get(loop_backing_file);
24392+ if (unlikely(!backing_file_func))
24393+ /* "loop" module is not loaded */
24394+ return 0;
24395+ }
1facf9fc 24396+
b752ccd1 24397+ h_sb = h_adding->d_sb;
392086de
AM
24398+ backing_file = backing_file_func(h_sb);
24399+ if (!backing_file)
1facf9fc 24400+ return 0;
24401+
2000de60 24402+ h_adding = backing_file->f_path.dentry;
b752ccd1
AM
24403+ /*
24404+ * h_adding can be local NFS.
24405+ * in this case aufs cannot detect the loop.
24406+ */
24407+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 24408+ return 1;
b752ccd1 24409+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 24410+}
24411+
24412+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
24413+int au_test_loopback_kthread(void)
24414+{
b752ccd1
AM
24415+ int ret;
24416+ struct task_struct *tsk = current;
a2a7ad62 24417+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
24418+
24419+ ret = 0;
24420+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
24421+ get_task_comm(comm, tsk);
24422+ c = comm[4];
b752ccd1 24423+ ret = ('0' <= c && c <= '9'
a2a7ad62 24424+ && !strncmp(comm, "loop", 4));
b752ccd1 24425+ }
1facf9fc 24426+
b752ccd1 24427+ return ret;
1facf9fc 24428+}
87a755f4
AM
24429+
24430+/* ---------------------------------------------------------------------- */
24431+
24432+#define au_warn_loopback_step 16
24433+static int au_warn_loopback_nelem = au_warn_loopback_step;
24434+static unsigned long *au_warn_loopback_array;
24435+
24436+void au_warn_loopback(struct super_block *h_sb)
24437+{
24438+ int i, new_nelem;
24439+ unsigned long *a, magic;
24440+ static DEFINE_SPINLOCK(spin);
24441+
24442+ magic = h_sb->s_magic;
24443+ spin_lock(&spin);
24444+ a = au_warn_loopback_array;
24445+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
24446+ if (a[i] == magic) {
24447+ spin_unlock(&spin);
24448+ return;
24449+ }
24450+
24451+ /* h_sb is new to us, print it */
24452+ if (i < au_warn_loopback_nelem) {
24453+ a[i] = magic;
24454+ goto pr;
24455+ }
24456+
24457+ /* expand the array */
24458+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
24459+ a = au_kzrealloc(au_warn_loopback_array,
24460+ au_warn_loopback_nelem * sizeof(unsigned long),
e2f27e51
AM
24461+ new_nelem * sizeof(unsigned long), GFP_ATOMIC,
24462+ /*may_shrink*/0);
87a755f4
AM
24463+ if (a) {
24464+ au_warn_loopback_nelem = new_nelem;
24465+ au_warn_loopback_array = a;
24466+ a[i] = magic;
24467+ goto pr;
24468+ }
24469+
24470+ spin_unlock(&spin);
24471+ AuWarn1("realloc failed, ignored\n");
24472+ return;
24473+
24474+pr:
24475+ spin_unlock(&spin);
0c3ec466
AM
24476+ pr_warn("you may want to try another patch for loopback file "
24477+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
24478+}
24479+
24480+int au_loopback_init(void)
24481+{
24482+ int err;
24483+ struct super_block *sb __maybe_unused;
24484+
79b8bda9 24485+ BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(unsigned long));
87a755f4
AM
24486+
24487+ err = 0;
24488+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
24489+ sizeof(unsigned long), GFP_NOFS);
24490+ if (unlikely(!au_warn_loopback_array))
24491+ err = -ENOMEM;
24492+
24493+ return err;
24494+}
24495+
24496+void au_loopback_fin(void)
24497+{
79b8bda9
AM
24498+ if (backing_file_func)
24499+ symbol_put(loop_backing_file);
9f237c51 24500+ au_kfree_try_rcu(au_warn_loopback_array);
87a755f4 24501+}
7f207e10
AM
24502diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
24503--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
24504+++ linux/fs/aufs/loop.h 2019-05-06 09:03:04.820143837 +0200
24505@@ -0,0 +1,55 @@
062440b3 24506+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 24507+/*
ba1aed25 24508+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 24509+ *
24510+ * This program, aufs is free software; you can redistribute it and/or modify
24511+ * it under the terms of the GNU General Public License as published by
24512+ * the Free Software Foundation; either version 2 of the License, or
24513+ * (at your option) any later version.
dece6358
AM
24514+ *
24515+ * This program is distributed in the hope that it will be useful,
24516+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24517+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24518+ * GNU General Public License for more details.
24519+ *
24520+ * You should have received a copy of the GNU General Public License
523b37e3 24521+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24522+ */
24523+
24524+/*
24525+ * support for loopback mount as a branch
24526+ */
24527+
24528+#ifndef __AUFS_LOOP_H__
24529+#define __AUFS_LOOP_H__
24530+
24531+#ifdef __KERNEL__
24532+
dece6358
AM
24533+struct dentry;
24534+struct super_block;
1facf9fc 24535+
24536+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
24537+/* drivers/block/loop.c */
24538+struct file *loop_backing_file(struct super_block *sb);
24539+
1facf9fc 24540+/* loop.c */
b752ccd1 24541+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 24542+int au_test_loopback_kthread(void);
87a755f4
AM
24543+void au_warn_loopback(struct super_block *h_sb);
24544+
24545+int au_loopback_init(void);
24546+void au_loopback_fin(void);
1facf9fc 24547+#else
eca801bf
AM
24548+AuStub(struct file *, loop_backing_file, return NULL)
24549+
4a4d8108 24550+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 24551+ struct dentry *h_adding)
4a4d8108 24552+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
24553+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
24554+
24555+AuStubInt0(au_loopback_init, void)
24556+AuStubVoid(au_loopback_fin, void)
1facf9fc 24557+#endif /* BLK_DEV_LOOP */
24558+
24559+#endif /* __KERNEL__ */
24560+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
24561diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
24562--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
b00004a5 24563+++ linux/fs/aufs/magic.mk 2018-06-04 09:08:09.188079511 +0200
2121bcd9
AM
24564@@ -0,0 +1,31 @@
24565+# SPDX-License-Identifier: GPL-2.0
1facf9fc 24566+
24567+# defined in ${srctree}/fs/fuse/inode.c
24568+# tristate
24569+ifdef CONFIG_FUSE_FS
24570+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
24571+endif
24572+
1facf9fc 24573+# defined in ${srctree}/fs/xfs/xfs_sb.h
24574+# tristate
24575+ifdef CONFIG_XFS_FS
24576+ccflags-y += -DXFS_SB_MAGIC=0x58465342
24577+endif
24578+
24579+# defined in ${srctree}/fs/configfs/mount.c
24580+# tristate
24581+ifdef CONFIG_CONFIGFS_FS
24582+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
24583+endif
24584+
1facf9fc 24585+# defined in ${srctree}/fs/ubifs/ubifs.h
24586+# tristate
24587+ifdef CONFIG_UBIFS_FS
24588+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
24589+endif
4a4d8108
AM
24590+
24591+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
24592+# tristate
24593+ifdef CONFIG_HFSPLUS_FS
24594+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
24595+endif
7f207e10
AM
24596diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
24597--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
b00004a5 24598+++ linux/fs/aufs/Makefile 2018-06-04 09:08:09.181412645 +0200
2121bcd9
AM
24599@@ -0,0 +1,46 @@
24600+# SPDX-License-Identifier: GPL-2.0
4a4d8108
AM
24601+
24602+include ${src}/magic.mk
24603+ifeq (${CONFIG_AUFS_FS},m)
24604+include ${src}/conf.mk
24605+endif
24606+-include ${src}/priv_def.mk
24607+
24608+# cf. include/linux/kernel.h
24609+# enable pr_debug
24610+ccflags-y += -DDEBUG
f6c5ef8b
AM
24611+# sparse requires the full pathname
24612+ifdef M
523b37e3 24613+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 24614+else
523b37e3 24615+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 24616+endif
4a4d8108
AM
24617+
24618+obj-$(CONFIG_AUFS_FS) += aufs.o
24619+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
24620+ wkq.o vfsub.o dcsub.o \
e49829fe 24621+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
24622+ dinfo.o dentry.o \
24623+ dynop.o \
24624+ finfo.o file.o f_op.o \
24625+ dir.o vdir.o \
24626+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 24627+ mvdown.o ioctl.o
4a4d8108
AM
24628+
24629+# all are boolean
e49829fe 24630+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
24631+aufs-$(CONFIG_SYSFS) += sysfs.o
24632+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
24633+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
24634+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
24635+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108 24636+aufs-$(CONFIG_AUFS_EXPORT) += export.o
c1595e42
JR
24637+aufs-$(CONFIG_AUFS_XATTR) += xattr.o
24638+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
8b6a4947 24639+aufs-$(CONFIG_AUFS_DIRREN) += dirren.o
076b876e 24640+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
4a4d8108
AM
24641+aufs-$(CONFIG_AUFS_POLL) += poll.o
24642+aufs-$(CONFIG_AUFS_RDU) += rdu.o
4a4d8108
AM
24643+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
24644+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
24645+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
24646diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
24647--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 24648+++ linux/fs/aufs/module.c 2019-03-05 12:13:00.142557771 +0100
062440b3 24649@@ -0,0 +1,273 @@
cd7a4cd9 24650+// SPDX-License-Identifier: GPL-2.0
1facf9fc 24651+/*
ba1aed25 24652+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 24653+ *
24654+ * This program, aufs is free software; you can redistribute it and/or modify
24655+ * it under the terms of the GNU General Public License as published by
24656+ * the Free Software Foundation; either version 2 of the License, or
24657+ * (at your option) any later version.
dece6358
AM
24658+ *
24659+ * This program is distributed in the hope that it will be useful,
24660+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24661+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24662+ * GNU General Public License for more details.
24663+ *
24664+ * You should have received a copy of the GNU General Public License
523b37e3 24665+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24666+ */
24667+
24668+/*
24669+ * module global variables and operations
24670+ */
24671+
24672+#include <linux/module.h>
24673+#include <linux/seq_file.h>
24674+#include "aufs.h"
24675+
e2f27e51
AM
24676+/* shrinkable realloc */
24677+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink)
1facf9fc 24678+{
e2f27e51
AM
24679+ size_t sz;
24680+ int diff;
1facf9fc 24681+
e2f27e51
AM
24682+ sz = 0;
24683+ diff = -1;
24684+ if (p) {
24685+#if 0 /* unused */
24686+ if (!new_sz) {
9f237c51 24687+ au_kfree_rcu(p);
e2f27e51
AM
24688+ p = NULL;
24689+ goto out;
24690+ }
24691+#else
24692+ AuDebugOn(!new_sz);
24693+#endif
24694+ sz = ksize(p);
24695+ diff = au_kmidx_sub(sz, new_sz);
24696+ }
24697+ if (sz && !diff)
24698+ goto out;
24699+
24700+ if (sz < new_sz)
24701+ /* expand or SLOB */
24702+ p = krealloc(p, new_sz, gfp);
24703+ else if (new_sz < sz && may_shrink) {
24704+ /* shrink */
24705+ void *q;
24706+
24707+ q = kmalloc(new_sz, gfp);
24708+ if (q) {
24709+ if (p) {
24710+ memcpy(q, p, new_sz);
9f237c51 24711+ au_kfree_try_rcu(p);
e2f27e51
AM
24712+ }
24713+ p = q;
24714+ } else
24715+ p = NULL;
24716+ }
24717+
24718+out:
24719+ return p;
24720+}
24721+
24722+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
24723+ int may_shrink)
24724+{
24725+ p = au_krealloc(p, new_sz, gfp, may_shrink);
24726+ if (p && new_sz > nused)
1facf9fc 24727+ memset(p + nused, 0, new_sz - nused);
24728+ return p;
24729+}
24730+
24731+/* ---------------------------------------------------------------------- */
1facf9fc 24732+/*
24733+ * aufs caches
24734+ */
1c60b727 24735+struct kmem_cache *au_cache[AuCache_Last];
5afbbe0d
AM
24736+
24737+static void au_cache_fin(void)
24738+{
24739+ int i;
24740+
24741+ /*
24742+ * Make sure all delayed rcu free inodes are flushed before we
24743+ * destroy cache.
24744+ */
24745+ rcu_barrier();
24746+
24747+ /* excluding AuCache_HNOTIFY */
24748+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
24749+ for (i = 0; i < AuCache_HNOTIFY; i++) {
1c60b727
AM
24750+ kmem_cache_destroy(au_cache[i]);
24751+ au_cache[i] = NULL;
5afbbe0d
AM
24752+ }
24753+}
24754+
1facf9fc 24755+static int __init au_cache_init(void)
24756+{
1c60b727
AM
24757+ au_cache[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
24758+ if (au_cache[AuCache_DINFO])
027c5e7a 24759+ /* SLAB_DESTROY_BY_RCU */
1c60b727 24760+ au_cache[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
f0c0a007 24761+ au_icntnr_init_once);
1c60b727
AM
24762+ if (au_cache[AuCache_ICNTNR])
24763+ au_cache[AuCache_FINFO] = AuCacheCtor(au_finfo,
f0c0a007 24764+ au_fi_init_once);
1c60b727
AM
24765+ if (au_cache[AuCache_FINFO])
24766+ au_cache[AuCache_VDIR] = AuCache(au_vdir);
24767+ if (au_cache[AuCache_VDIR])
24768+ au_cache[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
24769+ if (au_cache[AuCache_DEHSTR])
1facf9fc 24770+ return 0;
24771+
5afbbe0d 24772+ au_cache_fin();
1facf9fc 24773+ return -ENOMEM;
24774+}
24775+
1facf9fc 24776+/* ---------------------------------------------------------------------- */
24777+
24778+int au_dir_roflags;
24779+
e49829fe 24780+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
24781+/*
24782+ * iterate_supers_type() doesn't protect us from
24783+ * remounting (branch management)
24784+ */
8b6a4947 24785+struct hlist_bl_head au_sbilist;
e49829fe
JR
24786+#endif
24787+
1facf9fc 24788+/*
24789+ * functions for module interface.
24790+ */
24791+MODULE_LICENSE("GPL");
24792+/* MODULE_LICENSE("GPL v2"); */
dece6358 24793+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 24794+MODULE_DESCRIPTION(AUFS_NAME
24795+ " -- Advanced multi layered unification filesystem");
24796+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 24797+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 24798+
1facf9fc 24799+/* this module parameter has no meaning when SYSFS is disabled */
24800+int sysaufs_brs = 1;
24801+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
cd7a4cd9 24802+module_param_named(brs, sysaufs_brs, int, 0444);
1facf9fc 24803+
076b876e 24804+/* this module parameter has no meaning when USER_NS is disabled */
8cdd5066 24805+bool au_userns;
076b876e 24806+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
cd7a4cd9 24807+module_param_named(allow_userns, au_userns, bool, 0444);
076b876e 24808+
1facf9fc 24809+/* ---------------------------------------------------------------------- */
24810+
24811+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
24812+
24813+int au_seq_path(struct seq_file *seq, struct path *path)
24814+{
79b8bda9
AM
24815+ int err;
24816+
24817+ err = seq_path(seq, path, au_esc_chars);
1c60b727 24818+ if (err >= 0)
79b8bda9 24819+ err = 0;
1c60b727 24820+ else
79b8bda9
AM
24821+ err = -ENOMEM;
24822+
24823+ return err;
1facf9fc 24824+}
24825+
24826+/* ---------------------------------------------------------------------- */
24827+
24828+static int __init aufs_init(void)
24829+{
24830+ int err, i;
24831+ char *p;
24832+
24833+ p = au_esc_chars;
24834+ for (i = 1; i <= ' '; i++)
24835+ *p++ = i;
24836+ *p++ = '\\';
24837+ *p++ = '\x7f';
24838+ *p = 0;
24839+
24840+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
24841+
b95c5147
AM
24842+ memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop));
24843+ for (i = 0; i < AuIop_Last; i++)
24844+ aufs_iop_nogetattr[i].getattr = NULL;
24845+
1c60b727 24846+ memset(au_cache, 0, sizeof(au_cache)); /* including hnotify */
f0c0a007 24847+
e49829fe 24848+ au_sbilist_init();
1facf9fc 24849+ sysaufs_brs_init();
24850+ au_debug_init();
4a4d8108 24851+ au_dy_init();
1facf9fc 24852+ err = sysaufs_init();
24853+ if (unlikely(err))
24854+ goto out;
062440b3 24855+ err = dbgaufs_init();
4f0767ce 24856+ if (unlikely(err))
953406b4 24857+ goto out_sysaufs;
062440b3
AM
24858+ err = au_procfs_init();
24859+ if (unlikely(err))
24860+ goto out_dbgaufs;
e49829fe
JR
24861+ err = au_wkq_init();
24862+ if (unlikely(err))
24863+ goto out_procfs;
87a755f4 24864+ err = au_loopback_init();
1facf9fc 24865+ if (unlikely(err))
24866+ goto out_wkq;
87a755f4
AM
24867+ err = au_hnotify_init();
24868+ if (unlikely(err))
24869+ goto out_loopback;
1facf9fc 24870+ err = au_sysrq_init();
24871+ if (unlikely(err))
24872+ goto out_hin;
24873+ err = au_cache_init();
24874+ if (unlikely(err))
24875+ goto out_sysrq;
076b876e
AM
24876+
24877+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
1facf9fc 24878+ err = register_filesystem(&aufs_fs_type);
24879+ if (unlikely(err))
24880+ goto out_cache;
076b876e 24881+
4a4d8108
AM
24882+ /* since we define pr_fmt, call printk directly */
24883+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 24884+ goto out; /* success */
24885+
4f0767ce 24886+out_cache:
1facf9fc 24887+ au_cache_fin();
4f0767ce 24888+out_sysrq:
1facf9fc 24889+ au_sysrq_fin();
4f0767ce 24890+out_hin:
4a4d8108 24891+ au_hnotify_fin();
87a755f4
AM
24892+out_loopback:
24893+ au_loopback_fin();
4f0767ce 24894+out_wkq:
1facf9fc 24895+ au_wkq_fin();
e49829fe
JR
24896+out_procfs:
24897+ au_procfs_fin();
062440b3
AM
24898+out_dbgaufs:
24899+ dbgaufs_fin();
4f0767ce 24900+out_sysaufs:
1facf9fc 24901+ sysaufs_fin();
4a4d8108 24902+ au_dy_fin();
4f0767ce 24903+out:
1facf9fc 24904+ return err;
24905+}
24906+
24907+static void __exit aufs_exit(void)
24908+{
24909+ unregister_filesystem(&aufs_fs_type);
24910+ au_cache_fin();
24911+ au_sysrq_fin();
4a4d8108 24912+ au_hnotify_fin();
87a755f4 24913+ au_loopback_fin();
1facf9fc 24914+ au_wkq_fin();
e49829fe 24915+ au_procfs_fin();
062440b3 24916+ dbgaufs_fin();
1facf9fc 24917+ sysaufs_fin();
4a4d8108 24918+ au_dy_fin();
1facf9fc 24919+}
24920+
24921+module_init(aufs_init);
24922+module_exit(aufs_exit);
7f207e10
AM
24923diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
24924--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 24925+++ linux/fs/aufs/module.h 2019-03-05 12:13:00.142557771 +0100
9f237c51 24926@@ -0,0 +1,166 @@
062440b3 24927+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 24928+/*
ba1aed25 24929+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 24930+ *
24931+ * This program, aufs is free software; you can redistribute it and/or modify
24932+ * it under the terms of the GNU General Public License as published by
24933+ * the Free Software Foundation; either version 2 of the License, or
24934+ * (at your option) any later version.
dece6358
AM
24935+ *
24936+ * This program is distributed in the hope that it will be useful,
24937+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24938+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24939+ * GNU General Public License for more details.
24940+ *
24941+ * You should have received a copy of the GNU General Public License
523b37e3 24942+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24943+ */
24944+
24945+/*
24946+ * module initialization and module-global
24947+ */
24948+
24949+#ifndef __AUFS_MODULE_H__
24950+#define __AUFS_MODULE_H__
24951+
24952+#ifdef __KERNEL__
24953+
24954+#include <linux/slab.h>
9f237c51
AM
24955+#include "debug.h"
24956+#include "dentry.h"
24957+#include "dir.h"
24958+#include "file.h"
24959+#include "inode.h"
1facf9fc 24960+
dece6358
AM
24961+struct path;
24962+struct seq_file;
24963+
1facf9fc 24964+/* module parameters */
1facf9fc 24965+extern int sysaufs_brs;
8cdd5066 24966+extern bool au_userns;
1facf9fc 24967+
24968+/* ---------------------------------------------------------------------- */
24969+
24970+extern int au_dir_roflags;
24971+
e2f27e51
AM
24972+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink);
24973+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
24974+ int may_shrink);
24975+
9f237c51
AM
24976+/*
24977+ * Comparing the size of the object with sizeof(struct rcu_head)
24978+ * case 1: object is always larger
24979+ * --> au_kfree_rcu() or au_kfree_do_rcu()
24980+ * case 2: object is always smaller
24981+ * --> au_kfree_small()
24982+ * case 3: object can be any size
24983+ * --> au_kfree_try_rcu()
24984+ */
24985+
24986+static inline void au_kfree_do_rcu(const void *p)
24987+{
24988+ struct {
24989+ struct rcu_head rcu;
24990+ } *a = (void *)p;
24991+
24992+ kfree_rcu(a, rcu);
24993+}
24994+
24995+#define au_kfree_rcu(_p) do { \
24996+ typeof(_p) p = (_p); \
24997+ BUILD_BUG_ON(sizeof(*p) < sizeof(struct rcu_head)); \
24998+ if (p) \
24999+ au_kfree_do_rcu(p); \
25000+ } while (0)
25001+
25002+#define au_kfree_do_sz_test(sz) (sz >= sizeof(struct rcu_head))
25003+#define au_kfree_sz_test(p) (p && au_kfree_do_sz_test(ksize(p)))
25004+
25005+static inline void au_kfree_try_rcu(const void *p)
25006+{
25007+ if (!p)
25008+ return;
25009+ if (au_kfree_sz_test(p))
25010+ au_kfree_do_rcu(p);
25011+ else
25012+ kfree(p);
25013+}
25014+
25015+static inline void au_kfree_small(const void *p)
25016+{
25017+ if (!p)
25018+ return;
25019+ AuDebugOn(au_kfree_sz_test(p));
25020+ kfree(p);
25021+}
25022+
e2f27e51
AM
25023+static inline int au_kmidx_sub(size_t sz, size_t new_sz)
25024+{
25025+#ifndef CONFIG_SLOB
25026+ return kmalloc_index(sz) - kmalloc_index(new_sz);
25027+#else
25028+ return -1; /* SLOB is untested */
25029+#endif
25030+}
25031+
1facf9fc 25032+int au_seq_path(struct seq_file *seq, struct path *path);
25033+
e49829fe
JR
25034+#ifdef CONFIG_PROC_FS
25035+/* procfs.c */
25036+int __init au_procfs_init(void);
25037+void au_procfs_fin(void);
25038+#else
25039+AuStubInt0(au_procfs_init, void);
25040+AuStubVoid(au_procfs_fin, void);
25041+#endif
25042+
4f0767ce
JR
25043+/* ---------------------------------------------------------------------- */
25044+
1c60b727 25045+/* kmem cache */
1facf9fc 25046+enum {
25047+ AuCache_DINFO,
25048+ AuCache_ICNTNR,
25049+ AuCache_FINFO,
25050+ AuCache_VDIR,
25051+ AuCache_DEHSTR,
7eafdf33 25052+ AuCache_HNOTIFY, /* must be last */
1facf9fc 25053+ AuCache_Last
25054+};
25055+
1c60b727 25056+extern struct kmem_cache *au_cache[AuCache_Last];
f0c0a007 25057+
4a4d8108
AM
25058+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
25059+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
25060+#define AuCacheCtor(type, ctor) \
25061+ kmem_cache_create(#type, sizeof(struct type), \
25062+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 25063+
9f237c51
AM
25064+#define AuCacheFuncs(name, index) \
25065+ static inline struct au_##name *au_cache_alloc_##name(void) \
25066+ { return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \
25067+ static inline void au_cache_free_##name##_norcu(struct au_##name *p) \
25068+ { kmem_cache_free(au_cache[AuCache_##index], p); } \
25069+ \
25070+ static inline void au_cache_free_##name##_rcu_cb(struct rcu_head *rcu) \
25071+ { void *p = rcu; \
25072+ p -= offsetof(struct au_##name, rcu); \
25073+ kmem_cache_free(au_cache[AuCache_##index], p); } \
25074+ static inline void au_cache_free_##name##_rcu(struct au_##name *p) \
25075+ { BUILD_BUG_ON(sizeof(struct au_##name) < sizeof(struct rcu_head)); \
25076+ call_rcu(&p->rcu, au_cache_free_##name##_rcu_cb); } \
25077+ \
25078+ static inline void au_cache_free_##name(struct au_##name *p) \
25079+ { /* au_cache_free_##name##_norcu(p); */ \
25080+ au_cache_free_##name##_rcu(p); }
1facf9fc 25081+
25082+AuCacheFuncs(dinfo, DINFO);
25083+AuCacheFuncs(icntnr, ICNTNR);
25084+AuCacheFuncs(finfo, FINFO);
25085+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
25086+AuCacheFuncs(vdir_dehstr, DEHSTR);
25087+#ifdef CONFIG_AUFS_HNOTIFY
25088+AuCacheFuncs(hnotify, HNOTIFY);
25089+#endif
1facf9fc 25090+
4a4d8108
AM
25091+#endif /* __KERNEL__ */
25092+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
25093diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
25094--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25
AM
25095+++ linux/fs/aufs/mvdown.c 2019-03-05 12:13:00.142557771 +0100
25096@@ -0,0 +1,706 @@
cd7a4cd9 25097+// SPDX-License-Identifier: GPL-2.0
c2b27bf2 25098+/*
ba1aed25 25099+ * Copyright (C) 2011-2019 Junjiro R. Okajima
c2b27bf2
AM
25100+ *
25101+ * This program, aufs is free software; you can redistribute it and/or modify
25102+ * it under the terms of the GNU General Public License as published by
25103+ * the Free Software Foundation; either version 2 of the License, or
25104+ * (at your option) any later version.
25105+ *
25106+ * This program is distributed in the hope that it will be useful,
25107+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25108+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25109+ * GNU General Public License for more details.
25110+ *
25111+ * You should have received a copy of the GNU General Public License
523b37e3
AM
25112+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
25113+ */
25114+
25115+/*
25116+ * move-down, opposite of copy-up
c2b27bf2
AM
25117+ */
25118+
25119+#include "aufs.h"
25120+
c2b27bf2
AM
25121+struct au_mvd_args {
25122+ struct {
c2b27bf2
AM
25123+ struct super_block *h_sb;
25124+ struct dentry *h_parent;
25125+ struct au_hinode *hdir;
392086de 25126+ struct inode *h_dir, *h_inode;
c1595e42 25127+ struct au_pin pin;
c2b27bf2
AM
25128+ } info[AUFS_MVDOWN_NARRAY];
25129+
25130+ struct aufs_mvdown mvdown;
25131+ struct dentry *dentry, *parent;
25132+ struct inode *inode, *dir;
25133+ struct super_block *sb;
25134+ aufs_bindex_t bopq, bwh, bfound;
25135+ unsigned char rename_lock;
c2b27bf2
AM
25136+};
25137+
392086de 25138+#define mvd_errno mvdown.au_errno
076b876e
AM
25139+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
25140+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid
25141+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
25142+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid
c2b27bf2 25143+
392086de
AM
25144+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
25145+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
25146+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
25147+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
25148+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
c1595e42 25149+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin
392086de
AM
25150+
25151+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
25152+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
25153+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
25154+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
25155+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c1595e42 25156+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin
c2b27bf2
AM
25157+
25158+#define AU_MVD_PR(flag, ...) do { \
25159+ if (flag) \
25160+ pr_err(__VA_ARGS__); \
25161+ } while (0)
25162+
076b876e
AM
25163+static int find_lower_writable(struct au_mvd_args *a)
25164+{
25165+ struct super_block *sb;
5afbbe0d 25166+ aufs_bindex_t bindex, bbot;
076b876e
AM
25167+ struct au_branch *br;
25168+
25169+ sb = a->sb;
25170+ bindex = a->mvd_bsrc;
5afbbe0d 25171+ bbot = au_sbbot(sb);
076b876e 25172+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
5afbbe0d 25173+ for (bindex++; bindex <= bbot; bindex++) {
076b876e
AM
25174+ br = au_sbr(sb, bindex);
25175+ if (au_br_fhsm(br->br_perm)
8b6a4947 25176+ && !sb_rdonly(au_br_sb(br)))
076b876e
AM
25177+ return bindex;
25178+ }
25179+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
5afbbe0d 25180+ for (bindex++; bindex <= bbot; bindex++) {
076b876e
AM
25181+ br = au_sbr(sb, bindex);
25182+ if (!au_br_rdonly(br))
25183+ return bindex;
25184+ }
25185+ else
5afbbe0d 25186+ for (bindex++; bindex <= bbot; bindex++) {
076b876e 25187+ br = au_sbr(sb, bindex);
8b6a4947 25188+ if (!sb_rdonly(au_br_sb(br))) {
076b876e
AM
25189+ if (au_br_rdonly(br))
25190+ a->mvdown.flags
25191+ |= AUFS_MVDOWN_ROLOWER_R;
25192+ return bindex;
25193+ }
25194+ }
25195+
25196+ return -1;
25197+}
25198+
c2b27bf2 25199+/* make the parent dir on bdst */
392086de 25200+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25201+{
25202+ int err;
25203+
25204+ err = 0;
25205+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
25206+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
25207+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
25208+ a->mvd_h_dst_parent = NULL;
5afbbe0d 25209+ if (au_dbbot(a->parent) >= a->mvd_bdst)
c2b27bf2
AM
25210+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
25211+ if (!a->mvd_h_dst_parent) {
25212+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
25213+ if (unlikely(err)) {
392086de 25214+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
25215+ goto out;
25216+ }
25217+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
25218+ }
25219+
25220+out:
25221+ AuTraceErr(err);
25222+ return err;
25223+}
25224+
25225+/* lock them all */
392086de 25226+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25227+{
25228+ int err;
25229+ struct dentry *h_trap;
25230+
25231+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
25232+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
c1595e42
JR
25233+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst,
25234+ au_opt_udba(a->sb),
25235+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
25236+ AuTraceErr(err);
25237+ if (unlikely(err)) {
25238+ AU_MVD_PR(dmsg, "pin_dst failed\n");
25239+ goto out;
25240+ }
25241+
c2b27bf2
AM
25242+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
25243+ a->rename_lock = 0;
c1595e42
JR
25244+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
25245+ AuLsc_DI_PARENT, AuLsc_I_PARENT3,
25246+ au_opt_udba(a->sb),
25247+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
25248+ err = au_do_pin(&a->mvd_pin_src);
25249+ AuTraceErr(err);
5527c038 25250+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
c1595e42
JR
25251+ if (unlikely(err)) {
25252+ AU_MVD_PR(dmsg, "pin_src failed\n");
25253+ goto out_dst;
25254+ }
25255+ goto out; /* success */
c2b27bf2
AM
25256+ }
25257+
c2b27bf2 25258+ a->rename_lock = 1;
c1595e42
JR
25259+ au_pin_hdir_unlock(&a->mvd_pin_dst);
25260+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
25261+ au_opt_udba(a->sb),
25262+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
25263+ AuTraceErr(err);
5527c038 25264+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
c1595e42
JR
25265+ if (unlikely(err)) {
25266+ AU_MVD_PR(dmsg, "pin_src failed\n");
25267+ au_pin_hdir_lock(&a->mvd_pin_dst);
25268+ goto out_dst;
25269+ }
25270+ au_pin_hdir_unlock(&a->mvd_pin_src);
c2b27bf2
AM
25271+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
25272+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
25273+ if (h_trap) {
25274+ err = (h_trap != a->mvd_h_src_parent);
25275+ if (err)
25276+ err = (h_trap != a->mvd_h_dst_parent);
25277+ }
25278+ BUG_ON(err); /* it should never happen */
c1595e42
JR
25279+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) {
25280+ err = -EBUSY;
25281+ AuTraceErr(err);
25282+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
25283+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
25284+ au_pin_hdir_lock(&a->mvd_pin_src);
25285+ au_unpin(&a->mvd_pin_src);
25286+ au_pin_hdir_lock(&a->mvd_pin_dst);
25287+ goto out_dst;
25288+ }
25289+ goto out; /* success */
c2b27bf2 25290+
c1595e42
JR
25291+out_dst:
25292+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
25293+out:
25294+ AuTraceErr(err);
25295+ return err;
25296+}
25297+
392086de 25298+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2 25299+{
c1595e42
JR
25300+ if (!a->rename_lock)
25301+ au_unpin(&a->mvd_pin_src);
25302+ else {
c2b27bf2
AM
25303+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
25304+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
c1595e42
JR
25305+ au_pin_hdir_lock(&a->mvd_pin_src);
25306+ au_unpin(&a->mvd_pin_src);
25307+ au_pin_hdir_lock(&a->mvd_pin_dst);
25308+ }
25309+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
25310+}
25311+
25312+/* copy-down the file */
392086de 25313+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25314+{
25315+ int err;
25316+ struct au_cp_generic cpg = {
25317+ .dentry = a->dentry,
25318+ .bdst = a->mvd_bdst,
25319+ .bsrc = a->mvd_bsrc,
25320+ .len = -1,
c1595e42 25321+ .pin = &a->mvd_pin_dst,
c2b27bf2
AM
25322+ .flags = AuCpup_DTIME | AuCpup_HOPEN
25323+ };
25324+
25325+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
25326+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
25327+ au_fset_cpup(cpg.flags, OVERWRITE);
25328+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
25329+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
25330+ err = au_sio_cpdown_simple(&cpg);
25331+ if (unlikely(err))
392086de 25332+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
25333+
25334+ AuTraceErr(err);
25335+ return err;
25336+}
25337+
25338+/*
25339+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
25340+ * were sleeping
25341+ */
392086de 25342+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25343+{
25344+ int err;
25345+ struct path h_path;
25346+ struct au_branch *br;
523b37e3 25347+ struct inode *delegated;
c2b27bf2
AM
25348+
25349+ br = au_sbr(a->sb, a->mvd_bdst);
25350+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
25351+ err = PTR_ERR(h_path.dentry);
25352+ if (IS_ERR(h_path.dentry)) {
392086de 25353+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
25354+ goto out;
25355+ }
25356+
25357+ err = 0;
5527c038 25358+ if (d_is_positive(h_path.dentry)) {
c2b27bf2 25359+ h_path.mnt = au_br_mnt(br);
523b37e3 25360+ delegated = NULL;
5527c038 25361+ err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path,
523b37e3
AM
25362+ &delegated, /*force*/0);
25363+ if (unlikely(err == -EWOULDBLOCK)) {
25364+ pr_warn("cannot retry for NFSv4 delegation"
25365+ " for an internal unlink\n");
25366+ iput(delegated);
25367+ }
c2b27bf2 25368+ if (unlikely(err))
392086de 25369+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
25370+ }
25371+ dput(h_path.dentry);
25372+
25373+out:
25374+ AuTraceErr(err);
25375+ return err;
25376+}
25377+
25378+/*
25379+ * unlink the topmost h_dentry
c2b27bf2 25380+ */
392086de 25381+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25382+{
25383+ int err;
25384+ struct path h_path;
523b37e3 25385+ struct inode *delegated;
c2b27bf2
AM
25386+
25387+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
25388+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
25389+ delegated = NULL;
25390+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
25391+ if (unlikely(err == -EWOULDBLOCK)) {
25392+ pr_warn("cannot retry for NFSv4 delegation"
25393+ " for an internal unlink\n");
25394+ iput(delegated);
25395+ }
c2b27bf2 25396+ if (unlikely(err))
392086de 25397+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
25398+
25399+ AuTraceErr(err);
25400+ return err;
25401+}
25402+
076b876e
AM
25403+/* Since mvdown succeeded, we ignore an error of this function */
25404+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
25405+{
25406+ int err;
25407+ struct au_branch *br;
25408+
25409+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
25410+ br = au_sbr(a->sb, a->mvd_bsrc);
25411+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
25412+ if (!err) {
25413+ br = au_sbr(a->sb, a->mvd_bdst);
25414+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
25415+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
25416+ }
25417+ if (!err)
25418+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
25419+ else
25420+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
25421+}
25422+
c2b27bf2
AM
25423+/*
25424+ * copy-down the file and unlink the bsrc file.
25425+ * - unlink the bdst whout if exist
25426+ * - copy-down the file (with whtmp name and rename)
25427+ * - unlink the bsrc file
25428+ */
392086de 25429+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25430+{
25431+ int err;
25432+
392086de 25433+ err = au_do_mkdir(dmsg, a);
c2b27bf2 25434+ if (!err)
392086de 25435+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
25436+ if (unlikely(err))
25437+ goto out;
25438+
25439+ /*
25440+ * do not revert the activities we made on bdst since they should be
25441+ * harmless in aufs.
25442+ */
25443+
392086de 25444+ err = au_do_cpdown(dmsg, a);
c2b27bf2 25445+ if (!err)
392086de
AM
25446+ err = au_do_unlink_wh(dmsg, a);
25447+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
25448+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
25449+ if (unlikely(err))
25450+ goto out_unlock;
25451+
c1595e42
JR
25452+ AuDbg("%pd2, 0x%x, %d --> %d\n",
25453+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst);
076b876e
AM
25454+ if (find_lower_writable(a) < 0)
25455+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
25456+
25457+ if (a->mvdown.flags & AUFS_MVDOWN_STFS)
25458+ au_do_stfs(dmsg, a);
25459+
c2b27bf2 25460+ /* maintain internal array */
392086de
AM
25461+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
25462+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
5afbbe0d 25463+ au_set_dbtop(a->dentry, a->mvd_bdst);
392086de 25464+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
5afbbe0d 25465+ au_set_ibtop(a->inode, a->mvd_bdst);
79b8bda9
AM
25466+ } else {
25467+ /* hide the lower */
25468+ au_set_h_dptr(a->dentry, a->mvd_bdst, NULL);
5afbbe0d 25469+ au_set_dbbot(a->dentry, a->mvd_bsrc);
79b8bda9 25470+ au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0);
5afbbe0d 25471+ au_set_ibbot(a->inode, a->mvd_bsrc);
392086de 25472+ }
5afbbe0d
AM
25473+ if (au_dbbot(a->dentry) < a->mvd_bdst)
25474+ au_set_dbbot(a->dentry, a->mvd_bdst);
25475+ if (au_ibbot(a->inode) < a->mvd_bdst)
25476+ au_set_ibbot(a->inode, a->mvd_bdst);
c2b27bf2
AM
25477+
25478+out_unlock:
392086de 25479+ au_do_unlock(dmsg, a);
c2b27bf2
AM
25480+out:
25481+ AuTraceErr(err);
25482+ return err;
25483+}
25484+
25485+/* ---------------------------------------------------------------------- */
25486+
c2b27bf2 25487+/* make sure the file is idle */
392086de 25488+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25489+{
25490+ int err, plinked;
c2b27bf2
AM
25491+
25492+ err = 0;
c2b27bf2 25493+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
5afbbe0d 25494+ if (au_dbtop(a->dentry) == a->mvd_bsrc
c1595e42 25495+ && au_dcount(a->dentry) == 1
c2b27bf2 25496+ && atomic_read(&a->inode->i_count) == 1
392086de 25497+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
25498+ && (!plinked || !au_plink_test(a->inode))
25499+ && a->inode->i_nlink == 1)
25500+ goto out;
25501+
25502+ err = -EBUSY;
392086de 25503+ AU_MVD_PR(dmsg,
c1595e42 25504+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
5afbbe0d 25505+ a->mvd_bsrc, au_dbtop(a->dentry), au_dcount(a->dentry),
c2b27bf2 25506+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 25507+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
25508+ plinked, plinked ? au_plink_test(a->inode) : 0);
25509+
25510+out:
25511+ AuTraceErr(err);
25512+ return err;
25513+}
25514+
25515+/* make sure the parent dir is fine */
392086de 25516+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
25517+ struct au_mvd_args *a)
25518+{
25519+ int err;
25520+ aufs_bindex_t bindex;
25521+
25522+ err = 0;
25523+ if (unlikely(au_alive_dir(a->parent))) {
25524+ err = -ENOENT;
392086de 25525+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
25526+ goto out;
25527+ }
25528+
25529+ a->bopq = au_dbdiropq(a->parent);
25530+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
25531+ AuDbg("b%d\n", bindex);
25532+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
25533+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
25534+ err = -EINVAL;
392086de
AM
25535+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
25536+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
25537+ a->bopq, a->mvd_bdst);
25538+ }
25539+
25540+out:
25541+ AuTraceErr(err);
25542+ return err;
25543+}
25544+
392086de 25545+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
25546+ struct au_mvd_args *a)
25547+{
25548+ int err;
25549+ struct au_dinfo *dinfo, *tmp;
25550+
25551+ /* lookup the next lower positive entry */
25552+ err = -ENOMEM;
25553+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
25554+ if (unlikely(!tmp))
25555+ goto out;
25556+
25557+ a->bfound = -1;
25558+ a->bwh = -1;
25559+ dinfo = au_di(a->dentry);
25560+ au_di_cp(tmp, dinfo);
25561+ au_di_swap(tmp, dinfo);
25562+
25563+ /* returns the number of positive dentries */
5afbbe0d
AM
25564+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1,
25565+ /* AuLkup_IGNORE_PERM */ 0);
c2b27bf2
AM
25566+ if (!err)
25567+ a->bwh = au_dbwh(a->dentry);
25568+ else if (err > 0)
5afbbe0d 25569+ a->bfound = au_dbtop(a->dentry);
c2b27bf2
AM
25570+
25571+ au_di_swap(tmp, dinfo);
25572+ au_rw_write_unlock(&tmp->di_rwsem);
25573+ au_di_free(tmp);
25574+ if (unlikely(err < 0))
392086de 25575+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
25576+
25577+ /*
25578+ * here, we have these cases.
25579+ * bfound == -1
25580+ * no positive dentry under bsrc. there are more sub-cases.
25581+ * bwh < 0
25582+ * there no whiteout, we can safely move-down.
25583+ * bwh <= bsrc
25584+ * impossible
25585+ * bsrc < bwh && bwh < bdst
25586+ * there is a whiteout on RO branch. cannot proceed.
25587+ * bwh == bdst
25588+ * there is a whiteout on the RW target branch. it should
25589+ * be removed.
25590+ * bdst < bwh
25591+ * there is a whiteout somewhere unrelated branch.
25592+ * -1 < bfound && bfound <= bsrc
25593+ * impossible.
25594+ * bfound < bdst
25595+ * found, but it is on RO branch between bsrc and bdst. cannot
25596+ * proceed.
25597+ * bfound == bdst
25598+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
25599+ * error.
25600+ * bdst < bfound
25601+ * found, after we create the file on bdst, it will be hidden.
25602+ */
25603+
25604+ AuDebugOn(a->bfound == -1
25605+ && a->bwh != -1
25606+ && a->bwh <= a->mvd_bsrc);
25607+ AuDebugOn(-1 < a->bfound
25608+ && a->bfound <= a->mvd_bsrc);
25609+
25610+ err = -EINVAL;
25611+ if (a->bfound == -1
25612+ && a->mvd_bsrc < a->bwh
25613+ && a->bwh != -1
25614+ && a->bwh < a->mvd_bdst) {
392086de
AM
25615+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
25616+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
25617+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
25618+ goto out;
25619+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
25620+ a->mvd_errno = EAU_MVDOWN_UPPER;
25621+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
25622+ a->mvd_bdst, a->bfound);
25623+ goto out;
25624+ }
25625+
25626+ err = 0; /* success */
25627+
25628+out:
25629+ AuTraceErr(err);
25630+ return err;
25631+}
25632+
392086de 25633+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25634+{
25635+ int err;
25636+
392086de
AM
25637+ err = 0;
25638+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
25639+ && a->bfound == a->mvd_bdst)
25640+ err = -EEXIST;
c2b27bf2
AM
25641+ AuTraceErr(err);
25642+ return err;
25643+}
25644+
392086de 25645+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25646+{
25647+ int err;
25648+ struct au_branch *br;
25649+
25650+ err = -EISDIR;
25651+ if (unlikely(S_ISDIR(a->inode->i_mode)))
25652+ goto out;
25653+
25654+ err = -EINVAL;
392086de 25655+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
5afbbe0d 25656+ a->mvd_bsrc = au_ibtop(a->inode);
392086de
AM
25657+ else {
25658+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
25659+ if (unlikely(a->mvd_bsrc < 0
5afbbe0d
AM
25660+ || (a->mvd_bsrc < au_dbtop(a->dentry)
25661+ || au_dbbot(a->dentry) < a->mvd_bsrc
392086de 25662+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
5afbbe0d
AM
25663+ || (a->mvd_bsrc < au_ibtop(a->inode)
25664+ || au_ibbot(a->inode) < a->mvd_bsrc
392086de
AM
25665+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
25666+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
25667+ AU_MVD_PR(dmsg, "no upper\n");
25668+ goto out;
25669+ }
25670+ }
5afbbe0d 25671+ if (unlikely(a->mvd_bsrc == au_sbbot(a->sb))) {
392086de
AM
25672+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
25673+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
25674+ goto out;
25675+ }
392086de 25676+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
25677+ br = au_sbr(a->sb, a->mvd_bsrc);
25678+ err = au_br_rdonly(br);
392086de
AM
25679+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
25680+ if (unlikely(err))
25681+ goto out;
25682+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
25683+ || IS_APPEND(a->mvd_h_src_inode))) {
25684+ if (err)
25685+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
25686+ /* go on */
25687+ } else
c2b27bf2
AM
25688+ goto out;
25689+
25690+ err = -EINVAL;
392086de
AM
25691+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
25692+ a->mvd_bdst = find_lower_writable(a);
25693+ if (unlikely(a->mvd_bdst < 0)) {
25694+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
25695+ AU_MVD_PR(dmsg, "no writable lower branch\n");
25696+ goto out;
25697+ }
25698+ } else {
25699+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
25700+ if (unlikely(a->mvd_bdst < 0
5afbbe0d 25701+ || au_sbbot(a->sb) < a->mvd_bdst)) {
392086de
AM
25702+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
25703+ AU_MVD_PR(dmsg, "no lower brid\n");
25704+ goto out;
25705+ }
c2b27bf2
AM
25706+ }
25707+
392086de 25708+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 25709+ if (!err)
392086de 25710+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 25711+ if (!err)
392086de 25712+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 25713+ if (!err)
392086de 25714+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
25715+ if (!err)
25716+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
25717+
25718+out:
25719+ AuTraceErr(err);
25720+ return err;
25721+}
25722+
25723+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
25724+{
392086de
AM
25725+ int err, e;
25726+ unsigned char dmsg;
25727+ struct au_mvd_args *args;
79b8bda9 25728+ struct inode *inode;
c2b27bf2 25729+
79b8bda9 25730+ inode = d_inode(dentry);
c2b27bf2
AM
25731+ err = -EPERM;
25732+ if (unlikely(!capable(CAP_SYS_ADMIN)))
25733+ goto out;
25734+
392086de
AM
25735+ err = -ENOMEM;
25736+ args = kmalloc(sizeof(*args), GFP_NOFS);
25737+ if (unlikely(!args))
25738+ goto out;
25739+
25740+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
25741+ if (!err)
ba1aed25
AM
25742+ /* VERIFY_WRITE */
25743+ err = !access_ok(uarg, sizeof(*uarg));
c2b27bf2
AM
25744+ if (unlikely(err)) {
25745+ err = -EFAULT;
392086de
AM
25746+ AuTraceErr(err);
25747+ goto out_free;
c2b27bf2 25748+ }
392086de
AM
25749+ AuDbg("flags 0x%x\n", args->mvdown.flags);
25750+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
25751+ args->mvdown.au_errno = 0;
25752+ args->dentry = dentry;
79b8bda9 25753+ args->inode = inode;
392086de 25754+ args->sb = dentry->d_sb;
c2b27bf2 25755+
392086de
AM
25756+ err = -ENOENT;
25757+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
25758+ args->parent = dget_parent(dentry);
5527c038 25759+ args->dir = d_inode(args->parent);
febd17d6 25760+ inode_lock_nested(args->dir, I_MUTEX_PARENT);
392086de
AM
25761+ dput(args->parent);
25762+ if (unlikely(args->parent != dentry->d_parent)) {
25763+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
25764+ goto out_dir;
25765+ }
25766+
febd17d6 25767+ inode_lock_nested(inode, I_MUTEX_CHILD);
b95c5147 25768+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW);
c2b27bf2
AM
25769+ if (unlikely(err))
25770+ goto out_inode;
25771+
392086de
AM
25772+ di_write_lock_parent(args->parent);
25773+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
25774+ if (unlikely(err))
25775+ goto out_parent;
25776+
392086de 25777+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
25778+ if (unlikely(err))
25779+ goto out_parent;
c2b27bf2 25780+
392086de 25781+ au_cpup_attr_timesizes(args->dir);
79b8bda9
AM
25782+ au_cpup_attr_timesizes(inode);
25783+ if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER))
25784+ au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst));
c2b27bf2
AM
25785+ /* au_digen_dec(dentry); */
25786+
25787+out_parent:
392086de 25788+ di_write_unlock(args->parent);
c2b27bf2
AM
25789+ aufs_read_unlock(dentry, AuLock_DW);
25790+out_inode:
febd17d6 25791+ inode_unlock(inode);
c2b27bf2 25792+out_dir:
febd17d6 25793+ inode_unlock(args->dir);
392086de
AM
25794+out_free:
25795+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
25796+ if (unlikely(e))
25797+ err = -EFAULT;
9f237c51 25798+ au_kfree_rcu(args);
c2b27bf2
AM
25799+out:
25800+ AuTraceErr(err);
25801+ return err;
25802+}
25803diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
25804--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 25805+++ linux/fs/aufs/opts.c 2019-03-05 12:13:00.142557771 +0100
acd2b654 25806@@ -0,0 +1,1877 @@
cd7a4cd9 25807+// SPDX-License-Identifier: GPL-2.0
1facf9fc 25808+/*
ba1aed25 25809+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 25810+ *
25811+ * This program, aufs is free software; you can redistribute it and/or modify
25812+ * it under the terms of the GNU General Public License as published by
25813+ * the Free Software Foundation; either version 2 of the License, or
25814+ * (at your option) any later version.
dece6358
AM
25815+ *
25816+ * This program is distributed in the hope that it will be useful,
25817+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25818+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25819+ * GNU General Public License for more details.
25820+ *
25821+ * You should have received a copy of the GNU General Public License
523b37e3 25822+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25823+ */
25824+
25825+/*
25826+ * mount options/flags
25827+ */
25828+
dece6358 25829+#include <linux/namei.h>
1facf9fc 25830+#include <linux/types.h> /* a distribution requires */
25831+#include <linux/parser.h>
25832+#include "aufs.h"
25833+
25834+/* ---------------------------------------------------------------------- */
25835+
25836+enum {
25837+ Opt_br,
7e9cd9fe
AM
25838+ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
25839+ Opt_idel, Opt_imod,
25840+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
dece6358 25841+ Opt_rdblk_def, Opt_rdhash_def,
7e9cd9fe 25842+ Opt_xino, Opt_noxino,
1facf9fc 25843+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
25844+ Opt_trunc_xino_path, Opt_itrunc_xino,
25845+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 25846+ Opt_shwh, Opt_noshwh,
1facf9fc 25847+ Opt_plink, Opt_noplink, Opt_list_plink,
25848+ Opt_udba,
4a4d8108 25849+ Opt_dio, Opt_nodio,
1facf9fc 25850+ Opt_diropq_a, Opt_diropq_w,
25851+ Opt_warn_perm, Opt_nowarn_perm,
25852+ Opt_wbr_copyup, Opt_wbr_create,
076b876e 25853+ Opt_fhsm_sec,
1facf9fc 25854+ Opt_verbose, Opt_noverbose,
25855+ Opt_sum, Opt_nosum, Opt_wsum,
076b876e 25856+ Opt_dirperm1, Opt_nodirperm1,
8b6a4947 25857+ Opt_dirren, Opt_nodirren,
c1595e42 25858+ Opt_acl, Opt_noacl,
1facf9fc 25859+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
25860+};
25861+
25862+static match_table_t options = {
25863+ {Opt_br, "br=%s"},
25864+ {Opt_br, "br:%s"},
25865+
25866+ {Opt_add, "add=%d:%s"},
25867+ {Opt_add, "add:%d:%s"},
25868+ {Opt_add, "ins=%d:%s"},
25869+ {Opt_add, "ins:%d:%s"},
25870+ {Opt_append, "append=%s"},
25871+ {Opt_append, "append:%s"},
25872+ {Opt_prepend, "prepend=%s"},
25873+ {Opt_prepend, "prepend:%s"},
25874+
25875+ {Opt_del, "del=%s"},
25876+ {Opt_del, "del:%s"},
25877+ /* {Opt_idel, "idel:%d"}, */
25878+ {Opt_mod, "mod=%s"},
25879+ {Opt_mod, "mod:%s"},
25880+ /* {Opt_imod, "imod:%d:%s"}, */
25881+
25882+ {Opt_dirwh, "dirwh=%d"},
25883+
25884+ {Opt_xino, "xino=%s"},
25885+ {Opt_noxino, "noxino"},
25886+ {Opt_trunc_xino, "trunc_xino"},
25887+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
25888+ {Opt_notrunc_xino, "notrunc_xino"},
25889+ {Opt_trunc_xino_path, "trunc_xino=%s"},
25890+ {Opt_itrunc_xino, "itrunc_xino=%d"},
25891+ /* {Opt_zxino, "zxino=%s"}, */
25892+ {Opt_trunc_xib, "trunc_xib"},
25893+ {Opt_notrunc_xib, "notrunc_xib"},
25894+
e49829fe 25895+#ifdef CONFIG_PROC_FS
1facf9fc 25896+ {Opt_plink, "plink"},
e49829fe
JR
25897+#else
25898+ {Opt_ignore_silent, "plink"},
25899+#endif
25900+
1facf9fc 25901+ {Opt_noplink, "noplink"},
e49829fe 25902+
1facf9fc 25903+#ifdef CONFIG_AUFS_DEBUG
25904+ {Opt_list_plink, "list_plink"},
25905+#endif
25906+
25907+ {Opt_udba, "udba=%s"},
25908+
4a4d8108
AM
25909+ {Opt_dio, "dio"},
25910+ {Opt_nodio, "nodio"},
25911+
8b6a4947
AM
25912+#ifdef CONFIG_AUFS_DIRREN
25913+ {Opt_dirren, "dirren"},
25914+ {Opt_nodirren, "nodirren"},
25915+#else
25916+ {Opt_ignore, "dirren"},
25917+ {Opt_ignore_silent, "nodirren"},
25918+#endif
25919+
076b876e
AM
25920+#ifdef CONFIG_AUFS_FHSM
25921+ {Opt_fhsm_sec, "fhsm_sec=%d"},
25922+#else
8b6a4947 25923+ {Opt_ignore, "fhsm_sec=%d"},
076b876e
AM
25924+#endif
25925+
1facf9fc 25926+ {Opt_diropq_a, "diropq=always"},
25927+ {Opt_diropq_a, "diropq=a"},
25928+ {Opt_diropq_w, "diropq=whiteouted"},
25929+ {Opt_diropq_w, "diropq=w"},
25930+
25931+ {Opt_warn_perm, "warn_perm"},
25932+ {Opt_nowarn_perm, "nowarn_perm"},
25933+
25934+ /* keep them temporary */
1facf9fc 25935+ {Opt_ignore_silent, "nodlgt"},
8b6a4947 25936+ {Opt_ignore, "clean_plink"},
1facf9fc 25937+
dece6358
AM
25938+#ifdef CONFIG_AUFS_SHWH
25939+ {Opt_shwh, "shwh"},
25940+#endif
25941+ {Opt_noshwh, "noshwh"},
25942+
076b876e
AM
25943+ {Opt_dirperm1, "dirperm1"},
25944+ {Opt_nodirperm1, "nodirperm1"},
25945+
1facf9fc 25946+ {Opt_verbose, "verbose"},
25947+ {Opt_verbose, "v"},
25948+ {Opt_noverbose, "noverbose"},
25949+ {Opt_noverbose, "quiet"},
25950+ {Opt_noverbose, "q"},
25951+ {Opt_noverbose, "silent"},
25952+
25953+ {Opt_sum, "sum"},
25954+ {Opt_nosum, "nosum"},
25955+ {Opt_wsum, "wsum"},
25956+
25957+ {Opt_rdcache, "rdcache=%d"},
25958+ {Opt_rdblk, "rdblk=%d"},
dece6358 25959+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 25960+ {Opt_rdhash, "rdhash=%d"},
dece6358 25961+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 25962+
25963+ {Opt_wbr_create, "create=%s"},
25964+ {Opt_wbr_create, "create_policy=%s"},
25965+ {Opt_wbr_copyup, "cpup=%s"},
25966+ {Opt_wbr_copyup, "copyup=%s"},
25967+ {Opt_wbr_copyup, "copyup_policy=%s"},
25968+
c1595e42
JR
25969+ /* generic VFS flag */
25970+#ifdef CONFIG_FS_POSIX_ACL
25971+ {Opt_acl, "acl"},
25972+ {Opt_noacl, "noacl"},
25973+#else
8b6a4947 25974+ {Opt_ignore, "acl"},
c1595e42
JR
25975+ {Opt_ignore_silent, "noacl"},
25976+#endif
25977+
1facf9fc 25978+ /* internal use for the scripts */
25979+ {Opt_ignore_silent, "si=%s"},
25980+
25981+ {Opt_br, "dirs=%s"},
25982+ {Opt_ignore, "debug=%d"},
25983+ {Opt_ignore, "delete=whiteout"},
25984+ {Opt_ignore, "delete=all"},
25985+ {Opt_ignore, "imap=%s"},
25986+
1308ab2a 25987+ /* temporary workaround, due to old mount(8)? */
25988+ {Opt_ignore_silent, "relatime"},
25989+
1facf9fc 25990+ {Opt_err, NULL}
25991+};
25992+
25993+/* ---------------------------------------------------------------------- */
25994+
076b876e 25995+static const char *au_parser_pattern(int val, match_table_t tbl)
1facf9fc 25996+{
076b876e
AM
25997+ struct match_token *p;
25998+
25999+ p = tbl;
26000+ while (p->pattern) {
26001+ if (p->token == val)
26002+ return p->pattern;
26003+ p++;
1facf9fc 26004+ }
26005+ BUG();
26006+ return "??";
26007+}
26008+
076b876e
AM
26009+static const char *au_optstr(int *val, match_table_t tbl)
26010+{
26011+ struct match_token *p;
26012+ int v;
26013+
26014+ v = *val;
2000de60
JR
26015+ if (!v)
26016+ goto out;
076b876e 26017+ p = tbl;
2000de60
JR
26018+ while (p->pattern) {
26019+ if (p->token
26020+ && (v & p->token) == p->token) {
076b876e
AM
26021+ *val &= ~p->token;
26022+ return p->pattern;
26023+ }
26024+ p++;
26025+ }
2000de60
JR
26026+
26027+out:
076b876e
AM
26028+ return NULL;
26029+}
26030+
1facf9fc 26031+/* ---------------------------------------------------------------------- */
26032+
1e00d052 26033+static match_table_t brperm = {
1facf9fc 26034+ {AuBrPerm_RO, AUFS_BRPERM_RO},
26035+ {AuBrPerm_RR, AUFS_BRPERM_RR},
26036+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
26037+ {0, NULL}
26038+};
1facf9fc 26039+
86dc4139 26040+static match_table_t brattr = {
076b876e
AM
26041+ /* general */
26042+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
26043+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
c1595e42 26044+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
86dc4139 26045+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
2000de60 26046+#ifdef CONFIG_AUFS_FHSM
076b876e 26047+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
2000de60
JR
26048+#endif
26049+#ifdef CONFIG_AUFS_XATTR
c1595e42
JR
26050+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
26051+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
26052+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
26053+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
26054+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
26055+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
2000de60 26056+#endif
076b876e
AM
26057+
26058+ /* ro/rr branch */
1e00d052 26059+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
076b876e
AM
26060+
26061+ /* rw branch */
26062+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
1e00d052 26063+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
076b876e 26064+
1e00d052 26065+ {0, NULL}
1facf9fc 26066+};
26067+
1e00d052
AM
26068+static int br_attr_val(char *str, match_table_t table, substring_t args[])
26069+{
26070+ int attr, v;
26071+ char *p;
26072+
26073+ attr = 0;
26074+ do {
26075+ p = strchr(str, '+');
26076+ if (p)
26077+ *p = 0;
26078+ v = match_token(str, table, args);
076b876e
AM
26079+ if (v) {
26080+ if (v & AuBrAttr_CMOO_Mask)
26081+ attr &= ~AuBrAttr_CMOO_Mask;
1e00d052 26082+ attr |= v;
076b876e 26083+ } else {
1e00d052
AM
26084+ if (p)
26085+ *p = '+';
0c3ec466 26086+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
26087+ break;
26088+ }
26089+ if (p)
26090+ str = p + 1;
26091+ } while (p);
26092+
26093+ return attr;
26094+}
26095+
076b876e
AM
26096+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
26097+{
26098+ int sz;
26099+ const char *p;
26100+ char *q;
26101+
076b876e
AM
26102+ q = str->a;
26103+ *q = 0;
26104+ p = au_optstr(&perm, brattr);
26105+ if (p) {
26106+ sz = strlen(p);
26107+ memcpy(q, p, sz + 1);
26108+ q += sz;
26109+ } else
26110+ goto out;
26111+
26112+ do {
26113+ p = au_optstr(&perm, brattr);
26114+ if (p) {
26115+ *q++ = '+';
26116+ sz = strlen(p);
26117+ memcpy(q, p, sz + 1);
26118+ q += sz;
26119+ }
26120+ } while (p);
26121+
26122+out:
c1595e42 26123+ return q - str->a;
076b876e
AM
26124+}
26125+
4a4d8108 26126+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 26127+{
076b876e
AM
26128+ int val, bad, sz;
26129+ char *p;
1facf9fc 26130+ substring_t args[MAX_OPT_ARGS];
076b876e 26131+ au_br_perm_str_t attr;
1facf9fc 26132+
1e00d052
AM
26133+ p = strchr(perm, '+');
26134+ if (p)
26135+ *p = 0;
26136+ val = match_token(perm, brperm, args);
26137+ if (!val) {
26138+ if (p)
26139+ *p = '+';
0c3ec466 26140+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
26141+ val = AuBrPerm_RO;
26142+ goto out;
26143+ }
26144+ if (!p)
26145+ goto out;
26146+
076b876e
AM
26147+ val |= br_attr_val(p + 1, brattr, args);
26148+
26149+ bad = 0;
86dc4139 26150+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
26151+ case AuBrPerm_RO:
26152+ case AuBrPerm_RR:
076b876e
AM
26153+ bad = val & AuBrWAttr_Mask;
26154+ val &= ~AuBrWAttr_Mask;
1e00d052
AM
26155+ break;
26156+ case AuBrPerm_RW:
076b876e
AM
26157+ bad = val & AuBrRAttr_Mask;
26158+ val &= ~AuBrRAttr_Mask;
1e00d052
AM
26159+ break;
26160+ }
c1595e42
JR
26161+
26162+ /*
26163+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
26164+ * does not treat it as an error, just warning.
26165+ * this is a tiny guard for the user operation.
26166+ */
26167+ if (val & AuBrAttr_UNPIN) {
26168+ bad |= AuBrAttr_UNPIN;
26169+ val &= ~AuBrAttr_UNPIN;
26170+ }
26171+
076b876e
AM
26172+ if (unlikely(bad)) {
26173+ sz = au_do_optstr_br_attr(&attr, bad);
26174+ AuDebugOn(!sz);
26175+ pr_warn("ignored branch attribute %s\n", attr.a);
26176+ }
1e00d052
AM
26177+
26178+out:
1facf9fc 26179+ return val;
26180+}
26181+
076b876e 26182+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
1facf9fc 26183+{
076b876e
AM
26184+ au_br_perm_str_t attr;
26185+ const char *p;
26186+ char *q;
1e00d052
AM
26187+ int sz;
26188+
076b876e
AM
26189+ q = str->a;
26190+ p = au_optstr(&perm, brperm);
26191+ AuDebugOn(!p || !*p);
26192+ sz = strlen(p);
26193+ memcpy(q, p, sz + 1);
26194+ q += sz;
1e00d052 26195+
076b876e
AM
26196+ sz = au_do_optstr_br_attr(&attr, perm);
26197+ if (sz) {
26198+ *q++ = '+';
26199+ memcpy(q, attr.a, sz + 1);
1e00d052
AM
26200+ }
26201+
076b876e 26202+ AuDebugOn(strlen(str->a) >= sizeof(str->a));
1facf9fc 26203+}
26204+
26205+/* ---------------------------------------------------------------------- */
26206+
26207+static match_table_t udbalevel = {
26208+ {AuOpt_UDBA_REVAL, "reval"},
26209+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
26210+#ifdef CONFIG_AUFS_HNOTIFY
26211+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
26212+#ifdef CONFIG_AUFS_HFSNOTIFY
26213+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 26214+#endif
1facf9fc 26215+#endif
26216+ {-1, NULL}
26217+};
26218+
4a4d8108 26219+static int noinline_for_stack udba_val(char *str)
1facf9fc 26220+{
26221+ substring_t args[MAX_OPT_ARGS];
26222+
7f207e10 26223+ return match_token(str, udbalevel, args);
1facf9fc 26224+}
26225+
26226+const char *au_optstr_udba(int udba)
26227+{
076b876e 26228+ return au_parser_pattern(udba, udbalevel);
1facf9fc 26229+}
26230+
26231+/* ---------------------------------------------------------------------- */
26232+
26233+static match_table_t au_wbr_create_policy = {
26234+ {AuWbrCreate_TDP, "tdp"},
26235+ {AuWbrCreate_TDP, "top-down-parent"},
26236+ {AuWbrCreate_RR, "rr"},
26237+ {AuWbrCreate_RR, "round-robin"},
26238+ {AuWbrCreate_MFS, "mfs"},
26239+ {AuWbrCreate_MFS, "most-free-space"},
26240+ {AuWbrCreate_MFSV, "mfs:%d"},
26241+ {AuWbrCreate_MFSV, "most-free-space:%d"},
26242+
f2c43d5f
AM
26243+ /* top-down regardless the parent, and then mfs */
26244+ {AuWbrCreate_TDMFS, "tdmfs:%d"},
26245+ {AuWbrCreate_TDMFSV, "tdmfs:%d:%d"},
26246+
1facf9fc 26247+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
26248+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
26249+ {AuWbrCreate_PMFS, "pmfs"},
26250+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
26251+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
26252+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 26253+
26254+ {-1, NULL}
26255+};
26256+
1facf9fc 26257+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
26258+ struct au_opt_wbr_create *create)
26259+{
26260+ int err;
26261+ unsigned long long ull;
26262+
26263+ err = 0;
a2654f78 26264+ if (!match_u64(arg, &ull))
1facf9fc 26265+ create->mfsrr_watermark = ull;
26266+ else {
4a4d8108 26267+ pr_err("bad integer in %s\n", str);
1facf9fc 26268+ err = -EINVAL;
26269+ }
26270+
26271+ return err;
26272+}
26273+
26274+static int au_wbr_mfs_sec(substring_t *arg, char *str,
26275+ struct au_opt_wbr_create *create)
26276+{
26277+ int n, err;
26278+
26279+ err = 0;
027c5e7a 26280+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 26281+ create->mfs_second = n;
26282+ else {
4a4d8108 26283+ pr_err("bad integer in %s\n", str);
1facf9fc 26284+ err = -EINVAL;
26285+ }
26286+
26287+ return err;
26288+}
26289+
4a4d8108
AM
26290+static int noinline_for_stack
26291+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 26292+{
26293+ int err, e;
26294+ substring_t args[MAX_OPT_ARGS];
26295+
26296+ err = match_token(str, au_wbr_create_policy, args);
26297+ create->wbr_create = err;
26298+ switch (err) {
26299+ case AuWbrCreate_MFSRRV:
f2c43d5f 26300+ case AuWbrCreate_TDMFSV:
392086de 26301+ case AuWbrCreate_PMFSRRV:
1facf9fc 26302+ e = au_wbr_mfs_wmark(&args[0], str, create);
26303+ if (!e)
26304+ e = au_wbr_mfs_sec(&args[1], str, create);
26305+ if (unlikely(e))
26306+ err = e;
26307+ break;
26308+ case AuWbrCreate_MFSRR:
f2c43d5f 26309+ case AuWbrCreate_TDMFS:
392086de 26310+ case AuWbrCreate_PMFSRR:
1facf9fc 26311+ e = au_wbr_mfs_wmark(&args[0], str, create);
26312+ if (unlikely(e)) {
26313+ err = e;
26314+ break;
26315+ }
26316+ /*FALLTHROUGH*/
26317+ case AuWbrCreate_MFS:
26318+ case AuWbrCreate_PMFS:
027c5e7a 26319+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 26320+ break;
26321+ case AuWbrCreate_MFSV:
26322+ case AuWbrCreate_PMFSV:
26323+ e = au_wbr_mfs_sec(&args[0], str, create);
26324+ if (unlikely(e))
26325+ err = e;
26326+ break;
26327+ }
26328+
26329+ return err;
26330+}
26331+
26332+const char *au_optstr_wbr_create(int wbr_create)
26333+{
076b876e 26334+ return au_parser_pattern(wbr_create, au_wbr_create_policy);
1facf9fc 26335+}
26336+
26337+static match_table_t au_wbr_copyup_policy = {
26338+ {AuWbrCopyup_TDP, "tdp"},
26339+ {AuWbrCopyup_TDP, "top-down-parent"},
26340+ {AuWbrCopyup_BUP, "bup"},
26341+ {AuWbrCopyup_BUP, "bottom-up-parent"},
26342+ {AuWbrCopyup_BU, "bu"},
26343+ {AuWbrCopyup_BU, "bottom-up"},
26344+ {-1, NULL}
26345+};
26346+
4a4d8108 26347+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 26348+{
26349+ substring_t args[MAX_OPT_ARGS];
26350+
26351+ return match_token(str, au_wbr_copyup_policy, args);
26352+}
26353+
26354+const char *au_optstr_wbr_copyup(int wbr_copyup)
26355+{
076b876e 26356+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
1facf9fc 26357+}
26358+
26359+/* ---------------------------------------------------------------------- */
26360+
26361+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
26362+
26363+static void dump_opts(struct au_opts *opts)
26364+{
26365+#ifdef CONFIG_AUFS_DEBUG
26366+ /* reduce stack space */
26367+ union {
26368+ struct au_opt_add *add;
26369+ struct au_opt_del *del;
26370+ struct au_opt_mod *mod;
26371+ struct au_opt_xino *xino;
26372+ struct au_opt_xino_itrunc *xino_itrunc;
26373+ struct au_opt_wbr_create *create;
26374+ } u;
26375+ struct au_opt *opt;
26376+
26377+ opt = opts->opt;
26378+ while (opt->type != Opt_tail) {
26379+ switch (opt->type) {
26380+ case Opt_add:
26381+ u.add = &opt->add;
26382+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
26383+ u.add->bindex, u.add->pathname, u.add->perm,
26384+ u.add->path.dentry);
26385+ break;
26386+ case Opt_del:
26387+ case Opt_idel:
26388+ u.del = &opt->del;
26389+ AuDbg("del {%s, %p}\n",
26390+ u.del->pathname, u.del->h_path.dentry);
26391+ break;
26392+ case Opt_mod:
26393+ case Opt_imod:
26394+ u.mod = &opt->mod;
26395+ AuDbg("mod {%s, 0x%x, %p}\n",
26396+ u.mod->path, u.mod->perm, u.mod->h_root);
26397+ break;
26398+ case Opt_append:
26399+ u.add = &opt->add;
26400+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
26401+ u.add->bindex, u.add->pathname, u.add->perm,
26402+ u.add->path.dentry);
26403+ break;
26404+ case Opt_prepend:
26405+ u.add = &opt->add;
26406+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
26407+ u.add->bindex, u.add->pathname, u.add->perm,
26408+ u.add->path.dentry);
26409+ break;
26410+ case Opt_dirwh:
26411+ AuDbg("dirwh %d\n", opt->dirwh);
26412+ break;
26413+ case Opt_rdcache:
26414+ AuDbg("rdcache %d\n", opt->rdcache);
26415+ break;
26416+ case Opt_rdblk:
26417+ AuDbg("rdblk %u\n", opt->rdblk);
26418+ break;
dece6358
AM
26419+ case Opt_rdblk_def:
26420+ AuDbg("rdblk_def\n");
26421+ break;
1facf9fc 26422+ case Opt_rdhash:
26423+ AuDbg("rdhash %u\n", opt->rdhash);
26424+ break;
dece6358
AM
26425+ case Opt_rdhash_def:
26426+ AuDbg("rdhash_def\n");
26427+ break;
1facf9fc 26428+ case Opt_xino:
26429+ u.xino = &opt->xino;
523b37e3 26430+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 26431+ break;
26432+ case Opt_trunc_xino:
26433+ AuLabel(trunc_xino);
26434+ break;
26435+ case Opt_notrunc_xino:
26436+ AuLabel(notrunc_xino);
26437+ break;
26438+ case Opt_trunc_xino_path:
26439+ case Opt_itrunc_xino:
26440+ u.xino_itrunc = &opt->xino_itrunc;
26441+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
26442+ break;
1facf9fc 26443+ case Opt_noxino:
26444+ AuLabel(noxino);
26445+ break;
26446+ case Opt_trunc_xib:
26447+ AuLabel(trunc_xib);
26448+ break;
26449+ case Opt_notrunc_xib:
26450+ AuLabel(notrunc_xib);
26451+ break;
dece6358
AM
26452+ case Opt_shwh:
26453+ AuLabel(shwh);
26454+ break;
26455+ case Opt_noshwh:
26456+ AuLabel(noshwh);
26457+ break;
076b876e
AM
26458+ case Opt_dirperm1:
26459+ AuLabel(dirperm1);
26460+ break;
26461+ case Opt_nodirperm1:
26462+ AuLabel(nodirperm1);
26463+ break;
1facf9fc 26464+ case Opt_plink:
26465+ AuLabel(plink);
26466+ break;
26467+ case Opt_noplink:
26468+ AuLabel(noplink);
26469+ break;
26470+ case Opt_list_plink:
26471+ AuLabel(list_plink);
26472+ break;
26473+ case Opt_udba:
26474+ AuDbg("udba %d, %s\n",
26475+ opt->udba, au_optstr_udba(opt->udba));
26476+ break;
4a4d8108
AM
26477+ case Opt_dio:
26478+ AuLabel(dio);
26479+ break;
26480+ case Opt_nodio:
26481+ AuLabel(nodio);
26482+ break;
1facf9fc 26483+ case Opt_diropq_a:
26484+ AuLabel(diropq_a);
26485+ break;
26486+ case Opt_diropq_w:
26487+ AuLabel(diropq_w);
26488+ break;
26489+ case Opt_warn_perm:
26490+ AuLabel(warn_perm);
26491+ break;
26492+ case Opt_nowarn_perm:
26493+ AuLabel(nowarn_perm);
26494+ break;
1facf9fc 26495+ case Opt_verbose:
26496+ AuLabel(verbose);
26497+ break;
26498+ case Opt_noverbose:
26499+ AuLabel(noverbose);
26500+ break;
26501+ case Opt_sum:
26502+ AuLabel(sum);
26503+ break;
26504+ case Opt_nosum:
26505+ AuLabel(nosum);
26506+ break;
26507+ case Opt_wsum:
26508+ AuLabel(wsum);
26509+ break;
26510+ case Opt_wbr_create:
26511+ u.create = &opt->wbr_create;
26512+ AuDbg("create %d, %s\n", u.create->wbr_create,
26513+ au_optstr_wbr_create(u.create->wbr_create));
26514+ switch (u.create->wbr_create) {
26515+ case AuWbrCreate_MFSV:
26516+ case AuWbrCreate_PMFSV:
26517+ AuDbg("%d sec\n", u.create->mfs_second);
26518+ break;
26519+ case AuWbrCreate_MFSRR:
f2c43d5f 26520+ case AuWbrCreate_TDMFS:
1facf9fc 26521+ AuDbg("%llu watermark\n",
26522+ u.create->mfsrr_watermark);
26523+ break;
26524+ case AuWbrCreate_MFSRRV:
f2c43d5f 26525+ case AuWbrCreate_TDMFSV:
392086de 26526+ case AuWbrCreate_PMFSRRV:
1facf9fc 26527+ AuDbg("%llu watermark, %d sec\n",
26528+ u.create->mfsrr_watermark,
26529+ u.create->mfs_second);
26530+ break;
26531+ }
26532+ break;
26533+ case Opt_wbr_copyup:
26534+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
26535+ au_optstr_wbr_copyup(opt->wbr_copyup));
26536+ break;
076b876e
AM
26537+ case Opt_fhsm_sec:
26538+ AuDbg("fhsm_sec %u\n", opt->fhsm_second);
26539+ break;
8b6a4947
AM
26540+ case Opt_dirren:
26541+ AuLabel(dirren);
26542+ break;
26543+ case Opt_nodirren:
26544+ AuLabel(nodirren);
26545+ break;
c1595e42
JR
26546+ case Opt_acl:
26547+ AuLabel(acl);
26548+ break;
26549+ case Opt_noacl:
26550+ AuLabel(noacl);
26551+ break;
1facf9fc 26552+ default:
26553+ BUG();
26554+ }
26555+ opt++;
26556+ }
26557+#endif
26558+}
26559+
26560+void au_opts_free(struct au_opts *opts)
26561+{
26562+ struct au_opt *opt;
26563+
26564+ opt = opts->opt;
26565+ while (opt->type != Opt_tail) {
26566+ switch (opt->type) {
26567+ case Opt_add:
26568+ case Opt_append:
26569+ case Opt_prepend:
26570+ path_put(&opt->add.path);
26571+ break;
26572+ case Opt_del:
26573+ case Opt_idel:
26574+ path_put(&opt->del.h_path);
26575+ break;
26576+ case Opt_mod:
26577+ case Opt_imod:
26578+ dput(opt->mod.h_root);
26579+ break;
26580+ case Opt_xino:
26581+ fput(opt->xino.file);
26582+ break;
26583+ }
26584+ opt++;
26585+ }
26586+}
26587+
26588+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
26589+ aufs_bindex_t bindex)
26590+{
26591+ int err;
26592+ struct au_opt_add *add = &opt->add;
26593+ char *p;
26594+
26595+ add->bindex = bindex;
1e00d052 26596+ add->perm = AuBrPerm_RO;
1facf9fc 26597+ add->pathname = opt_str;
26598+ p = strchr(opt_str, '=');
26599+ if (p) {
26600+ *p++ = 0;
26601+ if (*p)
26602+ add->perm = br_perm_val(p);
26603+ }
26604+
26605+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
26606+ if (!err) {
26607+ if (!p) {
26608+ add->perm = AuBrPerm_RO;
26609+ if (au_test_fs_rr(add->path.dentry->d_sb))
26610+ add->perm = AuBrPerm_RR;
2121bcd9 26611+ else if (!bindex && !(sb_flags & SB_RDONLY))
1facf9fc 26612+ add->perm = AuBrPerm_RW;
26613+ }
26614+ opt->type = Opt_add;
26615+ goto out;
26616+ }
4a4d8108 26617+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 26618+ err = -EINVAL;
26619+
4f0767ce 26620+out:
1facf9fc 26621+ return err;
26622+}
26623+
26624+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
26625+{
26626+ int err;
26627+
26628+ del->pathname = args[0].from;
26629+ AuDbg("del path %s\n", del->pathname);
26630+
26631+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
26632+ if (unlikely(err))
4a4d8108 26633+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 26634+
26635+ return err;
26636+}
26637+
26638+#if 0 /* reserved for future use */
26639+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
26640+ struct au_opt_del *del, substring_t args[])
26641+{
26642+ int err;
26643+ struct dentry *root;
26644+
26645+ err = -EINVAL;
26646+ root = sb->s_root;
26647+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 26648+ if (bindex < 0 || au_sbbot(sb) < bindex) {
4a4d8108 26649+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 26650+ goto out;
26651+ }
26652+
26653+ err = 0;
26654+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
26655+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
26656+
4f0767ce 26657+out:
1facf9fc 26658+ aufs_read_unlock(root, !AuLock_IR);
26659+ return err;
26660+}
26661+#endif
26662+
4a4d8108
AM
26663+static int noinline_for_stack
26664+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 26665+{
26666+ int err;
26667+ struct path path;
26668+ char *p;
26669+
26670+ err = -EINVAL;
26671+ mod->path = args[0].from;
26672+ p = strchr(mod->path, '=');
26673+ if (unlikely(!p)) {
acd2b654 26674+ pr_err("no permission %s\n", args[0].from);
1facf9fc 26675+ goto out;
26676+ }
26677+
26678+ *p++ = 0;
26679+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
26680+ if (unlikely(err)) {
4a4d8108 26681+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 26682+ goto out;
26683+ }
26684+
26685+ mod->perm = br_perm_val(p);
26686+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
26687+ mod->h_root = dget(path.dentry);
26688+ path_put(&path);
26689+
4f0767ce 26690+out:
1facf9fc 26691+ return err;
26692+}
26693+
26694+#if 0 /* reserved for future use */
26695+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
26696+ struct au_opt_mod *mod, substring_t args[])
26697+{
26698+ int err;
26699+ struct dentry *root;
26700+
26701+ err = -EINVAL;
26702+ root = sb->s_root;
26703+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 26704+ if (bindex < 0 || au_sbbot(sb) < bindex) {
4a4d8108 26705+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 26706+ goto out;
26707+ }
26708+
26709+ err = 0;
26710+ mod->perm = br_perm_val(args[1].from);
26711+ AuDbg("mod path %s, perm 0x%x, %s\n",
26712+ mod->path, mod->perm, args[1].from);
26713+ mod->h_root = dget(au_h_dptr(root, bindex));
26714+
4f0767ce 26715+out:
1facf9fc 26716+ aufs_read_unlock(root, !AuLock_IR);
26717+ return err;
26718+}
26719+#endif
26720+
26721+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
26722+ substring_t args[])
26723+{
26724+ int err;
26725+ struct file *file;
26726+
26727+ file = au_xino_create(sb, args[0].from, /*silent*/0);
26728+ err = PTR_ERR(file);
26729+ if (IS_ERR(file))
26730+ goto out;
26731+
26732+ err = -EINVAL;
2000de60 26733+ if (unlikely(file->f_path.dentry->d_sb == sb)) {
1facf9fc 26734+ fput(file);
4a4d8108 26735+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 26736+ goto out;
26737+ }
26738+
26739+ err = 0;
26740+ xino->file = file;
26741+ xino->path = args[0].from;
26742+
4f0767ce 26743+out:
1facf9fc 26744+ return err;
26745+}
26746+
4a4d8108
AM
26747+static int noinline_for_stack
26748+au_opts_parse_xino_itrunc_path(struct super_block *sb,
26749+ struct au_opt_xino_itrunc *xino_itrunc,
26750+ substring_t args[])
1facf9fc 26751+{
26752+ int err;
5afbbe0d 26753+ aufs_bindex_t bbot, bindex;
1facf9fc 26754+ struct path path;
26755+ struct dentry *root;
26756+
26757+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
26758+ if (unlikely(err)) {
4a4d8108 26759+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 26760+ goto out;
26761+ }
26762+
26763+ xino_itrunc->bindex = -1;
26764+ root = sb->s_root;
26765+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d
AM
26766+ bbot = au_sbbot(sb);
26767+ for (bindex = 0; bindex <= bbot; bindex++) {
1facf9fc 26768+ if (au_h_dptr(root, bindex) == path.dentry) {
26769+ xino_itrunc->bindex = bindex;
26770+ break;
26771+ }
26772+ }
26773+ aufs_read_unlock(root, !AuLock_IR);
26774+ path_put(&path);
26775+
26776+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 26777+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 26778+ err = -EINVAL;
26779+ }
26780+
4f0767ce 26781+out:
1facf9fc 26782+ return err;
26783+}
26784+
26785+/* called without aufs lock */
26786+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
26787+{
26788+ int err, n, token;
26789+ aufs_bindex_t bindex;
26790+ unsigned char skipped;
26791+ struct dentry *root;
26792+ struct au_opt *opt, *opt_tail;
26793+ char *opt_str;
26794+ /* reduce the stack space */
26795+ union {
26796+ struct au_opt_xino_itrunc *xino_itrunc;
26797+ struct au_opt_wbr_create *create;
26798+ } u;
26799+ struct {
26800+ substring_t args[MAX_OPT_ARGS];
26801+ } *a;
26802+
26803+ err = -ENOMEM;
26804+ a = kmalloc(sizeof(*a), GFP_NOFS);
26805+ if (unlikely(!a))
26806+ goto out;
26807+
26808+ root = sb->s_root;
26809+ err = 0;
26810+ bindex = 0;
26811+ opt = opts->opt;
26812+ opt_tail = opt + opts->max_opt - 1;
26813+ opt->type = Opt_tail;
26814+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
26815+ err = -EINVAL;
26816+ skipped = 0;
26817+ token = match_token(opt_str, options, a->args);
26818+ switch (token) {
26819+ case Opt_br:
26820+ err = 0;
26821+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
26822+ && *opt_str) {
26823+ err = opt_add(opt, opt_str, opts->sb_flags,
26824+ bindex++);
26825+ if (unlikely(!err && ++opt > opt_tail)) {
26826+ err = -E2BIG;
26827+ break;
26828+ }
26829+ opt->type = Opt_tail;
26830+ skipped = 1;
26831+ }
26832+ break;
26833+ case Opt_add:
26834+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 26835+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26836+ break;
26837+ }
26838+ bindex = n;
26839+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
26840+ bindex);
26841+ if (!err)
26842+ opt->type = token;
26843+ break;
26844+ case Opt_append:
26845+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
26846+ /*dummy bindex*/1);
26847+ if (!err)
26848+ opt->type = token;
26849+ break;
26850+ case Opt_prepend:
26851+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
26852+ /*bindex*/0);
26853+ if (!err)
26854+ opt->type = token;
26855+ break;
26856+ case Opt_del:
26857+ err = au_opts_parse_del(&opt->del, a->args);
26858+ if (!err)
26859+ opt->type = token;
26860+ break;
26861+#if 0 /* reserved for future use */
26862+ case Opt_idel:
26863+ del->pathname = "(indexed)";
26864+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 26865+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26866+ break;
26867+ }
26868+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
26869+ if (!err)
26870+ opt->type = token;
26871+ break;
26872+#endif
26873+ case Opt_mod:
26874+ err = au_opts_parse_mod(&opt->mod, a->args);
26875+ if (!err)
26876+ opt->type = token;
26877+ break;
26878+#ifdef IMOD /* reserved for future use */
26879+ case Opt_imod:
26880+ u.mod->path = "(indexed)";
26881+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 26882+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26883+ break;
26884+ }
26885+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
26886+ if (!err)
26887+ opt->type = token;
26888+ break;
26889+#endif
26890+ case Opt_xino:
26891+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
26892+ if (!err)
26893+ opt->type = token;
26894+ break;
26895+
26896+ case Opt_trunc_xino_path:
26897+ err = au_opts_parse_xino_itrunc_path
26898+ (sb, &opt->xino_itrunc, a->args);
26899+ if (!err)
26900+ opt->type = token;
26901+ break;
26902+
26903+ case Opt_itrunc_xino:
26904+ u.xino_itrunc = &opt->xino_itrunc;
26905+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 26906+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26907+ break;
26908+ }
26909+ u.xino_itrunc->bindex = n;
26910+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 26911+ if (n < 0 || au_sbbot(sb) < n) {
4a4d8108 26912+ pr_err("out of bounds, %d\n", n);
1facf9fc 26913+ aufs_read_unlock(root, !AuLock_IR);
26914+ break;
26915+ }
26916+ aufs_read_unlock(root, !AuLock_IR);
26917+ err = 0;
26918+ opt->type = token;
26919+ break;
26920+
26921+ case Opt_dirwh:
26922+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
26923+ break;
26924+ err = 0;
26925+ opt->type = token;
26926+ break;
26927+
26928+ case Opt_rdcache:
027c5e7a
AM
26929+ if (unlikely(match_int(&a->args[0], &n))) {
26930+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26931+ break;
027c5e7a
AM
26932+ }
26933+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
26934+ pr_err("rdcache must be smaller than %d\n",
26935+ AUFS_RDCACHE_MAX);
26936+ break;
26937+ }
26938+ opt->rdcache = n;
1facf9fc 26939+ err = 0;
26940+ opt->type = token;
26941+ break;
26942+ case Opt_rdblk:
26943+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 26944+ || n < 0
1facf9fc 26945+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 26946+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26947+ break;
26948+ }
1308ab2a 26949+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
26950+ pr_err("rdblk must be larger than %d\n",
26951+ NAME_MAX);
1facf9fc 26952+ break;
26953+ }
26954+ opt->rdblk = n;
26955+ err = 0;
26956+ opt->type = token;
26957+ break;
26958+ case Opt_rdhash:
26959+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 26960+ || n < 0
1facf9fc 26961+ || n * sizeof(struct hlist_head)
26962+ > KMALLOC_MAX_SIZE)) {
4a4d8108 26963+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26964+ break;
26965+ }
26966+ opt->rdhash = n;
26967+ err = 0;
26968+ opt->type = token;
26969+ break;
26970+
26971+ case Opt_trunc_xino:
26972+ case Opt_notrunc_xino:
26973+ case Opt_noxino:
26974+ case Opt_trunc_xib:
26975+ case Opt_notrunc_xib:
dece6358
AM
26976+ case Opt_shwh:
26977+ case Opt_noshwh:
076b876e
AM
26978+ case Opt_dirperm1:
26979+ case Opt_nodirperm1:
1facf9fc 26980+ case Opt_plink:
26981+ case Opt_noplink:
26982+ case Opt_list_plink:
4a4d8108
AM
26983+ case Opt_dio:
26984+ case Opt_nodio:
1facf9fc 26985+ case Opt_diropq_a:
26986+ case Opt_diropq_w:
26987+ case Opt_warn_perm:
26988+ case Opt_nowarn_perm:
1facf9fc 26989+ case Opt_verbose:
26990+ case Opt_noverbose:
26991+ case Opt_sum:
26992+ case Opt_nosum:
26993+ case Opt_wsum:
dece6358
AM
26994+ case Opt_rdblk_def:
26995+ case Opt_rdhash_def:
8b6a4947
AM
26996+ case Opt_dirren:
26997+ case Opt_nodirren:
c1595e42
JR
26998+ case Opt_acl:
26999+ case Opt_noacl:
1facf9fc 27000+ err = 0;
27001+ opt->type = token;
27002+ break;
27003+
27004+ case Opt_udba:
27005+ opt->udba = udba_val(a->args[0].from);
27006+ if (opt->udba >= 0) {
27007+ err = 0;
27008+ opt->type = token;
27009+ } else
4a4d8108 27010+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 27011+ break;
27012+
27013+ case Opt_wbr_create:
27014+ u.create = &opt->wbr_create;
27015+ u.create->wbr_create
27016+ = au_wbr_create_val(a->args[0].from, u.create);
27017+ if (u.create->wbr_create >= 0) {
27018+ err = 0;
27019+ opt->type = token;
27020+ } else
4a4d8108 27021+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 27022+ break;
27023+ case Opt_wbr_copyup:
27024+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
27025+ if (opt->wbr_copyup >= 0) {
27026+ err = 0;
27027+ opt->type = token;
27028+ } else
4a4d8108 27029+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 27030+ break;
27031+
076b876e
AM
27032+ case Opt_fhsm_sec:
27033+ if (unlikely(match_int(&a->args[0], &n)
27034+ || n < 0)) {
27035+ pr_err("bad integer in %s\n", opt_str);
27036+ break;
27037+ }
27038+ if (sysaufs_brs) {
27039+ opt->fhsm_second = n;
27040+ opt->type = token;
27041+ } else
27042+ pr_warn("ignored %s\n", opt_str);
27043+ err = 0;
27044+ break;
27045+
1facf9fc 27046+ case Opt_ignore:
0c3ec466 27047+ pr_warn("ignored %s\n", opt_str);
1facf9fc 27048+ /*FALLTHROUGH*/
27049+ case Opt_ignore_silent:
27050+ skipped = 1;
27051+ err = 0;
27052+ break;
27053+ case Opt_err:
4a4d8108 27054+ pr_err("unknown option %s\n", opt_str);
1facf9fc 27055+ break;
27056+ }
27057+
27058+ if (!err && !skipped) {
27059+ if (unlikely(++opt > opt_tail)) {
27060+ err = -E2BIG;
27061+ opt--;
27062+ opt->type = Opt_tail;
27063+ break;
27064+ }
27065+ opt->type = Opt_tail;
27066+ }
27067+ }
27068+
9f237c51 27069+ au_kfree_rcu(a);
1facf9fc 27070+ dump_opts(opts);
27071+ if (unlikely(err))
27072+ au_opts_free(opts);
27073+
4f0767ce 27074+out:
1facf9fc 27075+ return err;
27076+}
27077+
27078+static int au_opt_wbr_create(struct super_block *sb,
27079+ struct au_opt_wbr_create *create)
27080+{
27081+ int err;
27082+ struct au_sbinfo *sbinfo;
27083+
dece6358
AM
27084+ SiMustWriteLock(sb);
27085+
1facf9fc 27086+ err = 1; /* handled */
27087+ sbinfo = au_sbi(sb);
27088+ if (sbinfo->si_wbr_create_ops->fin) {
27089+ err = sbinfo->si_wbr_create_ops->fin(sb);
27090+ if (!err)
27091+ err = 1;
27092+ }
27093+
27094+ sbinfo->si_wbr_create = create->wbr_create;
27095+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
27096+ switch (create->wbr_create) {
27097+ case AuWbrCreate_MFSRRV:
27098+ case AuWbrCreate_MFSRR:
f2c43d5f
AM
27099+ case AuWbrCreate_TDMFS:
27100+ case AuWbrCreate_TDMFSV:
392086de
AM
27101+ case AuWbrCreate_PMFSRR:
27102+ case AuWbrCreate_PMFSRRV:
1facf9fc 27103+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
27104+ /*FALLTHROUGH*/
27105+ case AuWbrCreate_MFS:
27106+ case AuWbrCreate_MFSV:
27107+ case AuWbrCreate_PMFS:
27108+ case AuWbrCreate_PMFSV:
e49829fe
JR
27109+ sbinfo->si_wbr_mfs.mfs_expire
27110+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 27111+ break;
27112+ }
27113+
27114+ if (sbinfo->si_wbr_create_ops->init)
27115+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
27116+
27117+ return err;
27118+}
27119+
27120+/*
27121+ * returns,
27122+ * plus: processed without an error
27123+ * zero: unprocessed
27124+ */
27125+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
27126+ struct au_opts *opts)
27127+{
27128+ int err;
27129+ struct au_sbinfo *sbinfo;
27130+
dece6358
AM
27131+ SiMustWriteLock(sb);
27132+
1facf9fc 27133+ err = 1; /* handled */
27134+ sbinfo = au_sbi(sb);
27135+ switch (opt->type) {
27136+ case Opt_udba:
27137+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
27138+ sbinfo->si_mntflags |= opt->udba;
27139+ opts->given_udba |= opt->udba;
27140+ break;
27141+
27142+ case Opt_plink:
27143+ au_opt_set(sbinfo->si_mntflags, PLINK);
27144+ break;
27145+ case Opt_noplink:
27146+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 27147+ au_plink_put(sb, /*verbose*/1);
1facf9fc 27148+ au_opt_clr(sbinfo->si_mntflags, PLINK);
27149+ break;
27150+ case Opt_list_plink:
27151+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
27152+ au_plink_list(sb);
27153+ break;
27154+
4a4d8108
AM
27155+ case Opt_dio:
27156+ au_opt_set(sbinfo->si_mntflags, DIO);
27157+ au_fset_opts(opts->flags, REFRESH_DYAOP);
27158+ break;
27159+ case Opt_nodio:
27160+ au_opt_clr(sbinfo->si_mntflags, DIO);
27161+ au_fset_opts(opts->flags, REFRESH_DYAOP);
27162+ break;
27163+
076b876e
AM
27164+ case Opt_fhsm_sec:
27165+ au_fhsm_set(sbinfo, opt->fhsm_second);
27166+ break;
27167+
1facf9fc 27168+ case Opt_diropq_a:
27169+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
27170+ break;
27171+ case Opt_diropq_w:
27172+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
27173+ break;
27174+
27175+ case Opt_warn_perm:
27176+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
27177+ break;
27178+ case Opt_nowarn_perm:
27179+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
27180+ break;
27181+
1facf9fc 27182+ case Opt_verbose:
27183+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
27184+ break;
27185+ case Opt_noverbose:
27186+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
27187+ break;
27188+
27189+ case Opt_sum:
27190+ au_opt_set(sbinfo->si_mntflags, SUM);
27191+ break;
27192+ case Opt_wsum:
27193+ au_opt_clr(sbinfo->si_mntflags, SUM);
27194+ au_opt_set(sbinfo->si_mntflags, SUM_W);
27195+ case Opt_nosum:
27196+ au_opt_clr(sbinfo->si_mntflags, SUM);
27197+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
27198+ break;
27199+
27200+ case Opt_wbr_create:
27201+ err = au_opt_wbr_create(sb, &opt->wbr_create);
27202+ break;
27203+ case Opt_wbr_copyup:
27204+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
27205+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
27206+ break;
27207+
27208+ case Opt_dirwh:
27209+ sbinfo->si_dirwh = opt->dirwh;
27210+ break;
27211+
27212+ case Opt_rdcache:
e49829fe
JR
27213+ sbinfo->si_rdcache
27214+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 27215+ break;
27216+ case Opt_rdblk:
27217+ sbinfo->si_rdblk = opt->rdblk;
27218+ break;
dece6358
AM
27219+ case Opt_rdblk_def:
27220+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
27221+ break;
1facf9fc 27222+ case Opt_rdhash:
27223+ sbinfo->si_rdhash = opt->rdhash;
27224+ break;
dece6358
AM
27225+ case Opt_rdhash_def:
27226+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
27227+ break;
27228+
27229+ case Opt_shwh:
27230+ au_opt_set(sbinfo->si_mntflags, SHWH);
27231+ break;
27232+ case Opt_noshwh:
27233+ au_opt_clr(sbinfo->si_mntflags, SHWH);
27234+ break;
1facf9fc 27235+
076b876e
AM
27236+ case Opt_dirperm1:
27237+ au_opt_set(sbinfo->si_mntflags, DIRPERM1);
27238+ break;
27239+ case Opt_nodirperm1:
27240+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
27241+ break;
27242+
1facf9fc 27243+ case Opt_trunc_xino:
27244+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
27245+ break;
27246+ case Opt_notrunc_xino:
27247+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
27248+ break;
27249+
27250+ case Opt_trunc_xino_path:
27251+ case Opt_itrunc_xino:
acd2b654
AM
27252+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex,
27253+ /*idx_begin*/0);
1facf9fc 27254+ if (!err)
27255+ err = 1;
27256+ break;
27257+
27258+ case Opt_trunc_xib:
27259+ au_fset_opts(opts->flags, TRUNC_XIB);
27260+ break;
27261+ case Opt_notrunc_xib:
27262+ au_fclr_opts(opts->flags, TRUNC_XIB);
27263+ break;
27264+
8b6a4947
AM
27265+ case Opt_dirren:
27266+ err = 1;
27267+ if (!au_opt_test(sbinfo->si_mntflags, DIRREN)) {
27268+ err = au_dr_opt_set(sb);
27269+ if (!err)
27270+ err = 1;
27271+ }
27272+ if (err == 1)
27273+ au_opt_set(sbinfo->si_mntflags, DIRREN);
27274+ break;
27275+ case Opt_nodirren:
27276+ err = 1;
27277+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) {
27278+ err = au_dr_opt_clr(sb, au_ftest_opts(opts->flags,
27279+ DR_FLUSHED));
27280+ if (!err)
27281+ err = 1;
27282+ }
27283+ if (err == 1)
27284+ au_opt_clr(sbinfo->si_mntflags, DIRREN);
27285+ break;
27286+
c1595e42 27287+ case Opt_acl:
2121bcd9 27288+ sb->s_flags |= SB_POSIXACL;
c1595e42
JR
27289+ break;
27290+ case Opt_noacl:
2121bcd9 27291+ sb->s_flags &= ~SB_POSIXACL;
c1595e42
JR
27292+ break;
27293+
1facf9fc 27294+ default:
27295+ err = 0;
27296+ break;
27297+ }
27298+
27299+ return err;
27300+}
27301+
27302+/*
27303+ * returns tri-state.
27304+ * plus: processed without an error
27305+ * zero: unprocessed
27306+ * minus: error
27307+ */
27308+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
27309+ struct au_opts *opts)
27310+{
27311+ int err, do_refresh;
27312+
27313+ err = 0;
27314+ switch (opt->type) {
27315+ case Opt_append:
5afbbe0d 27316+ opt->add.bindex = au_sbbot(sb) + 1;
1facf9fc 27317+ if (opt->add.bindex < 0)
27318+ opt->add.bindex = 0;
27319+ goto add;
27320+ case Opt_prepend:
27321+ opt->add.bindex = 0;
f6b6e03d 27322+ add: /* indented label */
1facf9fc 27323+ case Opt_add:
27324+ err = au_br_add(sb, &opt->add,
27325+ au_ftest_opts(opts->flags, REMOUNT));
27326+ if (!err) {
27327+ err = 1;
027c5e7a 27328+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 27329+ }
27330+ break;
27331+
27332+ case Opt_del:
27333+ case Opt_idel:
27334+ err = au_br_del(sb, &opt->del,
27335+ au_ftest_opts(opts->flags, REMOUNT));
27336+ if (!err) {
27337+ err = 1;
27338+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 27339+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 27340+ }
27341+ break;
27342+
27343+ case Opt_mod:
27344+ case Opt_imod:
27345+ err = au_br_mod(sb, &opt->mod,
27346+ au_ftest_opts(opts->flags, REMOUNT),
27347+ &do_refresh);
27348+ if (!err) {
27349+ err = 1;
027c5e7a
AM
27350+ if (do_refresh)
27351+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 27352+ }
27353+ break;
27354+ }
1facf9fc 27355+ return err;
27356+}
27357+
27358+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
27359+ struct au_opt_xino **opt_xino,
27360+ struct au_opts *opts)
27361+{
27362+ int err;
1facf9fc 27363+
27364+ err = 0;
27365+ switch (opt->type) {
27366+ case Opt_xino:
062440b3
AM
27367+ err = au_xino_set(sb, &opt->xino,
27368+ !!au_ftest_opts(opts->flags, REMOUNT));
27369+ if (unlikely(err))
27370+ break;
27371+
27372+ *opt_xino = &opt->xino;
1facf9fc 27373+ break;
27374+
27375+ case Opt_noxino:
27376+ au_xino_clr(sb);
1facf9fc 27377+ *opt_xino = (void *)-1;
27378+ break;
27379+ }
27380+
27381+ return err;
27382+}
27383+
27384+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
27385+ unsigned int pending)
27386+{
076b876e 27387+ int err, fhsm;
5afbbe0d 27388+ aufs_bindex_t bindex, bbot;
79b8bda9 27389+ unsigned char do_plink, skip, do_free, can_no_dreval;
1facf9fc 27390+ struct au_branch *br;
27391+ struct au_wbr *wbr;
79b8bda9 27392+ struct dentry *root, *dentry;
1facf9fc 27393+ struct inode *dir, *h_dir;
27394+ struct au_sbinfo *sbinfo;
27395+ struct au_hinode *hdir;
27396+
dece6358
AM
27397+ SiMustAnyLock(sb);
27398+
1facf9fc 27399+ sbinfo = au_sbi(sb);
27400+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
27401+
2121bcd9 27402+ if (!(sb_flags & SB_RDONLY)) {
dece6358 27403+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 27404+ pr_warn("first branch should be rw\n");
dece6358 27405+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
febd17d6 27406+ pr_warn_once("shwh should be used with ro\n");
dece6358 27407+ }
1facf9fc 27408+
4a4d8108 27409+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 27410+ && !au_opt_test(sbinfo->si_mntflags, XINO))
febd17d6 27411+ pr_warn_once("udba=*notify requires xino\n");
1facf9fc 27412+
076b876e 27413+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
febd17d6
JR
27414+ pr_warn_once("dirperm1 breaks the protection"
27415+ " by the permission bits on the lower branch\n");
076b876e 27416+
1facf9fc 27417+ err = 0;
076b876e 27418+ fhsm = 0;
1facf9fc 27419+ root = sb->s_root;
5527c038 27420+ dir = d_inode(root);
1facf9fc 27421+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
79b8bda9
AM
27422+ can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending),
27423+ UDBA_NONE);
5afbbe0d
AM
27424+ bbot = au_sbbot(sb);
27425+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
1facf9fc 27426+ skip = 0;
27427+ h_dir = au_h_iptr(dir, bindex);
27428+ br = au_sbr(sb, bindex);
1facf9fc 27429+
c1595e42
JR
27430+ if ((br->br_perm & AuBrAttr_ICEX)
27431+ && !h_dir->i_op->listxattr)
27432+ br->br_perm &= ~AuBrAttr_ICEX;
27433+#if 0
27434+ if ((br->br_perm & AuBrAttr_ICEX_SEC)
2121bcd9 27435+ && (au_br_sb(br)->s_flags & SB_NOSEC))
c1595e42
JR
27436+ br->br_perm &= ~AuBrAttr_ICEX_SEC;
27437+#endif
27438+
27439+ do_free = 0;
1facf9fc 27440+ wbr = br->br_wbr;
27441+ if (wbr)
27442+ wbr_wh_read_lock(wbr);
27443+
1e00d052 27444+ if (!au_br_writable(br->br_perm)) {
1facf9fc 27445+ do_free = !!wbr;
27446+ skip = (!wbr
27447+ || (!wbr->wbr_whbase
27448+ && !wbr->wbr_plink
27449+ && !wbr->wbr_orph));
1e00d052 27450+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 27451+ /* skip = (!br->br_whbase && !br->br_orph); */
27452+ skip = (!wbr || !wbr->wbr_whbase);
27453+ if (skip && wbr) {
27454+ if (do_plink)
27455+ skip = !!wbr->wbr_plink;
27456+ else
27457+ skip = !wbr->wbr_plink;
27458+ }
1e00d052 27459+ } else {
1facf9fc 27460+ /* skip = (br->br_whbase && br->br_ohph); */
27461+ skip = (wbr && wbr->wbr_whbase);
27462+ if (skip) {
27463+ if (do_plink)
27464+ skip = !!wbr->wbr_plink;
27465+ else
27466+ skip = !wbr->wbr_plink;
27467+ }
1facf9fc 27468+ }
27469+ if (wbr)
27470+ wbr_wh_read_unlock(wbr);
27471+
79b8bda9
AM
27472+ if (can_no_dreval) {
27473+ dentry = br->br_path.dentry;
27474+ spin_lock(&dentry->d_lock);
27475+ if (dentry->d_flags &
27476+ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE))
27477+ can_no_dreval = 0;
27478+ spin_unlock(&dentry->d_lock);
27479+ }
27480+
076b876e
AM
27481+ if (au_br_fhsm(br->br_perm)) {
27482+ fhsm++;
27483+ AuDebugOn(!br->br_fhsm);
27484+ }
27485+
1facf9fc 27486+ if (skip)
27487+ continue;
27488+
27489+ hdir = au_hi(dir, bindex);
5afbbe0d 27490+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 27491+ if (wbr)
27492+ wbr_wh_write_lock(wbr);
86dc4139 27493+ err = au_wh_init(br, sb);
1facf9fc 27494+ if (wbr)
27495+ wbr_wh_write_unlock(wbr);
5afbbe0d 27496+ au_hn_inode_unlock(hdir);
1facf9fc 27497+
27498+ if (!err && do_free) {
9f237c51 27499+ au_kfree_rcu(wbr);
1facf9fc 27500+ br->br_wbr = NULL;
27501+ }
27502+ }
27503+
79b8bda9
AM
27504+ if (can_no_dreval)
27505+ au_fset_si(sbinfo, NO_DREVAL);
27506+ else
27507+ au_fclr_si(sbinfo, NO_DREVAL);
27508+
c1595e42 27509+ if (fhsm >= 2) {
076b876e 27510+ au_fset_si(sbinfo, FHSM);
5afbbe0d 27511+ for (bindex = bbot; bindex >= 0; bindex--) {
c1595e42
JR
27512+ br = au_sbr(sb, bindex);
27513+ if (au_br_fhsm(br->br_perm)) {
27514+ au_fhsm_set_bottom(sb, bindex);
27515+ break;
27516+ }
27517+ }
27518+ } else {
076b876e 27519+ au_fclr_si(sbinfo, FHSM);
c1595e42
JR
27520+ au_fhsm_set_bottom(sb, -1);
27521+ }
076b876e 27522+
1facf9fc 27523+ return err;
27524+}
27525+
27526+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
27527+{
27528+ int err;
27529+ unsigned int tmp;
5afbbe0d 27530+ aufs_bindex_t bindex, bbot;
1facf9fc 27531+ struct au_opt *opt;
27532+ struct au_opt_xino *opt_xino, xino;
27533+ struct au_sbinfo *sbinfo;
027c5e7a 27534+ struct au_branch *br;
076b876e 27535+ struct inode *dir;
1facf9fc 27536+
dece6358
AM
27537+ SiMustWriteLock(sb);
27538+
1facf9fc 27539+ err = 0;
27540+ opt_xino = NULL;
27541+ opt = opts->opt;
27542+ while (err >= 0 && opt->type != Opt_tail)
27543+ err = au_opt_simple(sb, opt++, opts);
27544+ if (err > 0)
27545+ err = 0;
27546+ else if (unlikely(err < 0))
27547+ goto out;
27548+
27549+ /* disable xino and udba temporary */
27550+ sbinfo = au_sbi(sb);
27551+ tmp = sbinfo->si_mntflags;
27552+ au_opt_clr(sbinfo->si_mntflags, XINO);
27553+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
27554+
27555+ opt = opts->opt;
27556+ while (err >= 0 && opt->type != Opt_tail)
27557+ err = au_opt_br(sb, opt++, opts);
27558+ if (err > 0)
27559+ err = 0;
27560+ else if (unlikely(err < 0))
27561+ goto out;
27562+
5afbbe0d
AM
27563+ bbot = au_sbbot(sb);
27564+ if (unlikely(bbot < 0)) {
1facf9fc 27565+ err = -EINVAL;
4a4d8108 27566+ pr_err("no branches\n");
1facf9fc 27567+ goto out;
27568+ }
27569+
27570+ if (au_opt_test(tmp, XINO))
27571+ au_opt_set(sbinfo->si_mntflags, XINO);
27572+ opt = opts->opt;
27573+ while (!err && opt->type != Opt_tail)
27574+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
27575+ if (unlikely(err))
27576+ goto out;
27577+
27578+ err = au_opts_verify(sb, sb->s_flags, tmp);
27579+ if (unlikely(err))
27580+ goto out;
27581+
27582+ /* restore xino */
27583+ if (au_opt_test(tmp, XINO) && !opt_xino) {
27584+ xino.file = au_xino_def(sb);
27585+ err = PTR_ERR(xino.file);
27586+ if (IS_ERR(xino.file))
27587+ goto out;
27588+
27589+ err = au_xino_set(sb, &xino, /*remount*/0);
27590+ fput(xino.file);
27591+ if (unlikely(err))
27592+ goto out;
27593+ }
27594+
27595+ /* restore udba */
027c5e7a 27596+ tmp &= AuOptMask_UDBA;
1facf9fc 27597+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a 27598+ sbinfo->si_mntflags |= tmp;
5afbbe0d
AM
27599+ bbot = au_sbbot(sb);
27600+ for (bindex = 0; bindex <= bbot; bindex++) {
027c5e7a
AM
27601+ br = au_sbr(sb, bindex);
27602+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
27603+ if (unlikely(err))
27604+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
27605+ bindex, err);
27606+ /* go on even if err */
27607+ }
4a4d8108 27608+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
5527c038 27609+ dir = d_inode(sb->s_root);
4a4d8108 27610+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 27611+ }
27612+
4f0767ce 27613+out:
1facf9fc 27614+ return err;
27615+}
27616+
27617+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
27618+{
27619+ int err, rerr;
79b8bda9 27620+ unsigned char no_dreval;
1facf9fc 27621+ struct inode *dir;
27622+ struct au_opt_xino *opt_xino;
27623+ struct au_opt *opt;
27624+ struct au_sbinfo *sbinfo;
27625+
dece6358
AM
27626+ SiMustWriteLock(sb);
27627+
8b6a4947
AM
27628+ err = au_dr_opt_flush(sb);
27629+ if (unlikely(err))
27630+ goto out;
27631+ au_fset_opts(opts->flags, DR_FLUSHED);
27632+
5527c038 27633+ dir = d_inode(sb->s_root);
1facf9fc 27634+ sbinfo = au_sbi(sb);
1facf9fc 27635+ opt_xino = NULL;
27636+ opt = opts->opt;
27637+ while (err >= 0 && opt->type != Opt_tail) {
27638+ err = au_opt_simple(sb, opt, opts);
27639+ if (!err)
27640+ err = au_opt_br(sb, opt, opts);
27641+ if (!err)
27642+ err = au_opt_xino(sb, opt, &opt_xino, opts);
27643+ opt++;
27644+ }
27645+ if (err > 0)
27646+ err = 0;
27647+ AuTraceErr(err);
27648+ /* go on even err */
27649+
79b8bda9 27650+ no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
1facf9fc 27651+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
27652+ if (unlikely(rerr && !err))
27653+ err = rerr;
27654+
79b8bda9 27655+ if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
b95c5147 27656+ au_fset_opts(opts->flags, REFRESH_IDOP);
79b8bda9 27657+
1facf9fc 27658+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
27659+ rerr = au_xib_trunc(sb);
27660+ if (unlikely(rerr && !err))
27661+ err = rerr;
27662+ }
27663+
27664+ /* will be handled by the caller */
027c5e7a 27665+ if (!au_ftest_opts(opts->flags, REFRESH)
79b8bda9
AM
27666+ && (opts->given_udba
27667+ || au_opt_test(sbinfo->si_mntflags, XINO)
b95c5147 27668+ || au_ftest_opts(opts->flags, REFRESH_IDOP)
79b8bda9 27669+ ))
027c5e7a 27670+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 27671+
27672+ AuDbg("status 0x%x\n", opts->flags);
8b6a4947
AM
27673+
27674+out:
1facf9fc 27675+ return err;
27676+}
27677+
27678+/* ---------------------------------------------------------------------- */
27679+
27680+unsigned int au_opt_udba(struct super_block *sb)
27681+{
27682+ return au_mntflags(sb) & AuOptMask_UDBA;
27683+}
7f207e10
AM
27684diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
27685--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
eca801bf 27686+++ linux/fs/aufs/opts.h 2019-05-06 09:03:04.820143837 +0200
062440b3
AM
27687@@ -0,0 +1,225 @@
27688+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 27689+/*
ba1aed25 27690+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 27691+ *
27692+ * This program, aufs is free software; you can redistribute it and/or modify
27693+ * it under the terms of the GNU General Public License as published by
27694+ * the Free Software Foundation; either version 2 of the License, or
27695+ * (at your option) any later version.
dece6358
AM
27696+ *
27697+ * This program is distributed in the hope that it will be useful,
27698+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27699+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27700+ * GNU General Public License for more details.
27701+ *
27702+ * You should have received a copy of the GNU General Public License
523b37e3 27703+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27704+ */
27705+
27706+/*
27707+ * mount options/flags
27708+ */
27709+
27710+#ifndef __AUFS_OPTS_H__
27711+#define __AUFS_OPTS_H__
27712+
27713+#ifdef __KERNEL__
27714+
dece6358 27715+#include <linux/path.h>
1facf9fc 27716+
dece6358 27717+struct file;
dece6358 27718+
1facf9fc 27719+/* ---------------------------------------------------------------------- */
27720+
27721+/* mount flags */
27722+#define AuOpt_XINO 1 /* external inode number bitmap
27723+ and translation table */
27724+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
27725+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
27726+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 27727+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
27728+#define AuOpt_SHWH (1 << 5) /* show whiteout */
27729+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
076b876e
AM
27730+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
27731+ bits */
dece6358
AM
27732+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
27733+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
27734+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
27735+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
eca801bf 27736+#define AuOpt_VERBOSE (1 << 13) /* print the cause of error */
4a4d8108 27737+#define AuOpt_DIO (1 << 14) /* direct io */
8b6a4947 27738+#define AuOpt_DIRREN (1 << 15) /* directory rename */
1facf9fc 27739+
4a4d8108
AM
27740+#ifndef CONFIG_AUFS_HNOTIFY
27741+#undef AuOpt_UDBA_HNOTIFY
27742+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 27743+#endif
8b6a4947
AM
27744+#ifndef CONFIG_AUFS_DIRREN
27745+#undef AuOpt_DIRREN
27746+#define AuOpt_DIRREN 0
27747+#endif
dece6358
AM
27748+#ifndef CONFIG_AUFS_SHWH
27749+#undef AuOpt_SHWH
27750+#define AuOpt_SHWH 0
27751+#endif
1facf9fc 27752+
27753+#define AuOpt_Def (AuOpt_XINO \
27754+ | AuOpt_UDBA_REVAL \
27755+ | AuOpt_PLINK \
27756+ /* | AuOpt_DIRPERM1 */ \
27757+ | AuOpt_WARN_PERM)
27758+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
27759+ | AuOpt_UDBA_REVAL \
4a4d8108 27760+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 27761+
27762+#define au_opt_test(flags, name) (flags & AuOpt_##name)
27763+#define au_opt_set(flags, name) do { \
27764+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
27765+ ((flags) |= AuOpt_##name); \
27766+} while (0)
27767+#define au_opt_set_udba(flags, name) do { \
27768+ (flags) &= ~AuOptMask_UDBA; \
27769+ ((flags) |= AuOpt_##name); \
27770+} while (0)
7f207e10
AM
27771+#define au_opt_clr(flags, name) do { \
27772+ ((flags) &= ~AuOpt_##name); \
27773+} while (0)
1facf9fc 27774+
e49829fe
JR
27775+static inline unsigned int au_opts_plink(unsigned int mntflags)
27776+{
27777+#ifdef CONFIG_PROC_FS
27778+ return mntflags;
27779+#else
27780+ return mntflags & ~AuOpt_PLINK;
27781+#endif
27782+}
27783+
1facf9fc 27784+/* ---------------------------------------------------------------------- */
27785+
27786+/* policies to select one among multiple writable branches */
27787+enum {
27788+ AuWbrCreate_TDP, /* top down parent */
27789+ AuWbrCreate_RR, /* round robin */
27790+ AuWbrCreate_MFS, /* most free space */
27791+ AuWbrCreate_MFSV, /* mfs with seconds */
27792+ AuWbrCreate_MFSRR, /* mfs then rr */
27793+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
f2c43d5f
AM
27794+ AuWbrCreate_TDMFS, /* top down regardless parent and mfs */
27795+ AuWbrCreate_TDMFSV, /* top down regardless parent and mfs */
1facf9fc 27796+ AuWbrCreate_PMFS, /* parent and mfs */
27797+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
27798+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
27799+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 27800+
27801+ AuWbrCreate_Def = AuWbrCreate_TDP
27802+};
27803+
27804+enum {
27805+ AuWbrCopyup_TDP, /* top down parent */
27806+ AuWbrCopyup_BUP, /* bottom up parent */
27807+ AuWbrCopyup_BU, /* bottom up */
27808+
27809+ AuWbrCopyup_Def = AuWbrCopyup_TDP
27810+};
27811+
27812+/* ---------------------------------------------------------------------- */
27813+
27814+struct au_opt_add {
27815+ aufs_bindex_t bindex;
27816+ char *pathname;
27817+ int perm;
27818+ struct path path;
27819+};
27820+
27821+struct au_opt_del {
27822+ char *pathname;
27823+ struct path h_path;
27824+};
27825+
27826+struct au_opt_mod {
27827+ char *path;
27828+ int perm;
27829+ struct dentry *h_root;
27830+};
27831+
27832+struct au_opt_xino {
27833+ char *path;
27834+ struct file *file;
27835+};
27836+
27837+struct au_opt_xino_itrunc {
27838+ aufs_bindex_t bindex;
27839+};
27840+
27841+struct au_opt_wbr_create {
27842+ int wbr_create;
27843+ int mfs_second;
27844+ unsigned long long mfsrr_watermark;
27845+};
27846+
27847+struct au_opt {
27848+ int type;
27849+ union {
27850+ struct au_opt_xino xino;
27851+ struct au_opt_xino_itrunc xino_itrunc;
27852+ struct au_opt_add add;
27853+ struct au_opt_del del;
27854+ struct au_opt_mod mod;
27855+ int dirwh;
27856+ int rdcache;
27857+ unsigned int rdblk;
27858+ unsigned int rdhash;
27859+ int udba;
27860+ struct au_opt_wbr_create wbr_create;
27861+ int wbr_copyup;
076b876e 27862+ unsigned int fhsm_second;
1facf9fc 27863+ };
27864+};
27865+
27866+/* opts flags */
27867+#define AuOpts_REMOUNT 1
027c5e7a
AM
27868+#define AuOpts_REFRESH (1 << 1)
27869+#define AuOpts_TRUNC_XIB (1 << 2)
27870+#define AuOpts_REFRESH_DYAOP (1 << 3)
b95c5147 27871+#define AuOpts_REFRESH_IDOP (1 << 4)
8b6a4947 27872+#define AuOpts_DR_FLUSHED (1 << 5)
1facf9fc 27873+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
27874+#define au_fset_opts(flags, name) \
27875+ do { (flags) |= AuOpts_##name; } while (0)
27876+#define au_fclr_opts(flags, name) \
27877+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 27878+
8b6a4947
AM
27879+#ifndef CONFIG_AUFS_DIRREN
27880+#undef AuOpts_DR_FLUSHED
27881+#define AuOpts_DR_FLUSHED 0
27882+#endif
27883+
1facf9fc 27884+struct au_opts {
27885+ struct au_opt *opt;
27886+ int max_opt;
27887+
27888+ unsigned int given_udba;
27889+ unsigned int flags;
27890+ unsigned long sb_flags;
27891+};
27892+
27893+/* ---------------------------------------------------------------------- */
27894+
7e9cd9fe 27895+/* opts.c */
076b876e 27896+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
1facf9fc 27897+const char *au_optstr_udba(int udba);
27898+const char *au_optstr_wbr_copyup(int wbr_copyup);
27899+const char *au_optstr_wbr_create(int wbr_create);
27900+
27901+void au_opts_free(struct au_opts *opts);
3c1bdaff 27902+struct super_block;
1facf9fc 27903+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
27904+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
27905+ unsigned int pending);
27906+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
27907+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
27908+
27909+unsigned int au_opt_udba(struct super_block *sb);
27910+
1facf9fc 27911+#endif /* __KERNEL__ */
27912+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
27913diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
27914--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 27915+++ linux/fs/aufs/plink.c 2019-03-05 12:13:00.142557771 +0100
062440b3 27916@@ -0,0 +1,516 @@
cd7a4cd9 27917+// SPDX-License-Identifier: GPL-2.0
1facf9fc 27918+/*
ba1aed25 27919+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 27920+ *
27921+ * This program, aufs is free software; you can redistribute it and/or modify
27922+ * it under the terms of the GNU General Public License as published by
27923+ * the Free Software Foundation; either version 2 of the License, or
27924+ * (at your option) any later version.
dece6358
AM
27925+ *
27926+ * This program is distributed in the hope that it will be useful,
27927+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27928+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27929+ * GNU General Public License for more details.
27930+ *
27931+ * You should have received a copy of the GNU General Public License
523b37e3 27932+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27933+ */
27934+
27935+/*
27936+ * pseudo-link
27937+ */
27938+
27939+#include "aufs.h"
27940+
27941+/*
e49829fe 27942+ * the pseudo-link maintenance mode.
1facf9fc 27943+ * during a user process maintains the pseudo-links,
27944+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
27945+ *
27946+ * Flags
27947+ * NOPLM:
27948+ * For entry functions which will handle plink, and i_mutex is already held
27949+ * in VFS.
27950+ * They cannot wait and should return an error at once.
27951+ * Callers has to check the error.
27952+ * NOPLMW:
27953+ * For entry functions which will handle plink, but i_mutex is not held
27954+ * in VFS.
27955+ * They can wait the plink maintenance mode to finish.
27956+ *
27957+ * They behave like F_SETLK and F_SETLKW.
27958+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 27959+ */
e49829fe
JR
27960+
27961+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 27962+{
e49829fe
JR
27963+ int err;
27964+ pid_t pid, ppid;
f0c0a007 27965+ struct task_struct *parent, *prev;
e49829fe 27966+ struct au_sbinfo *sbi;
dece6358
AM
27967+
27968+ SiMustAnyLock(sb);
27969+
e49829fe
JR
27970+ err = 0;
27971+ if (!au_opt_test(au_mntflags(sb), PLINK))
27972+ goto out;
27973+
27974+ sbi = au_sbi(sb);
27975+ pid = sbi->si_plink_maint_pid;
27976+ if (!pid || pid == current->pid)
27977+ goto out;
27978+
27979+ /* todo: it highly depends upon /sbin/mount.aufs */
f0c0a007
AM
27980+ prev = NULL;
27981+ parent = current;
27982+ ppid = 0;
e49829fe 27983+ rcu_read_lock();
f0c0a007
AM
27984+ while (1) {
27985+ parent = rcu_dereference(parent->real_parent);
27986+ if (parent == prev)
27987+ break;
27988+ ppid = task_pid_vnr(parent);
27989+ if (pid == ppid) {
27990+ rcu_read_unlock();
27991+ goto out;
27992+ }
27993+ prev = parent;
27994+ }
e49829fe 27995+ rcu_read_unlock();
e49829fe
JR
27996+
27997+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
27998+ /* if there is no i_mutex lock in VFS, we don't need to wait */
27999+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
28000+ while (sbi->si_plink_maint_pid) {
28001+ si_read_unlock(sb);
28002+ /* gave up wake_up_bit() */
28003+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
28004+
28005+ if (au_ftest_lock(flags, FLUSH))
28006+ au_nwt_flush(&sbi->si_nowait);
28007+ si_noflush_read_lock(sb);
28008+ }
28009+ } else if (au_ftest_lock(flags, NOPLM)) {
28010+ AuDbg("ppid %d, pid %d\n", ppid, pid);
28011+ err = -EAGAIN;
28012+ }
28013+
28014+out:
28015+ return err;
4a4d8108
AM
28016+}
28017+
e49829fe 28018+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 28019+{
4a4d8108 28020+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 28021+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 28022+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 28023+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
28024+}
28025+
e49829fe 28026+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
28027+{
28028+ int err;
4a4d8108
AM
28029+ struct au_sbinfo *sbinfo;
28030+
28031+ err = 0;
4a4d8108
AM
28032+ sbinfo = au_sbi(sb);
28033+ /* make sure i am the only one in this fs */
e49829fe
JR
28034+ si_write_lock(sb, AuLock_FLUSH);
28035+ if (au_opt_test(au_mntflags(sb), PLINK)) {
28036+ spin_lock(&sbinfo->si_plink_maint_lock);
28037+ if (!sbinfo->si_plink_maint_pid)
28038+ sbinfo->si_plink_maint_pid = current->pid;
28039+ else
28040+ err = -EBUSY;
28041+ spin_unlock(&sbinfo->si_plink_maint_lock);
28042+ }
4a4d8108
AM
28043+ si_write_unlock(sb);
28044+
28045+ return err;
1facf9fc 28046+}
28047+
28048+/* ---------------------------------------------------------------------- */
28049+
1facf9fc 28050+#ifdef CONFIG_AUFS_DEBUG
28051+void au_plink_list(struct super_block *sb)
28052+{
86dc4139 28053+ int i;
1facf9fc 28054+ struct au_sbinfo *sbinfo;
8b6a4947
AM
28055+ struct hlist_bl_head *hbl;
28056+ struct hlist_bl_node *pos;
5afbbe0d 28057+ struct au_icntnr *icntnr;
1facf9fc 28058+
dece6358
AM
28059+ SiMustAnyLock(sb);
28060+
1facf9fc 28061+ sbinfo = au_sbi(sb);
28062+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 28063+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 28064+
86dc4139 28065+ for (i = 0; i < AuPlink_NHASH; i++) {
8b6a4947
AM
28066+ hbl = sbinfo->si_plink + i;
28067+ hlist_bl_lock(hbl);
28068+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink)
5afbbe0d 28069+ AuDbg("%lu\n", icntnr->vfs_inode.i_ino);
8b6a4947 28070+ hlist_bl_unlock(hbl);
86dc4139 28071+ }
1facf9fc 28072+}
28073+#endif
28074+
28075+/* is the inode pseudo-linked? */
28076+int au_plink_test(struct inode *inode)
28077+{
86dc4139 28078+ int found, i;
1facf9fc 28079+ struct au_sbinfo *sbinfo;
8b6a4947
AM
28080+ struct hlist_bl_head *hbl;
28081+ struct hlist_bl_node *pos;
5afbbe0d 28082+ struct au_icntnr *icntnr;
1facf9fc 28083+
28084+ sbinfo = au_sbi(inode->i_sb);
dece6358 28085+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 28086+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 28087+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 28088+
28089+ found = 0;
86dc4139 28090+ i = au_plink_hash(inode->i_ino);
8b6a4947
AM
28091+ hbl = sbinfo->si_plink + i;
28092+ hlist_bl_lock(hbl);
28093+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink)
5afbbe0d 28094+ if (&icntnr->vfs_inode == inode) {
1facf9fc 28095+ found = 1;
28096+ break;
28097+ }
8b6a4947 28098+ hlist_bl_unlock(hbl);
1facf9fc 28099+ return found;
28100+}
28101+
28102+/* ---------------------------------------------------------------------- */
28103+
28104+/*
28105+ * generate a name for plink.
28106+ * the file will be stored under AUFS_WH_PLINKDIR.
28107+ */
28108+/* 20 is max digits length of ulong 64 */
28109+#define PLINK_NAME_LEN ((20 + 1) * 2)
28110+
28111+static int plink_name(char *name, int len, struct inode *inode,
28112+ aufs_bindex_t bindex)
28113+{
28114+ int rlen;
28115+ struct inode *h_inode;
28116+
28117+ h_inode = au_h_iptr(inode, bindex);
28118+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
28119+ return rlen;
28120+}
28121+
7f207e10
AM
28122+struct au_do_plink_lkup_args {
28123+ struct dentry **errp;
28124+ struct qstr *tgtname;
28125+ struct dentry *h_parent;
28126+ struct au_branch *br;
28127+};
28128+
28129+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
28130+ struct dentry *h_parent,
28131+ struct au_branch *br)
28132+{
28133+ struct dentry *h_dentry;
febd17d6 28134+ struct inode *h_inode;
7f207e10 28135+
febd17d6 28136+ h_inode = d_inode(h_parent);
be118d29 28137+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2);
b4510431 28138+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
3c1bdaff 28139+ inode_unlock_shared(h_inode);
7f207e10
AM
28140+ return h_dentry;
28141+}
28142+
28143+static void au_call_do_plink_lkup(void *args)
28144+{
28145+ struct au_do_plink_lkup_args *a = args;
28146+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
28147+}
28148+
1facf9fc 28149+/* lookup the plink-ed @inode under the branch at @bindex */
28150+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
28151+{
28152+ struct dentry *h_dentry, *h_parent;
28153+ struct au_branch *br;
7f207e10 28154+ int wkq_err;
1facf9fc 28155+ char a[PLINK_NAME_LEN];
0c3ec466 28156+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 28157+
e49829fe
JR
28158+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
28159+
1facf9fc 28160+ br = au_sbr(inode->i_sb, bindex);
28161+ h_parent = br->br_wbr->wbr_plink;
1facf9fc 28162+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
28163+
2dfbb274 28164+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
28165+ struct au_do_plink_lkup_args args = {
28166+ .errp = &h_dentry,
28167+ .tgtname = &tgtname,
28168+ .h_parent = h_parent,
28169+ .br = br
28170+ };
28171+
28172+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
28173+ if (unlikely(wkq_err))
28174+ h_dentry = ERR_PTR(wkq_err);
28175+ } else
28176+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
28177+
1facf9fc 28178+ return h_dentry;
28179+}
28180+
28181+/* create a pseudo-link */
28182+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
28183+ struct dentry *h_dentry, struct au_branch *br)
28184+{
28185+ int err;
28186+ struct path h_path = {
86dc4139 28187+ .mnt = au_br_mnt(br)
1facf9fc 28188+ };
523b37e3 28189+ struct inode *h_dir, *delegated;
1facf9fc 28190+
5527c038 28191+ h_dir = d_inode(h_parent);
febd17d6 28192+ inode_lock_nested(h_dir, AuLsc_I_CHILD2);
4f0767ce 28193+again:
b4510431 28194+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 28195+ err = PTR_ERR(h_path.dentry);
28196+ if (IS_ERR(h_path.dentry))
28197+ goto out;
28198+
28199+ err = 0;
28200+ /* wh.plink dir is not monitored */
7f207e10 28201+ /* todo: is it really safe? */
5527c038
JR
28202+ if (d_is_positive(h_path.dentry)
28203+ && d_inode(h_path.dentry) != d_inode(h_dentry)) {
523b37e3
AM
28204+ delegated = NULL;
28205+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
28206+ if (unlikely(err == -EWOULDBLOCK)) {
28207+ pr_warn("cannot retry for NFSv4 delegation"
28208+ " for an internal unlink\n");
28209+ iput(delegated);
28210+ }
1facf9fc 28211+ dput(h_path.dentry);
28212+ h_path.dentry = NULL;
28213+ if (!err)
28214+ goto again;
28215+ }
5527c038 28216+ if (!err && d_is_negative(h_path.dentry)) {
523b37e3
AM
28217+ delegated = NULL;
28218+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
28219+ if (unlikely(err == -EWOULDBLOCK)) {
28220+ pr_warn("cannot retry for NFSv4 delegation"
28221+ " for an internal link\n");
28222+ iput(delegated);
28223+ }
28224+ }
1facf9fc 28225+ dput(h_path.dentry);
28226+
4f0767ce 28227+out:
febd17d6 28228+ inode_unlock(h_dir);
1facf9fc 28229+ return err;
28230+}
28231+
28232+struct do_whplink_args {
28233+ int *errp;
28234+ struct qstr *tgt;
28235+ struct dentry *h_parent;
28236+ struct dentry *h_dentry;
28237+ struct au_branch *br;
28238+};
28239+
28240+static void call_do_whplink(void *args)
28241+{
28242+ struct do_whplink_args *a = args;
28243+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
28244+}
28245+
28246+static int whplink(struct dentry *h_dentry, struct inode *inode,
28247+ aufs_bindex_t bindex, struct au_branch *br)
28248+{
28249+ int err, wkq_err;
28250+ struct au_wbr *wbr;
28251+ struct dentry *h_parent;
1facf9fc 28252+ char a[PLINK_NAME_LEN];
0c3ec466 28253+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 28254+
28255+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
28256+ h_parent = wbr->wbr_plink;
1facf9fc 28257+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
28258+
28259+ /* always superio. */
2dfbb274 28260+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 28261+ struct do_whplink_args args = {
28262+ .errp = &err,
28263+ .tgt = &tgtname,
28264+ .h_parent = h_parent,
28265+ .h_dentry = h_dentry,
28266+ .br = br
28267+ };
28268+ wkq_err = au_wkq_wait(call_do_whplink, &args);
28269+ if (unlikely(wkq_err))
28270+ err = wkq_err;
28271+ } else
28272+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 28273+
28274+ return err;
28275+}
28276+
1facf9fc 28277+/*
28278+ * create a new pseudo-link for @h_dentry on @bindex.
28279+ * the linked inode is held in aufs @inode.
28280+ */
28281+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
28282+ struct dentry *h_dentry)
28283+{
28284+ struct super_block *sb;
28285+ struct au_sbinfo *sbinfo;
8b6a4947
AM
28286+ struct hlist_bl_head *hbl;
28287+ struct hlist_bl_node *pos;
5afbbe0d 28288+ struct au_icntnr *icntnr;
86dc4139 28289+ int found, err, cnt, i;
1facf9fc 28290+
28291+ sb = inode->i_sb;
28292+ sbinfo = au_sbi(sb);
28293+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 28294+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 28295+
86dc4139 28296+ found = au_plink_test(inode);
4a4d8108 28297+ if (found)
1facf9fc 28298+ return;
4a4d8108 28299+
86dc4139 28300+ i = au_plink_hash(inode->i_ino);
8b6a4947 28301+ hbl = sbinfo->si_plink + i;
5afbbe0d 28302+ au_igrab(inode);
1facf9fc 28303+
8b6a4947
AM
28304+ hlist_bl_lock(hbl);
28305+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) {
5afbbe0d 28306+ if (&icntnr->vfs_inode == inode) {
4a4d8108
AM
28307+ found = 1;
28308+ break;
28309+ }
1facf9fc 28310+ }
5afbbe0d
AM
28311+ if (!found) {
28312+ icntnr = container_of(inode, struct au_icntnr, vfs_inode);
8b6a4947 28313+ hlist_bl_add_head(&icntnr->plink, hbl);
5afbbe0d 28314+ }
8b6a4947 28315+ hlist_bl_unlock(hbl);
4a4d8108 28316+ if (!found) {
8b6a4947 28317+ cnt = au_hbl_count(hbl);
acd2b654 28318+#define msg "unexpectedly unbalanced or too many pseudo-links"
86dc4139
AM
28319+ if (cnt > AUFS_PLINK_WARN)
28320+ AuWarn1(msg ", %d\n", cnt);
28321+#undef msg
1facf9fc 28322+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
5afbbe0d
AM
28323+ if (unlikely(err)) {
28324+ pr_warn("err %d, damaged pseudo link.\n", err);
8b6a4947 28325+ au_hbl_del(&icntnr->plink, hbl);
5afbbe0d 28326+ iput(&icntnr->vfs_inode);
4a4d8108 28327+ }
5afbbe0d
AM
28328+ } else
28329+ iput(&icntnr->vfs_inode);
1facf9fc 28330+}
28331+
28332+/* free all plinks */
e49829fe 28333+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 28334+{
86dc4139 28335+ int i, warned;
1facf9fc 28336+ struct au_sbinfo *sbinfo;
8b6a4947
AM
28337+ struct hlist_bl_head *hbl;
28338+ struct hlist_bl_node *pos, *tmp;
5afbbe0d 28339+ struct au_icntnr *icntnr;
1facf9fc 28340+
dece6358
AM
28341+ SiMustWriteLock(sb);
28342+
1facf9fc 28343+ sbinfo = au_sbi(sb);
28344+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 28345+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 28346+
1facf9fc 28347+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
28348+ warned = 0;
28349+ for (i = 0; i < AuPlink_NHASH; i++) {
8b6a4947
AM
28350+ hbl = sbinfo->si_plink + i;
28351+ if (!warned && verbose && !hlist_bl_empty(hbl)) {
86dc4139
AM
28352+ pr_warn("pseudo-link is not flushed");
28353+ warned = 1;
28354+ }
8b6a4947 28355+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink)
5afbbe0d 28356+ iput(&icntnr->vfs_inode);
8b6a4947 28357+ INIT_HLIST_BL_HEAD(hbl);
86dc4139 28358+ }
1facf9fc 28359+}
28360+
e49829fe
JR
28361+void au_plink_clean(struct super_block *sb, int verbose)
28362+{
28363+ struct dentry *root;
28364+
28365+ root = sb->s_root;
28366+ aufs_write_lock(root);
28367+ if (au_opt_test(au_mntflags(sb), PLINK))
28368+ au_plink_put(sb, verbose);
28369+ aufs_write_unlock(root);
28370+}
28371+
86dc4139
AM
28372+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
28373+{
28374+ int do_put;
5afbbe0d 28375+ aufs_bindex_t btop, bbot, bindex;
86dc4139
AM
28376+
28377+ do_put = 0;
5afbbe0d
AM
28378+ btop = au_ibtop(inode);
28379+ bbot = au_ibbot(inode);
28380+ if (btop >= 0) {
28381+ for (bindex = btop; bindex <= bbot; bindex++) {
86dc4139
AM
28382+ if (!au_h_iptr(inode, bindex)
28383+ || au_ii_br_id(inode, bindex) != br_id)
28384+ continue;
28385+ au_set_h_iptr(inode, bindex, NULL, 0);
28386+ do_put = 1;
28387+ break;
28388+ }
28389+ if (do_put)
5afbbe0d 28390+ for (bindex = btop; bindex <= bbot; bindex++)
86dc4139
AM
28391+ if (au_h_iptr(inode, bindex)) {
28392+ do_put = 0;
28393+ break;
28394+ }
28395+ } else
28396+ do_put = 1;
28397+
28398+ return do_put;
28399+}
28400+
1facf9fc 28401+/* free the plinks on a branch specified by @br_id */
28402+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
28403+{
28404+ struct au_sbinfo *sbinfo;
8b6a4947
AM
28405+ struct hlist_bl_head *hbl;
28406+ struct hlist_bl_node *pos, *tmp;
5afbbe0d 28407+ struct au_icntnr *icntnr;
1facf9fc 28408+ struct inode *inode;
86dc4139 28409+ int i, do_put;
1facf9fc 28410+
dece6358
AM
28411+ SiMustWriteLock(sb);
28412+
1facf9fc 28413+ sbinfo = au_sbi(sb);
28414+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 28415+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 28416+
8b6a4947 28417+ /* no bit_lock since sbinfo is write-locked */
86dc4139 28418+ for (i = 0; i < AuPlink_NHASH; i++) {
8b6a4947
AM
28419+ hbl = sbinfo->si_plink + i;
28420+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink) {
5afbbe0d 28421+ inode = au_igrab(&icntnr->vfs_inode);
86dc4139
AM
28422+ ii_write_lock_child(inode);
28423+ do_put = au_plink_do_half_refresh(inode, br_id);
5afbbe0d 28424+ if (do_put) {
8b6a4947 28425+ hlist_bl_del(&icntnr->plink);
5afbbe0d
AM
28426+ iput(inode);
28427+ }
86dc4139
AM
28428+ ii_write_unlock(inode);
28429+ iput(inode);
dece6358 28430+ }
dece6358
AM
28431+ }
28432+}
7f207e10
AM
28433diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
28434--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 28435+++ linux/fs/aufs/poll.c 2019-03-05 12:13:00.142557771 +0100
cd7a4cd9
AM
28436@@ -0,0 +1,51 @@
28437+// SPDX-License-Identifier: GPL-2.0
dece6358 28438+/*
ba1aed25 28439+ * Copyright (C) 2005-2019 Junjiro R. Okajima
dece6358
AM
28440+ *
28441+ * This program, aufs is free software; you can redistribute it and/or modify
28442+ * it under the terms of the GNU General Public License as published by
28443+ * the Free Software Foundation; either version 2 of the License, or
28444+ * (at your option) any later version.
28445+ *
28446+ * This program is distributed in the hope that it will be useful,
28447+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28448+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28449+ * GNU General Public License for more details.
28450+ *
28451+ * You should have received a copy of the GNU General Public License
523b37e3 28452+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
28453+ */
28454+
1308ab2a 28455+/*
28456+ * poll operation
28457+ * There is only one filesystem which implements ->poll operation, currently.
28458+ */
28459+
28460+#include "aufs.h"
28461+
cd7a4cd9 28462+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt)
1308ab2a 28463+{
be118d29 28464+ __poll_t mask;
1308ab2a 28465+ struct file *h_file;
1308ab2a 28466+ struct super_block *sb;
28467+
28468+ /* We should pretend an error happened. */
be118d29 28469+ mask = EPOLLERR /* | EPOLLIN | EPOLLOUT */;
b912730e 28470+ sb = file->f_path.dentry->d_sb;
e49829fe 28471+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 28472+
521ced18 28473+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
062440b3
AM
28474+ if (IS_ERR(h_file)) {
28475+ AuDbg("h_file %ld\n", PTR_ERR(h_file));
1308ab2a 28476+ goto out;
062440b3 28477+ }
1308ab2a 28478+
cd7a4cd9 28479+ mask = vfs_poll(h_file, pt);
b912730e 28480+ fput(h_file); /* instead of au_read_post() */
1308ab2a 28481+
4f0767ce 28482+out:
1308ab2a 28483+ si_read_unlock(sb);
062440b3 28484+ if (mask & EPOLLERR)
b00004a5 28485+ AuDbg("mask 0x%x\n", mask);
1308ab2a 28486+ return mask;
28487+}
c1595e42
JR
28488diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
28489--- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 28490+++ linux/fs/aufs/posix_acl.c 2019-03-05 12:13:00.142557771 +0100
062440b3 28491@@ -0,0 +1,103 @@
cd7a4cd9 28492+// SPDX-License-Identifier: GPL-2.0
c1595e42 28493+/*
ba1aed25 28494+ * Copyright (C) 2014-2019 Junjiro R. Okajima
c1595e42
JR
28495+ *
28496+ * This program, aufs is free software; you can redistribute it and/or modify
28497+ * it under the terms of the GNU General Public License as published by
28498+ * the Free Software Foundation; either version 2 of the License, or
28499+ * (at your option) any later version.
28500+ *
28501+ * This program is distributed in the hope that it will be useful,
28502+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28503+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28504+ * GNU General Public License for more details.
28505+ *
28506+ * You should have received a copy of the GNU General Public License
28507+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28508+ */
28509+
28510+/*
28511+ * posix acl operations
28512+ */
28513+
28514+#include <linux/fs.h>
c1595e42
JR
28515+#include "aufs.h"
28516+
28517+struct posix_acl *aufs_get_acl(struct inode *inode, int type)
28518+{
28519+ struct posix_acl *acl;
28520+ int err;
28521+ aufs_bindex_t bindex;
28522+ struct inode *h_inode;
28523+ struct super_block *sb;
28524+
28525+ acl = NULL;
28526+ sb = inode->i_sb;
28527+ si_read_lock(sb, AuLock_FLUSH);
28528+ ii_read_lock_child(inode);
2121bcd9 28529+ if (!(sb->s_flags & SB_POSIXACL))
c1595e42
JR
28530+ goto out;
28531+
5afbbe0d 28532+ bindex = au_ibtop(inode);
c1595e42
JR
28533+ h_inode = au_h_iptr(inode, bindex);
28534+ if (unlikely(!h_inode
28535+ || ((h_inode->i_mode & S_IFMT)
28536+ != (inode->i_mode & S_IFMT)))) {
28537+ err = au_busy_or_stale();
28538+ acl = ERR_PTR(err);
28539+ goto out;
28540+ }
28541+
28542+ /* always topmost only */
28543+ acl = get_acl(h_inode, type);
a2654f78
AM
28544+ if (!IS_ERR_OR_NULL(acl))
28545+ set_cached_acl(inode, type, acl);
c1595e42
JR
28546+
28547+out:
28548+ ii_read_unlock(inode);
28549+ si_read_unlock(sb);
28550+
28551+ AuTraceErrPtr(acl);
28552+ return acl;
28553+}
28554+
28555+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
28556+{
28557+ int err;
28558+ ssize_t ssz;
28559+ struct dentry *dentry;
f2c43d5f 28560+ struct au_sxattr arg = {
c1595e42
JR
28561+ .type = AU_ACL_SET,
28562+ .u.acl_set = {
28563+ .acl = acl,
28564+ .type = type
28565+ },
28566+ };
28567+
5afbbe0d
AM
28568+ IMustLock(inode);
28569+
c1595e42
JR
28570+ if (inode->i_ino == AUFS_ROOT_INO)
28571+ dentry = dget(inode->i_sb->s_root);
28572+ else {
28573+ dentry = d_find_alias(inode);
28574+ if (!dentry)
28575+ dentry = d_find_any_alias(inode);
28576+ if (!dentry) {
28577+ pr_warn("cannot handle this inode, "
28578+ "please report to aufs-users ML\n");
28579+ err = -ENOENT;
28580+ goto out;
28581+ }
28582+ }
28583+
f2c43d5f 28584+ ssz = au_sxattr(dentry, inode, &arg);
c1595e42
JR
28585+ dput(dentry);
28586+ err = ssz;
a2654f78 28587+ if (ssz >= 0) {
c1595e42 28588+ err = 0;
a2654f78
AM
28589+ set_cached_acl(inode, type, acl);
28590+ }
c1595e42
JR
28591+
28592+out:
c1595e42
JR
28593+ return err;
28594+}
7f207e10
AM
28595diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
28596--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 28597+++ linux/fs/aufs/procfs.c 2019-03-05 12:13:00.142557771 +0100
062440b3 28598@@ -0,0 +1,171 @@
cd7a4cd9 28599+// SPDX-License-Identifier: GPL-2.0
e49829fe 28600+/*
ba1aed25 28601+ * Copyright (C) 2010-2019 Junjiro R. Okajima
e49829fe
JR
28602+ *
28603+ * This program, aufs is free software; you can redistribute it and/or modify
28604+ * it under the terms of the GNU General Public License as published by
28605+ * the Free Software Foundation; either version 2 of the License, or
28606+ * (at your option) any later version.
28607+ *
28608+ * This program is distributed in the hope that it will be useful,
28609+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28610+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28611+ * GNU General Public License for more details.
28612+ *
28613+ * You should have received a copy of the GNU General Public License
523b37e3 28614+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
28615+ */
28616+
28617+/*
28618+ * procfs interfaces
28619+ */
28620+
28621+#include <linux/proc_fs.h>
28622+#include "aufs.h"
28623+
28624+static int au_procfs_plm_release(struct inode *inode, struct file *file)
28625+{
28626+ struct au_sbinfo *sbinfo;
28627+
28628+ sbinfo = file->private_data;
28629+ if (sbinfo) {
28630+ au_plink_maint_leave(sbinfo);
28631+ kobject_put(&sbinfo->si_kobj);
28632+ }
28633+
28634+ return 0;
28635+}
28636+
28637+static void au_procfs_plm_write_clean(struct file *file)
28638+{
28639+ struct au_sbinfo *sbinfo;
28640+
28641+ sbinfo = file->private_data;
28642+ if (sbinfo)
28643+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
28644+}
28645+
28646+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
28647+{
28648+ int err;
28649+ struct super_block *sb;
28650+ struct au_sbinfo *sbinfo;
8b6a4947 28651+ struct hlist_bl_node *pos;
e49829fe
JR
28652+
28653+ err = -EBUSY;
28654+ if (unlikely(file->private_data))
28655+ goto out;
28656+
28657+ sb = NULL;
53392da6 28658+ /* don't use au_sbilist_lock() here */
8b6a4947
AM
28659+ hlist_bl_lock(&au_sbilist);
28660+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list)
e49829fe
JR
28661+ if (id == sysaufs_si_id(sbinfo)) {
28662+ kobject_get(&sbinfo->si_kobj);
28663+ sb = sbinfo->si_sb;
28664+ break;
28665+ }
8b6a4947 28666+ hlist_bl_unlock(&au_sbilist);
e49829fe
JR
28667+
28668+ err = -EINVAL;
28669+ if (unlikely(!sb))
28670+ goto out;
28671+
28672+ err = au_plink_maint_enter(sb);
28673+ if (!err)
28674+ /* keep kobject_get() */
28675+ file->private_data = sbinfo;
28676+ else
28677+ kobject_put(&sbinfo->si_kobj);
28678+out:
28679+ return err;
28680+}
28681+
28682+/*
28683+ * Accept a valid "si=xxxx" only.
28684+ * Once it is accepted successfully, accept "clean" too.
28685+ */
28686+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
28687+ size_t count, loff_t *ppos)
28688+{
28689+ ssize_t err;
28690+ unsigned long id;
28691+ /* last newline is allowed */
28692+ char buf[3 + sizeof(unsigned long) * 2 + 1];
28693+
28694+ err = -EACCES;
28695+ if (unlikely(!capable(CAP_SYS_ADMIN)))
28696+ goto out;
28697+
28698+ err = -EINVAL;
28699+ if (unlikely(count > sizeof(buf)))
28700+ goto out;
28701+
28702+ err = copy_from_user(buf, ubuf, count);
28703+ if (unlikely(err)) {
28704+ err = -EFAULT;
28705+ goto out;
28706+ }
28707+ buf[count] = 0;
28708+
28709+ err = -EINVAL;
28710+ if (!strcmp("clean", buf)) {
28711+ au_procfs_plm_write_clean(file);
28712+ goto out_success;
28713+ } else if (unlikely(strncmp("si=", buf, 3)))
28714+ goto out;
28715+
9dbd164d 28716+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
28717+ if (unlikely(err))
28718+ goto out;
28719+
28720+ err = au_procfs_plm_write_si(file, id);
28721+ if (unlikely(err))
28722+ goto out;
28723+
28724+out_success:
28725+ err = count; /* success */
28726+out:
28727+ return err;
28728+}
28729+
28730+static const struct file_operations au_procfs_plm_fop = {
28731+ .write = au_procfs_plm_write,
28732+ .release = au_procfs_plm_release,
28733+ .owner = THIS_MODULE
28734+};
28735+
28736+/* ---------------------------------------------------------------------- */
28737+
28738+static struct proc_dir_entry *au_procfs_dir;
28739+
28740+void au_procfs_fin(void)
28741+{
28742+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
28743+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
28744+}
28745+
28746+int __init au_procfs_init(void)
28747+{
28748+ int err;
28749+ struct proc_dir_entry *entry;
28750+
28751+ err = -ENOMEM;
28752+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
28753+ if (unlikely(!au_procfs_dir))
28754+ goto out;
28755+
cd7a4cd9 28756+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | 0200,
e49829fe
JR
28757+ au_procfs_dir, &au_procfs_plm_fop);
28758+ if (unlikely(!entry))
28759+ goto out_dir;
28760+
28761+ err = 0;
28762+ goto out; /* success */
28763+
28764+
28765+out_dir:
28766+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
28767+out:
28768+ return err;
28769+}
7f207e10
AM
28770diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
28771--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25
AM
28772+++ linux/fs/aufs/rdu.c 2019-03-05 12:13:00.142557771 +0100
28773@@ -0,0 +1,384 @@
cd7a4cd9 28774+// SPDX-License-Identifier: GPL-2.0
1308ab2a 28775+/*
ba1aed25 28776+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1308ab2a 28777+ *
28778+ * This program, aufs is free software; you can redistribute it and/or modify
28779+ * it under the terms of the GNU General Public License as published by
28780+ * the Free Software Foundation; either version 2 of the License, or
28781+ * (at your option) any later version.
28782+ *
28783+ * This program is distributed in the hope that it will be useful,
28784+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28785+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28786+ * GNU General Public License for more details.
28787+ *
28788+ * You should have received a copy of the GNU General Public License
523b37e3 28789+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 28790+ */
28791+
28792+/*
28793+ * readdir in userspace.
28794+ */
28795+
b752ccd1 28796+#include <linux/compat.h>
4a4d8108 28797+#include <linux/fs_stack.h>
1308ab2a 28798+#include <linux/security.h>
1308ab2a 28799+#include "aufs.h"
28800+
28801+/* bits for struct aufs_rdu.flags */
28802+#define AuRdu_CALLED 1
28803+#define AuRdu_CONT (1 << 1)
28804+#define AuRdu_FULL (1 << 2)
28805+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
28806+#define au_fset_rdu(flags, name) \
28807+ do { (flags) |= AuRdu_##name; } while (0)
28808+#define au_fclr_rdu(flags, name) \
28809+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 28810+
28811+struct au_rdu_arg {
392086de 28812+ struct dir_context ctx;
1308ab2a 28813+ struct aufs_rdu *rdu;
28814+ union au_rdu_ent_ul ent;
28815+ unsigned long end;
28816+
28817+ struct super_block *sb;
28818+ int err;
28819+};
28820+
392086de 28821+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 28822+ loff_t offset, u64 h_ino, unsigned int d_type)
28823+{
28824+ int err, len;
392086de 28825+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 28826+ struct aufs_rdu *rdu = arg->rdu;
28827+ struct au_rdu_ent ent;
28828+
28829+ err = 0;
28830+ arg->err = 0;
28831+ au_fset_rdu(rdu->cookie.flags, CALLED);
28832+ len = au_rdu_len(nlen);
28833+ if (arg->ent.ul + len < arg->end) {
28834+ ent.ino = h_ino;
28835+ ent.bindex = rdu->cookie.bindex;
28836+ ent.type = d_type;
28837+ ent.nlen = nlen;
4a4d8108
AM
28838+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
28839+ ent.type = DT_UNKNOWN;
1308ab2a 28840+
9dbd164d 28841+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 28842+ err = -EFAULT;
28843+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
28844+ goto out;
28845+ if (copy_to_user(arg->ent.e->name, name, nlen))
28846+ goto out;
28847+ /* the terminating NULL */
28848+ if (__put_user(0, arg->ent.e->name + nlen))
28849+ goto out;
28850+ err = 0;
28851+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
28852+ arg->ent.ul += len;
28853+ rdu->rent++;
28854+ } else {
28855+ err = -EFAULT;
28856+ au_fset_rdu(rdu->cookie.flags, FULL);
28857+ rdu->full = 1;
28858+ rdu->tail = arg->ent;
28859+ }
28860+
4f0767ce 28861+out:
1308ab2a 28862+ /* AuTraceErr(err); */
28863+ return err;
28864+}
28865+
28866+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
28867+{
28868+ int err;
28869+ loff_t offset;
28870+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
28871+
92d182d2 28872+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 28873+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
28874+ err = offset;
28875+ if (unlikely(offset != cookie->h_pos))
28876+ goto out;
28877+
28878+ err = 0;
28879+ do {
28880+ arg->err = 0;
28881+ au_fclr_rdu(cookie->flags, CALLED);
28882+ /* smp_mb(); */
392086de 28883+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 28884+ if (err >= 0)
28885+ err = arg->err;
28886+ } while (!err
28887+ && au_ftest_rdu(cookie->flags, CALLED)
28888+ && !au_ftest_rdu(cookie->flags, FULL));
28889+ cookie->h_pos = h_file->f_pos;
28890+
4f0767ce 28891+out:
1308ab2a 28892+ AuTraceErr(err);
28893+ return err;
28894+}
28895+
28896+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
28897+{
28898+ int err;
5afbbe0d 28899+ aufs_bindex_t bbot;
392086de
AM
28900+ struct au_rdu_arg arg = {
28901+ .ctx = {
2000de60 28902+ .actor = au_rdu_fill
392086de
AM
28903+ }
28904+ };
1308ab2a 28905+ struct dentry *dentry;
28906+ struct inode *inode;
28907+ struct file *h_file;
28908+ struct au_rdu_cookie *cookie = &rdu->cookie;
28909+
ba1aed25
AM
28910+ /* VERIFY_WRITE */
28911+ err = !access_ok(rdu->ent.e, rdu->sz);
1308ab2a 28912+ if (unlikely(err)) {
28913+ err = -EFAULT;
28914+ AuTraceErr(err);
28915+ goto out;
28916+ }
28917+ rdu->rent = 0;
28918+ rdu->tail = rdu->ent;
28919+ rdu->full = 0;
28920+ arg.rdu = rdu;
28921+ arg.ent = rdu->ent;
28922+ arg.end = arg.ent.ul;
28923+ arg.end += rdu->sz;
28924+
28925+ err = -ENOTDIR;
5afbbe0d 28926+ if (unlikely(!file->f_op->iterate && !file->f_op->iterate_shared))
1308ab2a 28927+ goto out;
28928+
28929+ err = security_file_permission(file, MAY_READ);
28930+ AuTraceErr(err);
28931+ if (unlikely(err))
28932+ goto out;
28933+
2000de60 28934+ dentry = file->f_path.dentry;
5527c038 28935+ inode = d_inode(dentry);
5afbbe0d 28936+ inode_lock_shared(inode);
1308ab2a 28937+
28938+ arg.sb = inode->i_sb;
e49829fe
JR
28939+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
28940+ if (unlikely(err))
28941+ goto out_mtx;
027c5e7a
AM
28942+ err = au_alive_dir(dentry);
28943+ if (unlikely(err))
28944+ goto out_si;
e49829fe 28945+ /* todo: reval? */
1308ab2a 28946+ fi_read_lock(file);
28947+
28948+ err = -EAGAIN;
28949+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
28950+ && cookie->generation != au_figen(file)))
28951+ goto out_unlock;
28952+
28953+ err = 0;
28954+ if (!rdu->blk) {
28955+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
28956+ if (!rdu->blk)
28957+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
28958+ }
5afbbe0d
AM
28959+ bbot = au_fbtop(file);
28960+ if (cookie->bindex < bbot)
28961+ cookie->bindex = bbot;
28962+ bbot = au_fbbot_dir(file);
28963+ /* AuDbg("b%d, b%d\n", cookie->bindex, bbot); */
28964+ for (; !err && cookie->bindex <= bbot;
1308ab2a 28965+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 28966+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 28967+ if (!h_file)
28968+ continue;
28969+
28970+ au_fclr_rdu(cookie->flags, FULL);
28971+ err = au_rdu_do(h_file, &arg);
28972+ AuTraceErr(err);
28973+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
28974+ break;
28975+ }
28976+ AuDbg("rent %llu\n", rdu->rent);
28977+
28978+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
28979+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
28980+ au_fset_rdu(cookie->flags, CONT);
28981+ cookie->generation = au_figen(file);
28982+ }
28983+
28984+ ii_read_lock_child(inode);
5afbbe0d 28985+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibtop(inode)));
1308ab2a 28986+ ii_read_unlock(inode);
28987+
4f0767ce 28988+out_unlock:
1308ab2a 28989+ fi_read_unlock(file);
027c5e7a 28990+out_si:
1308ab2a 28991+ si_read_unlock(arg.sb);
4f0767ce 28992+out_mtx:
5afbbe0d 28993+ inode_unlock_shared(inode);
4f0767ce 28994+out:
1308ab2a 28995+ AuTraceErr(err);
28996+ return err;
28997+}
28998+
28999+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
29000+{
29001+ int err;
29002+ ino_t ino;
29003+ unsigned long long nent;
29004+ union au_rdu_ent_ul *u;
29005+ struct au_rdu_ent ent;
29006+ struct super_block *sb;
29007+
29008+ err = 0;
29009+ nent = rdu->nent;
29010+ u = &rdu->ent;
2000de60 29011+ sb = file->f_path.dentry->d_sb;
1308ab2a 29012+ si_read_lock(sb, AuLock_FLUSH);
29013+ while (nent-- > 0) {
9dbd164d 29014+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 29015+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108 29016+ if (!err)
ba1aed25
AM
29017+ /* VERIFY_WRITE */
29018+ err = !access_ok(&u->e->ino, sizeof(ino));
1308ab2a 29019+ if (unlikely(err)) {
29020+ err = -EFAULT;
29021+ AuTraceErr(err);
29022+ break;
29023+ }
29024+
29025+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
29026+ if (!ent.wh)
29027+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
29028+ else
29029+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
29030+ &ino);
29031+ if (unlikely(err)) {
29032+ AuTraceErr(err);
29033+ break;
29034+ }
29035+
29036+ err = __put_user(ino, &u->e->ino);
29037+ if (unlikely(err)) {
29038+ err = -EFAULT;
29039+ AuTraceErr(err);
29040+ break;
29041+ }
29042+ u->ul += au_rdu_len(ent.nlen);
29043+ }
29044+ si_read_unlock(sb);
29045+
29046+ return err;
29047+}
29048+
29049+/* ---------------------------------------------------------------------- */
29050+
29051+static int au_rdu_verify(struct aufs_rdu *rdu)
29052+{
b752ccd1 29053+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 29054+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 29055+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 29056+ rdu->blk,
29057+ rdu->rent, rdu->shwh, rdu->full,
29058+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
29059+ rdu->cookie.generation);
dece6358 29060+
b752ccd1 29061+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 29062+ return 0;
dece6358 29063+
b752ccd1
AM
29064+ AuDbg("%u:%u\n",
29065+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 29066+ return -EINVAL;
29067+}
29068+
29069+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 29070+{
1308ab2a 29071+ long err, e;
29072+ struct aufs_rdu rdu;
29073+ void __user *p = (void __user *)arg;
dece6358 29074+
1308ab2a 29075+ err = copy_from_user(&rdu, p, sizeof(rdu));
29076+ if (unlikely(err)) {
29077+ err = -EFAULT;
29078+ AuTraceErr(err);
29079+ goto out;
29080+ }
29081+ err = au_rdu_verify(&rdu);
dece6358
AM
29082+ if (unlikely(err))
29083+ goto out;
29084+
1308ab2a 29085+ switch (cmd) {
29086+ case AUFS_CTL_RDU:
29087+ err = au_rdu(file, &rdu);
29088+ if (unlikely(err))
29089+ break;
dece6358 29090+
1308ab2a 29091+ e = copy_to_user(p, &rdu, sizeof(rdu));
29092+ if (unlikely(e)) {
29093+ err = -EFAULT;
29094+ AuTraceErr(err);
29095+ }
29096+ break;
29097+ case AUFS_CTL_RDU_INO:
29098+ err = au_rdu_ino(file, &rdu);
29099+ break;
29100+
29101+ default:
4a4d8108 29102+ /* err = -ENOTTY; */
1308ab2a 29103+ err = -EINVAL;
29104+ }
dece6358 29105+
4f0767ce 29106+out:
1308ab2a 29107+ AuTraceErr(err);
29108+ return err;
1facf9fc 29109+}
b752ccd1
AM
29110+
29111+#ifdef CONFIG_COMPAT
29112+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
29113+{
29114+ long err, e;
29115+ struct aufs_rdu rdu;
29116+ void __user *p = compat_ptr(arg);
29117+
29118+ /* todo: get_user()? */
29119+ err = copy_from_user(&rdu, p, sizeof(rdu));
29120+ if (unlikely(err)) {
29121+ err = -EFAULT;
29122+ AuTraceErr(err);
29123+ goto out;
29124+ }
29125+ rdu.ent.e = compat_ptr(rdu.ent.ul);
29126+ err = au_rdu_verify(&rdu);
29127+ if (unlikely(err))
29128+ goto out;
29129+
29130+ switch (cmd) {
29131+ case AUFS_CTL_RDU:
29132+ err = au_rdu(file, &rdu);
29133+ if (unlikely(err))
29134+ break;
29135+
29136+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
29137+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
29138+ e = copy_to_user(p, &rdu, sizeof(rdu));
29139+ if (unlikely(e)) {
29140+ err = -EFAULT;
29141+ AuTraceErr(err);
29142+ }
29143+ break;
29144+ case AUFS_CTL_RDU_INO:
29145+ err = au_rdu_ino(file, &rdu);
29146+ break;
29147+
29148+ default:
29149+ /* err = -ENOTTY; */
29150+ err = -EINVAL;
29151+ }
29152+
4f0767ce 29153+out:
b752ccd1
AM
29154+ AuTraceErr(err);
29155+ return err;
29156+}
29157+#endif
7f207e10
AM
29158diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
29159--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 29160+++ linux/fs/aufs/rwsem.h 2019-03-05 12:13:00.142557771 +0100
062440b3
AM
29161@@ -0,0 +1,73 @@
29162+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 29163+/*
ba1aed25 29164+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 29165+ *
29166+ * This program, aufs is free software; you can redistribute it and/or modify
29167+ * it under the terms of the GNU General Public License as published by
29168+ * the Free Software Foundation; either version 2 of the License, or
29169+ * (at your option) any later version.
dece6358
AM
29170+ *
29171+ * This program is distributed in the hope that it will be useful,
29172+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29173+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29174+ * GNU General Public License for more details.
29175+ *
29176+ * You should have received a copy of the GNU General Public License
523b37e3 29177+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29178+ */
29179+
29180+/*
29181+ * simple read-write semaphore wrappers
29182+ */
29183+
29184+#ifndef __AUFS_RWSEM_H__
29185+#define __AUFS_RWSEM_H__
29186+
29187+#ifdef __KERNEL__
29188+
4a4d8108 29189+#include "debug.h"
dece6358 29190+
acd2b654 29191+/* in the future, the name 'au_rwsem' will be totally gone */
8b6a4947 29192+#define au_rwsem rw_semaphore
dece6358
AM
29193+
29194+/* to debug easier, do not make them inlined functions */
8b6a4947 29195+#define AuRwMustNoWaiters(rw) AuDebugOn(rwsem_is_contended(rw))
dece6358 29196+/* rwsem_is_locked() is unusable */
8b6a4947
AM
29197+#define AuRwMustReadLock(rw) AuDebugOn(!lockdep_recursing(current) \
29198+ && debug_locks \
29199+ && !lockdep_is_held_type(rw, 1))
29200+#define AuRwMustWriteLock(rw) AuDebugOn(!lockdep_recursing(current) \
29201+ && debug_locks \
29202+ && !lockdep_is_held_type(rw, 0))
29203+#define AuRwMustAnyLock(rw) AuDebugOn(!lockdep_recursing(current) \
29204+ && debug_locks \
29205+ && !lockdep_is_held(rw))
29206+#define AuRwDestroy(rw) AuDebugOn(!lockdep_recursing(current) \
29207+ && debug_locks \
29208+ && lockdep_is_held(rw))
29209+
29210+#define au_rw_init(rw) init_rwsem(rw)
dece6358 29211+
5afbbe0d
AM
29212+#define au_rw_init_wlock(rw) do { \
29213+ au_rw_init(rw); \
8b6a4947 29214+ down_write(rw); \
5afbbe0d 29215+ } while (0)
dece6358 29216+
8b6a4947
AM
29217+#define au_rw_init_wlock_nested(rw, lsc) do { \
29218+ au_rw_init(rw); \
29219+ down_write_nested(rw, lsc); \
5afbbe0d 29220+ } while (0)
dece6358 29221+
8b6a4947
AM
29222+#define au_rw_read_lock(rw) down_read(rw)
29223+#define au_rw_read_lock_nested(rw, lsc) down_read_nested(rw, lsc)
29224+#define au_rw_read_unlock(rw) up_read(rw)
29225+#define au_rw_dgrade_lock(rw) downgrade_write(rw)
29226+#define au_rw_write_lock(rw) down_write(rw)
29227+#define au_rw_write_lock_nested(rw, lsc) down_write_nested(rw, lsc)
29228+#define au_rw_write_unlock(rw) up_write(rw)
29229+/* why is not _nested version defined? */
29230+#define au_rw_read_trylock(rw) down_read_trylock(rw)
29231+#define au_rw_write_trylock(rw) down_write_trylock(rw)
1facf9fc 29232+
29233+#endif /* __KERNEL__ */
29234+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
29235diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
29236--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
29237+++ linux/fs/aufs/sbinfo.c 2019-05-06 09:03:04.820143837 +0200
29238@@ -0,0 +1,314 @@
cd7a4cd9 29239+// SPDX-License-Identifier: GPL-2.0
1facf9fc 29240+/*
ba1aed25 29241+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 29242+ *
29243+ * This program, aufs is free software; you can redistribute it and/or modify
29244+ * it under the terms of the GNU General Public License as published by
29245+ * the Free Software Foundation; either version 2 of the License, or
29246+ * (at your option) any later version.
dece6358
AM
29247+ *
29248+ * This program is distributed in the hope that it will be useful,
29249+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29250+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29251+ * GNU General Public License for more details.
29252+ *
29253+ * You should have received a copy of the GNU General Public License
523b37e3 29254+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29255+ */
29256+
29257+/*
29258+ * superblock private data
29259+ */
29260+
eca801bf 29261+#include <linux/iversion.h>
1facf9fc 29262+#include "aufs.h"
29263+
29264+/*
29265+ * they are necessary regardless sysfs is disabled.
29266+ */
29267+void au_si_free(struct kobject *kobj)
29268+{
86dc4139 29269+ int i;
1facf9fc 29270+ struct au_sbinfo *sbinfo;
b752ccd1 29271+ char *locked __maybe_unused; /* debug only */
1facf9fc 29272+
29273+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139 29274+ for (i = 0; i < AuPlink_NHASH; i++)
8b6a4947 29275+ AuDebugOn(!hlist_bl_empty(sbinfo->si_plink + i));
f0c0a007 29276+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
5afbbe0d 29277+
acd2b654
AM
29278+ AuLCntZero(au_lcnt_read(&sbinfo->si_ninodes, /*do_rev*/0));
29279+ au_lcnt_fin(&sbinfo->si_ninodes, /*do_sync*/0);
29280+ AuLCntZero(au_lcnt_read(&sbinfo->si_nfiles, /*do_rev*/0));
29281+ au_lcnt_fin(&sbinfo->si_nfiles, /*do_sync*/0);
1facf9fc 29282+
062440b3 29283+ dbgaufs_si_fin(sbinfo);
e49829fe 29284+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 29285+ au_br_free(sbinfo);
e49829fe 29286+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1 29287+
9f237c51 29288+ au_kfree_try_rcu(sbinfo->si_branch);
1facf9fc 29289+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 29290+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 29291+
acd2b654
AM
29292+ au_lcnt_wait_for_fin(&sbinfo->si_ninodes);
29293+ /* si_nfiles is waited too */
9f237c51 29294+ au_kfree_rcu(sbinfo);
1facf9fc 29295+}
29296+
29297+int au_si_alloc(struct super_block *sb)
29298+{
86dc4139 29299+ int err, i;
1facf9fc 29300+ struct au_sbinfo *sbinfo;
29301+
29302+ err = -ENOMEM;
4a4d8108 29303+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 29304+ if (unlikely(!sbinfo))
29305+ goto out;
29306+
29307+ /* will be reallocated separately */
29308+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
29309+ if (unlikely(!sbinfo->si_branch))
febd17d6 29310+ goto out_sbinfo;
1facf9fc 29311+
1facf9fc 29312+ err = sysaufs_si_init(sbinfo);
062440b3
AM
29313+ if (!err) {
29314+ dbgaufs_si_null(sbinfo);
29315+ err = dbgaufs_si_init(sbinfo);
29316+ if (unlikely(err))
29317+ kobject_put(&sbinfo->si_kobj);
29318+ }
1facf9fc 29319+ if (unlikely(err))
29320+ goto out_br;
29321+
29322+ au_nwt_init(&sbinfo->si_nowait);
dece6358 29323+ au_rw_init_wlock(&sbinfo->si_rwsem);
b752ccd1 29324+
acd2b654
AM
29325+ au_lcnt_init(&sbinfo->si_ninodes, /*release*/NULL);
29326+ au_lcnt_init(&sbinfo->si_nfiles, /*release*/NULL);
7f207e10 29327+
5afbbe0d 29328+ sbinfo->si_bbot = -1;
392086de 29329+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 29330+
29331+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
29332+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
29333+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
29334+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 29335+
076b876e
AM
29336+ au_fhsm_init(sbinfo);
29337+
e49829fe 29338+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 29339+
392086de
AM
29340+ sbinfo->si_xino_jiffy = jiffies;
29341+ sbinfo->si_xino_expire
29342+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 29343+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 29344+ /* leave si_xib_last_pindex and si_xib_next_bit */
29345+
8b6a4947 29346+ INIT_HLIST_BL_HEAD(&sbinfo->si_aopen);
b912730e 29347+
e49829fe 29348+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 29349+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
29350+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
29351+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
29352+
86dc4139 29353+ for (i = 0; i < AuPlink_NHASH; i++)
8b6a4947 29354+ INIT_HLIST_BL_HEAD(sbinfo->si_plink + i);
1facf9fc 29355+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 29356+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 29357+
8b6a4947 29358+ INIT_HLIST_BL_HEAD(&sbinfo->si_files);
523b37e3 29359+
b95c5147
AM
29360+ /* with getattr by default */
29361+ sbinfo->si_iop_array = aufs_iop;
29362+
1facf9fc 29363+ /* leave other members for sysaufs and si_mnt. */
29364+ sbinfo->si_sb = sb;
29365+ sb->s_fs_info = sbinfo;
b752ccd1 29366+ si_pid_set(sb);
1facf9fc 29367+ return 0; /* success */
29368+
4f0767ce 29369+out_br:
9f237c51 29370+ au_kfree_try_rcu(sbinfo->si_branch);
4f0767ce 29371+out_sbinfo:
9f237c51 29372+ au_kfree_rcu(sbinfo);
4f0767ce 29373+out:
1facf9fc 29374+ return err;
29375+}
29376+
e2f27e51 29377+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink)
1facf9fc 29378+{
29379+ int err, sz;
29380+ struct au_branch **brp;
29381+
dece6358
AM
29382+ AuRwMustWriteLock(&sbinfo->si_rwsem);
29383+
1facf9fc 29384+ err = -ENOMEM;
5afbbe0d 29385+ sz = sizeof(*brp) * (sbinfo->si_bbot + 1);
1facf9fc 29386+ if (unlikely(!sz))
29387+ sz = sizeof(*brp);
e2f27e51
AM
29388+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS,
29389+ may_shrink);
1facf9fc 29390+ if (brp) {
29391+ sbinfo->si_branch = brp;
29392+ err = 0;
29393+ }
29394+
29395+ return err;
29396+}
29397+
29398+/* ---------------------------------------------------------------------- */
29399+
29400+unsigned int au_sigen_inc(struct super_block *sb)
29401+{
29402+ unsigned int gen;
5527c038 29403+ struct inode *inode;
1facf9fc 29404+
dece6358
AM
29405+ SiMustWriteLock(sb);
29406+
1facf9fc 29407+ gen = ++au_sbi(sb)->si_generation;
29408+ au_update_digen(sb->s_root);
5527c038
JR
29409+ inode = d_inode(sb->s_root);
29410+ au_update_iigen(inode, /*half*/0);
be118d29 29411+ inode_inc_iversion(inode);
1facf9fc 29412+ return gen;
29413+}
29414+
29415+aufs_bindex_t au_new_br_id(struct super_block *sb)
29416+{
29417+ aufs_bindex_t br_id;
29418+ int i;
29419+ struct au_sbinfo *sbinfo;
29420+
dece6358
AM
29421+ SiMustWriteLock(sb);
29422+
1facf9fc 29423+ sbinfo = au_sbi(sb);
29424+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
29425+ br_id = ++sbinfo->si_last_br_id;
7f207e10 29426+ AuDebugOn(br_id < 0);
1facf9fc 29427+ if (br_id && au_br_index(sb, br_id) < 0)
29428+ return br_id;
29429+ }
29430+
29431+ return -1;
29432+}
29433+
29434+/* ---------------------------------------------------------------------- */
29435+
e49829fe
JR
29436+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
29437+int si_read_lock(struct super_block *sb, int flags)
29438+{
29439+ int err;
29440+
29441+ err = 0;
29442+ if (au_ftest_lock(flags, FLUSH))
29443+ au_nwt_flush(&au_sbi(sb)->si_nowait);
29444+
29445+ si_noflush_read_lock(sb);
29446+ err = au_plink_maint(sb, flags);
29447+ if (unlikely(err))
29448+ si_read_unlock(sb);
29449+
29450+ return err;
29451+}
29452+
29453+int si_write_lock(struct super_block *sb, int flags)
29454+{
29455+ int err;
29456+
29457+ if (au_ftest_lock(flags, FLUSH))
29458+ au_nwt_flush(&au_sbi(sb)->si_nowait);
29459+
29460+ si_noflush_write_lock(sb);
29461+ err = au_plink_maint(sb, flags);
29462+ if (unlikely(err))
29463+ si_write_unlock(sb);
29464+
29465+ return err;
29466+}
29467+
1facf9fc 29468+/* dentry and super_block lock. call at entry point */
e49829fe 29469+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 29470+{
e49829fe 29471+ int err;
027c5e7a 29472+ struct super_block *sb;
e49829fe 29473+
027c5e7a
AM
29474+ sb = dentry->d_sb;
29475+ err = si_read_lock(sb, flags);
29476+ if (unlikely(err))
29477+ goto out;
29478+
29479+ if (au_ftest_lock(flags, DW))
29480+ di_write_lock_child(dentry);
29481+ else
29482+ di_read_lock_child(dentry, flags);
29483+
29484+ if (au_ftest_lock(flags, GEN)) {
29485+ err = au_digen_test(dentry, au_sigen(sb));
79b8bda9
AM
29486+ if (!au_opt_test(au_mntflags(sb), UDBA_NONE))
29487+ AuDebugOn(!err && au_dbrange_test(dentry));
29488+ else if (!err)
29489+ err = au_dbrange_test(dentry);
027c5e7a
AM
29490+ if (unlikely(err))
29491+ aufs_read_unlock(dentry, flags);
e49829fe
JR
29492+ }
29493+
027c5e7a 29494+out:
e49829fe 29495+ return err;
1facf9fc 29496+}
29497+
29498+void aufs_read_unlock(struct dentry *dentry, int flags)
29499+{
29500+ if (au_ftest_lock(flags, DW))
29501+ di_write_unlock(dentry);
29502+ else
29503+ di_read_unlock(dentry, flags);
29504+ si_read_unlock(dentry->d_sb);
29505+}
29506+
29507+void aufs_write_lock(struct dentry *dentry)
29508+{
e49829fe 29509+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 29510+ di_write_lock_child(dentry);
29511+}
29512+
29513+void aufs_write_unlock(struct dentry *dentry)
29514+{
29515+ di_write_unlock(dentry);
29516+ si_write_unlock(dentry->d_sb);
29517+}
29518+
e49829fe 29519+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 29520+{
e49829fe 29521+ int err;
027c5e7a
AM
29522+ unsigned int sigen;
29523+ struct super_block *sb;
e49829fe 29524+
027c5e7a
AM
29525+ sb = d1->d_sb;
29526+ err = si_read_lock(sb, flags);
29527+ if (unlikely(err))
29528+ goto out;
29529+
b95c5147 29530+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS));
027c5e7a
AM
29531+
29532+ if (au_ftest_lock(flags, GEN)) {
29533+ sigen = au_sigen(sb);
29534+ err = au_digen_test(d1, sigen);
29535+ AuDebugOn(!err && au_dbrange_test(d1));
29536+ if (!err) {
29537+ err = au_digen_test(d2, sigen);
29538+ AuDebugOn(!err && au_dbrange_test(d2));
29539+ }
29540+ if (unlikely(err))
29541+ aufs_read_and_write_unlock2(d1, d2);
29542+ }
29543+
29544+out:
e49829fe 29545+ return err;
1facf9fc 29546+}
29547+
29548+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
29549+{
29550+ di_write_unlock2(d1, d2);
29551+ si_read_unlock(d1->d_sb);
29552+}
7f207e10
AM
29553diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
29554--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
29555+++ linux/fs/aufs/super.c 2019-05-06 09:03:04.820143837 +0200
29556@@ -0,0 +1,1049 @@
cd7a4cd9 29557+// SPDX-License-Identifier: GPL-2.0
1facf9fc 29558+/*
ba1aed25 29559+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 29560+ *
29561+ * This program, aufs is free software; you can redistribute it and/or modify
29562+ * it under the terms of the GNU General Public License as published by
29563+ * the Free Software Foundation; either version 2 of the License, or
29564+ * (at your option) any later version.
dece6358
AM
29565+ *
29566+ * This program is distributed in the hope that it will be useful,
29567+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29568+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29569+ * GNU General Public License for more details.
29570+ *
29571+ * You should have received a copy of the GNU General Public License
523b37e3 29572+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29573+ */
29574+
29575+/*
29576+ * mount and super_block operations
29577+ */
29578+
eca801bf 29579+#include <linux/iversion.h>
f6c5ef8b 29580+#include <linux/mm.h>
1facf9fc 29581+#include <linux/seq_file.h>
29582+#include <linux/statfs.h>
7f207e10 29583+#include <linux/vmalloc.h>
1facf9fc 29584+#include "aufs.h"
29585+
29586+/*
29587+ * super_operations
29588+ */
29589+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
29590+{
29591+ struct au_icntnr *c;
29592+
29593+ c = au_cache_alloc_icntnr();
29594+ if (c) {
027c5e7a 29595+ au_icntnr_init(c);
be118d29 29596+ inode_set_iversion(&c->vfs_inode, 1); /* sigen(sb); */
1facf9fc 29597+ c->iinfo.ii_hinode = NULL;
29598+ return &c->vfs_inode;
29599+ }
29600+ return NULL;
29601+}
29602+
027c5e7a
AM
29603+static void aufs_destroy_inode_cb(struct rcu_head *head)
29604+{
29605+ struct inode *inode = container_of(head, struct inode, i_rcu);
29606+
1c60b727 29607+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
027c5e7a
AM
29608+}
29609+
1facf9fc 29610+static void aufs_destroy_inode(struct inode *inode)
29611+{
5afbbe0d
AM
29612+ if (!au_is_bad_inode(inode))
29613+ au_iinfo_fin(inode);
027c5e7a 29614+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 29615+}
29616+
29617+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
29618+{
29619+ struct inode *inode;
29620+ int err;
29621+
29622+ inode = iget_locked(sb, ino);
29623+ if (unlikely(!inode)) {
29624+ inode = ERR_PTR(-ENOMEM);
29625+ goto out;
29626+ }
29627+ if (!(inode->i_state & I_NEW))
29628+ goto out;
29629+
29630+ err = au_xigen_new(inode);
29631+ if (!err)
29632+ err = au_iinfo_init(inode);
29633+ if (!err)
be118d29 29634+ inode_inc_iversion(inode);
1facf9fc 29635+ else {
29636+ iget_failed(inode);
29637+ inode = ERR_PTR(err);
29638+ }
29639+
4f0767ce 29640+out:
1facf9fc 29641+ /* never return NULL */
29642+ AuDebugOn(!inode);
29643+ AuTraceErrPtr(inode);
29644+ return inode;
29645+}
29646+
29647+/* lock free root dinfo */
29648+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
29649+{
29650+ int err;
5afbbe0d 29651+ aufs_bindex_t bindex, bbot;
1facf9fc 29652+ struct path path;
4a4d8108 29653+ struct au_hdentry *hdp;
1facf9fc 29654+ struct au_branch *br;
076b876e 29655+ au_br_perm_str_t perm;
1facf9fc 29656+
29657+ err = 0;
5afbbe0d
AM
29658+ bbot = au_sbbot(sb);
29659+ bindex = 0;
29660+ hdp = au_hdentry(au_di(sb->s_root), bindex);
29661+ for (; !err && bindex <= bbot; bindex++, hdp++) {
1facf9fc 29662+ br = au_sbr(sb, bindex);
86dc4139 29663+ path.mnt = au_br_mnt(br);
5afbbe0d 29664+ path.dentry = hdp->hd_dentry;
1facf9fc 29665+ err = au_seq_path(seq, &path);
79b8bda9 29666+ if (!err) {
076b876e 29667+ au_optstr_br_perm(&perm, br->br_perm);
79b8bda9 29668+ seq_printf(seq, "=%s", perm.a);
5afbbe0d 29669+ if (bindex != bbot)
79b8bda9 29670+ seq_putc(seq, ':');
1e00d052 29671+ }
1facf9fc 29672+ }
79b8bda9
AM
29673+ if (unlikely(err || seq_has_overflowed(seq)))
29674+ err = -E2BIG;
1facf9fc 29675+
29676+ return err;
29677+}
29678+
f2c43d5f
AM
29679+static void au_gen_fmt(char *fmt, int len __maybe_unused, const char *pat,
29680+ const char *append)
29681+{
29682+ char *p;
29683+
29684+ p = fmt;
29685+ while (*pat != ':')
29686+ *p++ = *pat++;
29687+ *p++ = *pat++;
29688+ strcpy(p, append);
29689+ AuDebugOn(strlen(fmt) >= len);
29690+}
29691+
1facf9fc 29692+static void au_show_wbr_create(struct seq_file *m, int v,
29693+ struct au_sbinfo *sbinfo)
29694+{
29695+ const char *pat;
f2c43d5f
AM
29696+ char fmt[32];
29697+ struct au_wbr_mfs *mfs;
1facf9fc 29698+
dece6358
AM
29699+ AuRwMustAnyLock(&sbinfo->si_rwsem);
29700+
c2b27bf2 29701+ seq_puts(m, ",create=");
1facf9fc 29702+ pat = au_optstr_wbr_create(v);
f2c43d5f 29703+ mfs = &sbinfo->si_wbr_mfs;
1facf9fc 29704+ switch (v) {
29705+ case AuWbrCreate_TDP:
29706+ case AuWbrCreate_RR:
29707+ case AuWbrCreate_MFS:
29708+ case AuWbrCreate_PMFS:
c2b27bf2 29709+ seq_puts(m, pat);
1facf9fc 29710+ break;
f2c43d5f
AM
29711+ case AuWbrCreate_MFSRR:
29712+ case AuWbrCreate_TDMFS:
29713+ case AuWbrCreate_PMFSRR:
29714+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu");
29715+ seq_printf(m, fmt, mfs->mfsrr_watermark);
1facf9fc 29716+ break;
f2c43d5f 29717+ case AuWbrCreate_MFSV:
1facf9fc 29718+ case AuWbrCreate_PMFSV:
f2c43d5f
AM
29719+ au_gen_fmt(fmt, sizeof(fmt), pat, "%lu");
29720+ seq_printf(m, fmt,
29721+ jiffies_to_msecs(mfs->mfs_expire)
e49829fe 29722+ / MSEC_PER_SEC);
1facf9fc 29723+ break;
1facf9fc 29724+ case AuWbrCreate_MFSRRV:
f2c43d5f 29725+ case AuWbrCreate_TDMFSV:
392086de 29726+ case AuWbrCreate_PMFSRRV:
f2c43d5f
AM
29727+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu:%lu");
29728+ seq_printf(m, fmt, mfs->mfsrr_watermark,
29729+ jiffies_to_msecs(mfs->mfs_expire) / MSEC_PER_SEC);
392086de 29730+ break;
f2c43d5f
AM
29731+ default:
29732+ BUG();
1facf9fc 29733+ }
29734+}
29735+
7eafdf33 29736+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 29737+{
29738+#ifdef CONFIG_SYSFS
29739+ return 0;
29740+#else
29741+ int err;
29742+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
29743+ aufs_bindex_t bindex, brid;
1facf9fc 29744+ struct qstr *name;
29745+ struct file *f;
29746+ struct dentry *d, *h_root;
acd2b654 29747+ struct au_branch *br;
1facf9fc 29748+
dece6358
AM
29749+ AuRwMustAnyLock(&sbinfo->si_rwsem);
29750+
1facf9fc 29751+ err = 0;
1facf9fc 29752+ f = au_sbi(sb)->si_xib;
29753+ if (!f)
29754+ goto out;
29755+
29756+ /* stop printing the default xino path on the first writable branch */
29757+ h_root = NULL;
acd2b654
AM
29758+ bindex = au_xi_root(sb, f->f_path.dentry);
29759+ if (bindex >= 0) {
29760+ br = au_sbr_sb(sb, bindex);
29761+ h_root = au_br_dentry(br);
1facf9fc 29762+ }
acd2b654 29763+
2000de60 29764+ d = f->f_path.dentry;
1facf9fc 29765+ name = &d->d_name;
29766+ /* safe ->d_parent because the file is unlinked */
29767+ if (d->d_parent == h_root
29768+ && name->len == len
29769+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
29770+ goto out;
29771+
29772+ seq_puts(seq, ",xino=");
29773+ err = au_xino_path(seq, f);
29774+
4f0767ce 29775+out:
1facf9fc 29776+ return err;
29777+#endif
29778+}
29779+
29780+/* seq_file will re-call me in case of too long string */
7eafdf33 29781+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 29782+{
027c5e7a 29783+ int err;
1facf9fc 29784+ unsigned int mnt_flags, v;
29785+ struct super_block *sb;
29786+ struct au_sbinfo *sbinfo;
29787+
29788+#define AuBool(name, str) do { \
29789+ v = au_opt_test(mnt_flags, name); \
29790+ if (v != au_opt_test(AuOpt_Def, name)) \
29791+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
29792+} while (0)
29793+
29794+#define AuStr(name, str) do { \
29795+ v = mnt_flags & AuOptMask_##name; \
29796+ if (v != (AuOpt_Def & AuOptMask_##name)) \
29797+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
29798+} while (0)
29799+
29800+#define AuUInt(name, str, val) do { \
29801+ if (val != AUFS_##name##_DEF) \
29802+ seq_printf(m, "," #str "=%u", val); \
29803+} while (0)
29804+
7eafdf33 29805+ sb = dentry->d_sb;
2121bcd9 29806+ if (sb->s_flags & SB_POSIXACL)
c1595e42 29807+ seq_puts(m, ",acl");
be118d29
JR
29808+#if 0
29809+ if (sb->s_flags & SB_I_VERSION)
29810+ seq_puts(m, ",i_version");
29811+#endif
c1595e42
JR
29812+
29813+ /* lock free root dinfo */
1facf9fc 29814+ si_noflush_read_lock(sb);
29815+ sbinfo = au_sbi(sb);
29816+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
29817+
29818+ mnt_flags = au_mntflags(sb);
29819+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 29820+ err = au_show_xino(m, sb);
1facf9fc 29821+ if (unlikely(err))
29822+ goto out;
29823+ } else
29824+ seq_puts(m, ",noxino");
29825+
29826+ AuBool(TRUNC_XINO, trunc_xino);
29827+ AuStr(UDBA, udba);
dece6358 29828+ AuBool(SHWH, shwh);
1facf9fc 29829+ AuBool(PLINK, plink);
4a4d8108 29830+ AuBool(DIO, dio);
076b876e 29831+ AuBool(DIRPERM1, dirperm1);
1facf9fc 29832+
29833+ v = sbinfo->si_wbr_create;
29834+ if (v != AuWbrCreate_Def)
29835+ au_show_wbr_create(m, v, sbinfo);
29836+
29837+ v = sbinfo->si_wbr_copyup;
29838+ if (v != AuWbrCopyup_Def)
29839+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
29840+
29841+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
29842+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
29843+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
29844+
29845+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
29846+
027c5e7a
AM
29847+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
29848+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 29849+
29850+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
29851+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
29852+
076b876e
AM
29853+ au_fhsm_show(m, sbinfo);
29854+
8b6a4947 29855+ AuBool(DIRREN, dirren);
1facf9fc 29856+ AuBool(SUM, sum);
29857+ /* AuBool(SUM_W, wsum); */
29858+ AuBool(WARN_PERM, warn_perm);
29859+ AuBool(VERBOSE, verbose);
29860+
4f0767ce 29861+out:
1facf9fc 29862+ /* be sure to print "br:" last */
29863+ if (!sysaufs_brs) {
29864+ seq_puts(m, ",br:");
29865+ au_show_brs(m, sb);
29866+ }
29867+ si_read_unlock(sb);
29868+ return 0;
29869+
1facf9fc 29870+#undef AuBool
29871+#undef AuStr
4a4d8108 29872+#undef AuUInt
1facf9fc 29873+}
29874+
29875+/* ---------------------------------------------------------------------- */
29876+
29877+/* sum mode which returns the summation for statfs(2) */
29878+
29879+static u64 au_add_till_max(u64 a, u64 b)
29880+{
29881+ u64 old;
29882+
29883+ old = a;
29884+ a += b;
92d182d2
AM
29885+ if (old <= a)
29886+ return a;
29887+ return ULLONG_MAX;
29888+}
29889+
29890+static u64 au_mul_till_max(u64 a, long mul)
29891+{
29892+ u64 old;
29893+
29894+ old = a;
29895+ a *= mul;
29896+ if (old <= a)
1facf9fc 29897+ return a;
29898+ return ULLONG_MAX;
29899+}
29900+
29901+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
29902+{
29903+ int err;
92d182d2 29904+ long bsize, factor;
1facf9fc 29905+ u64 blocks, bfree, bavail, files, ffree;
5afbbe0d 29906+ aufs_bindex_t bbot, bindex, i;
1facf9fc 29907+ unsigned char shared;
7f207e10 29908+ struct path h_path;
1facf9fc 29909+ struct super_block *h_sb;
29910+
92d182d2
AM
29911+ err = 0;
29912+ bsize = LONG_MAX;
29913+ files = 0;
29914+ ffree = 0;
1facf9fc 29915+ blocks = 0;
29916+ bfree = 0;
29917+ bavail = 0;
5afbbe0d
AM
29918+ bbot = au_sbbot(sb);
29919+ for (bindex = 0; bindex <= bbot; bindex++) {
7f207e10
AM
29920+ h_path.mnt = au_sbr_mnt(sb, bindex);
29921+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 29922+ shared = 0;
92d182d2 29923+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 29924+ shared = (au_sbr_sb(sb, i) == h_sb);
29925+ if (shared)
29926+ continue;
29927+
29928+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
29929+ h_path.dentry = h_path.mnt->mnt_root;
29930+ err = vfs_statfs(&h_path, buf);
1facf9fc 29931+ if (unlikely(err))
29932+ goto out;
29933+
92d182d2
AM
29934+ if (bsize > buf->f_bsize) {
29935+ /*
29936+ * we will reduce bsize, so we have to expand blocks
29937+ * etc. to match them again
29938+ */
29939+ factor = (bsize / buf->f_bsize);
29940+ blocks = au_mul_till_max(blocks, factor);
29941+ bfree = au_mul_till_max(bfree, factor);
29942+ bavail = au_mul_till_max(bavail, factor);
29943+ bsize = buf->f_bsize;
29944+ }
29945+
29946+ factor = (buf->f_bsize / bsize);
29947+ blocks = au_add_till_max(blocks,
29948+ au_mul_till_max(buf->f_blocks, factor));
29949+ bfree = au_add_till_max(bfree,
29950+ au_mul_till_max(buf->f_bfree, factor));
29951+ bavail = au_add_till_max(bavail,
29952+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 29953+ files = au_add_till_max(files, buf->f_files);
29954+ ffree = au_add_till_max(ffree, buf->f_ffree);
29955+ }
29956+
92d182d2 29957+ buf->f_bsize = bsize;
1facf9fc 29958+ buf->f_blocks = blocks;
29959+ buf->f_bfree = bfree;
29960+ buf->f_bavail = bavail;
29961+ buf->f_files = files;
29962+ buf->f_ffree = ffree;
92d182d2 29963+ buf->f_frsize = 0;
1facf9fc 29964+
4f0767ce 29965+out:
1facf9fc 29966+ return err;
29967+}
29968+
29969+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
29970+{
29971+ int err;
7f207e10 29972+ struct path h_path;
1facf9fc 29973+ struct super_block *sb;
29974+
29975+ /* lock free root dinfo */
29976+ sb = dentry->d_sb;
29977+ si_noflush_read_lock(sb);
7f207e10 29978+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 29979+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
29980+ h_path.mnt = au_sbr_mnt(sb, 0);
29981+ h_path.dentry = h_path.mnt->mnt_root;
29982+ err = vfs_statfs(&h_path, buf);
29983+ } else
1facf9fc 29984+ err = au_statfs_sum(sb, buf);
29985+ si_read_unlock(sb);
29986+
29987+ if (!err) {
29988+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 29989+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 29990+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
29991+ }
29992+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
29993+
29994+ return err;
29995+}
29996+
29997+/* ---------------------------------------------------------------------- */
29998+
537831f9
AM
29999+static int aufs_sync_fs(struct super_block *sb, int wait)
30000+{
30001+ int err, e;
5afbbe0d 30002+ aufs_bindex_t bbot, bindex;
537831f9
AM
30003+ struct au_branch *br;
30004+ struct super_block *h_sb;
30005+
30006+ err = 0;
30007+ si_noflush_read_lock(sb);
5afbbe0d
AM
30008+ bbot = au_sbbot(sb);
30009+ for (bindex = 0; bindex <= bbot; bindex++) {
537831f9
AM
30010+ br = au_sbr(sb, bindex);
30011+ if (!au_br_writable(br->br_perm))
30012+ continue;
30013+
30014+ h_sb = au_sbr_sb(sb, bindex);
a2654f78
AM
30015+ e = vfsub_sync_filesystem(h_sb, wait);
30016+ if (unlikely(e && !err))
30017+ err = e;
30018+ /* go on even if an error happens */
537831f9
AM
30019+ }
30020+ si_read_unlock(sb);
30021+
30022+ return err;
30023+}
30024+
30025+/* ---------------------------------------------------------------------- */
30026+
1facf9fc 30027+/* final actions when unmounting a file system */
30028+static void aufs_put_super(struct super_block *sb)
30029+{
30030+ struct au_sbinfo *sbinfo;
30031+
30032+ sbinfo = au_sbi(sb);
062440b3
AM
30033+ if (sbinfo)
30034+ kobject_put(&sbinfo->si_kobj);
1facf9fc 30035+}
30036+
30037+/* ---------------------------------------------------------------------- */
30038+
79b8bda9
AM
30039+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
30040+ struct super_block *sb, void *arg)
7f207e10
AM
30041+{
30042+ void *array;
076b876e 30043+ unsigned long long n, sz;
7f207e10
AM
30044+
30045+ array = NULL;
30046+ n = 0;
30047+ if (!*hint)
30048+ goto out;
30049+
30050+ if (*hint > ULLONG_MAX / sizeof(array)) {
30051+ array = ERR_PTR(-EMFILE);
30052+ pr_err("hint %llu\n", *hint);
30053+ goto out;
30054+ }
30055+
076b876e
AM
30056+ sz = sizeof(array) * *hint;
30057+ array = kzalloc(sz, GFP_NOFS);
7f207e10 30058+ if (unlikely(!array))
076b876e 30059+ array = vzalloc(sz);
7f207e10
AM
30060+ if (unlikely(!array)) {
30061+ array = ERR_PTR(-ENOMEM);
30062+ goto out;
30063+ }
30064+
79b8bda9 30065+ n = cb(sb, array, *hint, arg);
7f207e10
AM
30066+ AuDebugOn(n > *hint);
30067+
30068+out:
30069+ *hint = n;
30070+ return array;
30071+}
30072+
79b8bda9 30073+static unsigned long long au_iarray_cb(struct super_block *sb, void *a,
7f207e10
AM
30074+ unsigned long long max __maybe_unused,
30075+ void *arg)
30076+{
30077+ unsigned long long n;
30078+ struct inode **p, *inode;
30079+ struct list_head *head;
30080+
30081+ n = 0;
30082+ p = a;
30083+ head = arg;
79b8bda9 30084+ spin_lock(&sb->s_inode_list_lock);
7f207e10 30085+ list_for_each_entry(inode, head, i_sb_list) {
5afbbe0d
AM
30086+ if (!au_is_bad_inode(inode)
30087+ && au_ii(inode)->ii_btop >= 0) {
2cbb1c4b
JR
30088+ spin_lock(&inode->i_lock);
30089+ if (atomic_read(&inode->i_count)) {
30090+ au_igrab(inode);
30091+ *p++ = inode;
30092+ n++;
30093+ AuDebugOn(n > max);
30094+ }
30095+ spin_unlock(&inode->i_lock);
7f207e10
AM
30096+ }
30097+ }
79b8bda9 30098+ spin_unlock(&sb->s_inode_list_lock);
7f207e10
AM
30099+
30100+ return n;
30101+}
30102+
30103+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
30104+{
acd2b654
AM
30105+ struct au_sbinfo *sbi;
30106+
30107+ sbi = au_sbi(sb);
30108+ *max = au_lcnt_read(&sbi->si_ninodes, /*do_rev*/1);
79b8bda9 30109+ return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes);
7f207e10
AM
30110+}
30111+
30112+void au_iarray_free(struct inode **a, unsigned long long max)
30113+{
30114+ unsigned long long ull;
30115+
30116+ for (ull = 0; ull < max; ull++)
30117+ iput(a[ull]);
be52b249 30118+ kvfree(a);
7f207e10
AM
30119+}
30120+
30121+/* ---------------------------------------------------------------------- */
30122+
1facf9fc 30123+/*
30124+ * refresh dentry and inode at remount time.
30125+ */
027c5e7a
AM
30126+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
30127+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
30128+ struct dentry *parent)
1facf9fc 30129+{
30130+ int err;
1facf9fc 30131+
30132+ di_write_lock_child(dentry);
1facf9fc 30133+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
30134+ err = au_refresh_dentry(dentry, parent);
30135+ if (!err && dir_flags)
5527c038 30136+ au_hn_reset(d_inode(dentry), dir_flags);
1facf9fc 30137+ di_read_unlock(parent, AuLock_IR);
1facf9fc 30138+ di_write_unlock(dentry);
30139+
30140+ return err;
30141+}
30142+
027c5e7a
AM
30143+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
30144+ struct au_sbinfo *sbinfo,
b95c5147 30145+ const unsigned int dir_flags, unsigned int do_idop)
1facf9fc 30146+{
027c5e7a
AM
30147+ int err;
30148+ struct dentry *parent;
027c5e7a
AM
30149+
30150+ err = 0;
30151+ parent = dget_parent(dentry);
30152+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
5527c038
JR
30153+ if (d_really_is_positive(dentry)) {
30154+ if (!d_is_dir(dentry))
027c5e7a
AM
30155+ err = au_do_refresh(dentry, /*dir_flags*/0,
30156+ parent);
30157+ else {
30158+ err = au_do_refresh(dentry, dir_flags, parent);
30159+ if (unlikely(err))
30160+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
30161+ }
30162+ } else
30163+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
30164+ AuDbgDentry(dentry);
30165+ }
30166+ dput(parent);
30167+
79b8bda9 30168+ if (!err) {
b95c5147 30169+ if (do_idop)
79b8bda9
AM
30170+ au_refresh_dop(dentry, /*force_reval*/0);
30171+ } else
30172+ au_refresh_dop(dentry, /*force_reval*/1);
30173+
027c5e7a
AM
30174+ AuTraceErr(err);
30175+ return err;
1facf9fc 30176+}
30177+
b95c5147 30178+static int au_refresh_d(struct super_block *sb, unsigned int do_idop)
1facf9fc 30179+{
30180+ int err, i, j, ndentry, e;
027c5e7a 30181+ unsigned int sigen;
1facf9fc 30182+ struct au_dcsub_pages dpages;
30183+ struct au_dpage *dpage;
027c5e7a
AM
30184+ struct dentry **dentries, *d;
30185+ struct au_sbinfo *sbinfo;
30186+ struct dentry *root = sb->s_root;
5527c038 30187+ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
1facf9fc 30188+
b95c5147 30189+ if (do_idop)
79b8bda9
AM
30190+ au_refresh_dop(root, /*force_reval*/0);
30191+
027c5e7a
AM
30192+ err = au_dpages_init(&dpages, GFP_NOFS);
30193+ if (unlikely(err))
1facf9fc 30194+ goto out;
027c5e7a
AM
30195+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
30196+ if (unlikely(err))
1facf9fc 30197+ goto out_dpages;
1facf9fc 30198+
027c5e7a
AM
30199+ sigen = au_sigen(sb);
30200+ sbinfo = au_sbi(sb);
30201+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 30202+ dpage = dpages.dpages + i;
30203+ dentries = dpage->dentries;
30204+ ndentry = dpage->ndentry;
027c5e7a 30205+ for (j = 0; j < ndentry; j++) {
1facf9fc 30206+ d = dentries[j];
79b8bda9 30207+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
b95c5147 30208+ do_idop);
027c5e7a
AM
30209+ if (unlikely(e && !err))
30210+ err = e;
30211+ /* go on even err */
1facf9fc 30212+ }
30213+ }
30214+
4f0767ce 30215+out_dpages:
1facf9fc 30216+ au_dpages_free(&dpages);
4f0767ce 30217+out:
1facf9fc 30218+ return err;
30219+}
30220+
b95c5147 30221+static int au_refresh_i(struct super_block *sb, unsigned int do_idop)
1facf9fc 30222+{
027c5e7a
AM
30223+ int err, e;
30224+ unsigned int sigen;
30225+ unsigned long long max, ull;
30226+ struct inode *inode, **array;
1facf9fc 30227+
027c5e7a
AM
30228+ array = au_iarray_alloc(sb, &max);
30229+ err = PTR_ERR(array);
30230+ if (IS_ERR(array))
30231+ goto out;
1facf9fc 30232+
30233+ err = 0;
027c5e7a
AM
30234+ sigen = au_sigen(sb);
30235+ for (ull = 0; ull < max; ull++) {
30236+ inode = array[ull];
076b876e
AM
30237+ if (unlikely(!inode))
30238+ break;
b95c5147
AM
30239+
30240+ e = 0;
30241+ ii_write_lock_child(inode);
537831f9 30242+ if (au_iigen(inode, NULL) != sigen) {
027c5e7a 30243+ e = au_refresh_hinode_self(inode);
1facf9fc 30244+ if (unlikely(e)) {
b95c5147 30245+ au_refresh_iop(inode, /*force_getattr*/1);
027c5e7a 30246+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 30247+ if (!err)
30248+ err = e;
30249+ /* go on even if err */
30250+ }
30251+ }
b95c5147
AM
30252+ if (!e && do_idop)
30253+ au_refresh_iop(inode, /*force_getattr*/0);
30254+ ii_write_unlock(inode);
1facf9fc 30255+ }
30256+
027c5e7a 30257+ au_iarray_free(array, max);
1facf9fc 30258+
4f0767ce 30259+out:
1facf9fc 30260+ return err;
30261+}
30262+
b95c5147 30263+static void au_remount_refresh(struct super_block *sb, unsigned int do_idop)
1facf9fc 30264+{
027c5e7a
AM
30265+ int err, e;
30266+ unsigned int udba;
5afbbe0d 30267+ aufs_bindex_t bindex, bbot;
1facf9fc 30268+ struct dentry *root;
30269+ struct inode *inode;
027c5e7a 30270+ struct au_branch *br;
79b8bda9 30271+ struct au_sbinfo *sbi;
1facf9fc 30272+
30273+ au_sigen_inc(sb);
79b8bda9
AM
30274+ sbi = au_sbi(sb);
30275+ au_fclr_si(sbi, FAILED_REFRESH_DIR);
1facf9fc 30276+
30277+ root = sb->s_root;
30278+ DiMustNoWaiters(root);
5527c038 30279+ inode = d_inode(root);
1facf9fc 30280+ IiMustNoWaiters(inode);
1facf9fc 30281+
027c5e7a 30282+ udba = au_opt_udba(sb);
5afbbe0d
AM
30283+ bbot = au_sbbot(sb);
30284+ for (bindex = 0; bindex <= bbot; bindex++) {
027c5e7a
AM
30285+ br = au_sbr(sb, bindex);
30286+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 30287+ if (unlikely(err))
027c5e7a
AM
30288+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
30289+ bindex, err);
30290+ /* go on even if err */
1facf9fc 30291+ }
027c5e7a 30292+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 30293+
b95c5147 30294+ if (do_idop) {
79b8bda9
AM
30295+ if (au_ftest_si(sbi, NO_DREVAL)) {
30296+ AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
30297+ sb->s_d_op = &aufs_dop_noreval;
b95c5147
AM
30298+ AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr);
30299+ sbi->si_iop_array = aufs_iop_nogetattr;
79b8bda9
AM
30300+ } else {
30301+ AuDebugOn(sb->s_d_op == &aufs_dop);
30302+ sb->s_d_op = &aufs_dop;
b95c5147
AM
30303+ AuDebugOn(sbi->si_iop_array == aufs_iop);
30304+ sbi->si_iop_array = aufs_iop;
79b8bda9 30305+ }
062440b3 30306+ pr_info("reset to %ps and %ps\n",
b95c5147 30307+ sb->s_d_op, sbi->si_iop_array);
79b8bda9
AM
30308+ }
30309+
027c5e7a 30310+ di_write_unlock(root);
b95c5147
AM
30311+ err = au_refresh_d(sb, do_idop);
30312+ e = au_refresh_i(sb, do_idop);
027c5e7a
AM
30313+ if (unlikely(e && !err))
30314+ err = e;
1facf9fc 30315+ /* aufs_write_lock() calls ..._child() */
30316+ di_write_lock_child(root);
027c5e7a
AM
30317+
30318+ au_cpup_attr_all(inode, /*force*/1);
30319+
30320+ if (unlikely(err))
30321+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 30322+}
30323+
30324+/* stop extra interpretation of errno in mount(8), and strange error messages */
30325+static int cvt_err(int err)
30326+{
30327+ AuTraceErr(err);
30328+
30329+ switch (err) {
30330+ case -ENOENT:
30331+ case -ENOTDIR:
30332+ case -EEXIST:
30333+ case -EIO:
30334+ err = -EINVAL;
30335+ }
30336+ return err;
30337+}
30338+
30339+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
30340+{
4a4d8108
AM
30341+ int err, do_dx;
30342+ unsigned int mntflags;
be52b249
AM
30343+ struct au_opts opts = {
30344+ .opt = NULL
30345+ };
1facf9fc 30346+ struct dentry *root;
30347+ struct inode *inode;
30348+ struct au_sbinfo *sbinfo;
30349+
30350+ err = 0;
30351+ root = sb->s_root;
30352+ if (!data || !*data) {
e49829fe
JR
30353+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
30354+ if (!err) {
30355+ di_write_lock_child(root);
30356+ err = au_opts_verify(sb, *flags, /*pending*/0);
30357+ aufs_write_unlock(root);
30358+ }
1facf9fc 30359+ goto out;
30360+ }
30361+
30362+ err = -ENOMEM;
1facf9fc 30363+ opts.opt = (void *)__get_free_page(GFP_NOFS);
30364+ if (unlikely(!opts.opt))
30365+ goto out;
30366+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
30367+ opts.flags = AuOpts_REMOUNT;
30368+ opts.sb_flags = *flags;
30369+
30370+ /* parse it before aufs lock */
30371+ err = au_opts_parse(sb, data, &opts);
30372+ if (unlikely(err))
30373+ goto out_opts;
30374+
30375+ sbinfo = au_sbi(sb);
5527c038 30376+ inode = d_inode(root);
febd17d6 30377+ inode_lock(inode);
e49829fe
JR
30378+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
30379+ if (unlikely(err))
30380+ goto out_mtx;
30381+ di_write_lock_child(root);
1facf9fc 30382+
30383+ /* au_opts_remount() may return an error */
30384+ err = au_opts_remount(sb, &opts);
30385+ au_opts_free(&opts);
30386+
027c5e7a 30387+ if (au_ftest_opts(opts.flags, REFRESH))
b95c5147 30388+ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP));
1facf9fc 30389+
4a4d8108
AM
30390+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
30391+ mntflags = au_mntflags(sb);
30392+ do_dx = !!au_opt_test(mntflags, DIO);
30393+ au_dy_arefresh(do_dx);
30394+ }
30395+
076b876e 30396+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
1facf9fc 30397+ aufs_write_unlock(root);
953406b4 30398+
e49829fe 30399+out_mtx:
febd17d6 30400+ inode_unlock(inode);
4f0767ce 30401+out_opts:
1c60b727 30402+ free_page((unsigned long)opts.opt);
4f0767ce 30403+out:
1facf9fc 30404+ err = cvt_err(err);
30405+ AuTraceErr(err);
30406+ return err;
30407+}
30408+
4a4d8108 30409+static const struct super_operations aufs_sop = {
1facf9fc 30410+ .alloc_inode = aufs_alloc_inode,
30411+ .destroy_inode = aufs_destroy_inode,
b752ccd1 30412+ /* always deleting, no clearing */
1facf9fc 30413+ .drop_inode = generic_delete_inode,
30414+ .show_options = aufs_show_options,
30415+ .statfs = aufs_statfs,
30416+ .put_super = aufs_put_super,
537831f9 30417+ .sync_fs = aufs_sync_fs,
1facf9fc 30418+ .remount_fs = aufs_remount_fs
30419+};
30420+
30421+/* ---------------------------------------------------------------------- */
30422+
30423+static int alloc_root(struct super_block *sb)
30424+{
30425+ int err;
30426+ struct inode *inode;
30427+ struct dentry *root;
30428+
30429+ err = -ENOMEM;
30430+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
30431+ err = PTR_ERR(inode);
30432+ if (IS_ERR(inode))
30433+ goto out;
30434+
b95c5147 30435+ inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */
1facf9fc 30436+ inode->i_fop = &aufs_dir_fop;
30437+ inode->i_mode = S_IFDIR;
9dbd164d 30438+ set_nlink(inode, 2);
1facf9fc 30439+ unlock_new_inode(inode);
30440+
92d182d2 30441+ root = d_make_root(inode);
1facf9fc 30442+ if (unlikely(!root))
92d182d2 30443+ goto out;
1facf9fc 30444+ err = PTR_ERR(root);
30445+ if (IS_ERR(root))
92d182d2 30446+ goto out;
1facf9fc 30447+
4a4d8108 30448+ err = au_di_init(root);
1facf9fc 30449+ if (!err) {
30450+ sb->s_root = root;
30451+ return 0; /* success */
30452+ }
30453+ dput(root);
1facf9fc 30454+
4f0767ce 30455+out:
1facf9fc 30456+ return err;
1facf9fc 30457+}
30458+
30459+static int aufs_fill_super(struct super_block *sb, void *raw_data,
30460+ int silent __maybe_unused)
30461+{
30462+ int err;
be52b249
AM
30463+ struct au_opts opts = {
30464+ .opt = NULL
30465+ };
79b8bda9 30466+ struct au_sbinfo *sbinfo;
1facf9fc 30467+ struct dentry *root;
30468+ struct inode *inode;
30469+ char *arg = raw_data;
30470+
30471+ if (unlikely(!arg || !*arg)) {
30472+ err = -EINVAL;
4a4d8108 30473+ pr_err("no arg\n");
1facf9fc 30474+ goto out;
30475+ }
30476+
30477+ err = -ENOMEM;
1facf9fc 30478+ opts.opt = (void *)__get_free_page(GFP_NOFS);
30479+ if (unlikely(!opts.opt))
30480+ goto out;
30481+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
30482+ opts.sb_flags = sb->s_flags;
30483+
30484+ err = au_si_alloc(sb);
30485+ if (unlikely(err))
30486+ goto out_opts;
79b8bda9 30487+ sbinfo = au_sbi(sb);
1facf9fc 30488+
30489+ /* all timestamps always follow the ones on the branch */
2121bcd9 30490+ sb->s_flags |= SB_NOATIME | SB_NODIRATIME;
be118d29 30491+ sb->s_flags |= SB_I_VERSION; /* do we really need this? */
1facf9fc 30492+ sb->s_op = &aufs_sop;
027c5e7a 30493+ sb->s_d_op = &aufs_dop;
1facf9fc 30494+ sb->s_magic = AUFS_SUPER_MAGIC;
30495+ sb->s_maxbytes = 0;
c1595e42 30496+ sb->s_stack_depth = 1;
1facf9fc 30497+ au_export_init(sb);
f2c43d5f 30498+ au_xattr_init(sb);
1facf9fc 30499+
30500+ err = alloc_root(sb);
30501+ if (unlikely(err)) {
30502+ si_write_unlock(sb);
30503+ goto out_info;
30504+ }
30505+ root = sb->s_root;
5527c038 30506+ inode = d_inode(root);
1facf9fc 30507+
30508+ /*
30509+ * actually we can parse options regardless aufs lock here.
30510+ * but at remount time, parsing must be done before aufs lock.
30511+ * so we follow the same rule.
30512+ */
30513+ ii_write_lock_parent(inode);
30514+ aufs_write_unlock(root);
30515+ err = au_opts_parse(sb, arg, &opts);
30516+ if (unlikely(err))
30517+ goto out_root;
30518+
30519+ /* lock vfs_inode first, then aufs. */
febd17d6 30520+ inode_lock(inode);
1facf9fc 30521+ aufs_write_lock(root);
30522+ err = au_opts_mount(sb, &opts);
30523+ au_opts_free(&opts);
79b8bda9
AM
30524+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) {
30525+ sb->s_d_op = &aufs_dop_noreval;
062440b3 30526+ pr_info("%ps\n", sb->s_d_op);
79b8bda9 30527+ au_refresh_dop(root, /*force_reval*/0);
b95c5147
AM
30528+ sbinfo->si_iop_array = aufs_iop_nogetattr;
30529+ au_refresh_iop(inode, /*force_getattr*/0);
79b8bda9 30530+ }
1facf9fc 30531+ aufs_write_unlock(root);
febd17d6 30532+ inode_unlock(inode);
4a4d8108
AM
30533+ if (!err)
30534+ goto out_opts; /* success */
1facf9fc 30535+
4f0767ce 30536+out_root:
1facf9fc 30537+ dput(root);
30538+ sb->s_root = NULL;
4f0767ce 30539+out_info:
79b8bda9 30540+ kobject_put(&sbinfo->si_kobj);
1facf9fc 30541+ sb->s_fs_info = NULL;
4f0767ce 30542+out_opts:
1c60b727 30543+ free_page((unsigned long)opts.opt);
4f0767ce 30544+out:
1facf9fc 30545+ AuTraceErr(err);
30546+ err = cvt_err(err);
30547+ AuTraceErr(err);
30548+ return err;
30549+}
30550+
30551+/* ---------------------------------------------------------------------- */
30552+
027c5e7a
AM
30553+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
30554+ const char *dev_name __maybe_unused,
30555+ void *raw_data)
1facf9fc 30556+{
027c5e7a 30557+ struct dentry *root;
1facf9fc 30558+
30559+ /* all timestamps always follow the ones on the branch */
30560+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
30561+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
30562+ if (IS_ERR(root))
30563+ goto out;
30564+
062440b3 30565+ au_sbilist_add(root->d_sb);
027c5e7a
AM
30566+
30567+out:
30568+ return root;
1facf9fc 30569+}
30570+
e49829fe
JR
30571+static void aufs_kill_sb(struct super_block *sb)
30572+{
30573+ struct au_sbinfo *sbinfo;
30574+
30575+ sbinfo = au_sbi(sb);
30576+ if (sbinfo) {
30577+ au_sbilist_del(sb);
30578+ aufs_write_lock(sb->s_root);
076b876e 30579+ au_fhsm_fin(sb);
e49829fe
JR
30580+ if (sbinfo->si_wbr_create_ops->fin)
30581+ sbinfo->si_wbr_create_ops->fin(sb);
30582+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
30583+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
b95c5147 30584+ au_remount_refresh(sb, /*do_idop*/0);
e49829fe
JR
30585+ }
30586+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
30587+ au_plink_put(sb, /*verbose*/1);
30588+ au_xino_clr(sb);
8b6a4947 30589+ au_dr_opt_flush(sb);
1e00d052 30590+ sbinfo->si_sb = NULL;
e49829fe 30591+ aufs_write_unlock(sb->s_root);
e49829fe
JR
30592+ au_nwt_flush(&sbinfo->si_nowait);
30593+ }
98d9a5b1 30594+ kill_anon_super(sb);
e49829fe
JR
30595+}
30596+
1facf9fc 30597+struct file_system_type aufs_fs_type = {
30598+ .name = AUFS_FSTYPE,
c06a8ce3
AM
30599+ /* a race between rename and others */
30600+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 30601+ .mount = aufs_mount,
e49829fe 30602+ .kill_sb = aufs_kill_sb,
1facf9fc 30603+ /* no need to __module_get() and module_put(). */
30604+ .owner = THIS_MODULE,
30605+};
7f207e10
AM
30606diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
30607--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 30608+++ linux/fs/aufs/super.h 2019-03-05 12:13:00.142557771 +0100
acd2b654 30609@@ -0,0 +1,589 @@
062440b3 30610+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 30611+/*
ba1aed25 30612+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 30613+ *
30614+ * This program, aufs is free software; you can redistribute it and/or modify
30615+ * it under the terms of the GNU General Public License as published by
30616+ * the Free Software Foundation; either version 2 of the License, or
30617+ * (at your option) any later version.
dece6358
AM
30618+ *
30619+ * This program is distributed in the hope that it will be useful,
30620+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30621+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30622+ * GNU General Public License for more details.
30623+ *
30624+ * You should have received a copy of the GNU General Public License
523b37e3 30625+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30626+ */
30627+
30628+/*
30629+ * super_block operations
30630+ */
30631+
30632+#ifndef __AUFS_SUPER_H__
30633+#define __AUFS_SUPER_H__
30634+
30635+#ifdef __KERNEL__
30636+
30637+#include <linux/fs.h>
5527c038 30638+#include <linux/kobject.h>
8b6a4947 30639+#include "hbl.h"
acd2b654 30640+#include "lcnt.h"
1facf9fc 30641+#include "rwsem.h"
1facf9fc 30642+#include "wkq.h"
30643+
1facf9fc 30644+/* policies to select one among multiple writable branches */
30645+struct au_wbr_copyup_operations {
30646+ int (*copyup)(struct dentry *dentry);
30647+};
30648+
392086de
AM
30649+#define AuWbr_DIR 1 /* target is a dir */
30650+#define AuWbr_PARENT (1 << 1) /* always require a parent */
30651+
30652+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
30653+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
30654+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
30655+
1facf9fc 30656+struct au_wbr_create_operations {
392086de 30657+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 30658+ int (*init)(struct super_block *sb);
30659+ int (*fin)(struct super_block *sb);
30660+};
30661+
30662+struct au_wbr_mfs {
30663+ struct mutex mfs_lock; /* protect this structure */
30664+ unsigned long mfs_jiffy;
30665+ unsigned long mfs_expire;
30666+ aufs_bindex_t mfs_bindex;
30667+
30668+ unsigned long long mfsrr_bytes;
30669+ unsigned long long mfsrr_watermark;
30670+};
30671+
86dc4139
AM
30672+#define AuPlink_NHASH 100
30673+static inline int au_plink_hash(ino_t ino)
30674+{
30675+ return ino % AuPlink_NHASH;
30676+}
30677+
076b876e
AM
30678+/* File-based Hierarchical Storage Management */
30679+struct au_fhsm {
30680+#ifdef CONFIG_AUFS_FHSM
30681+ /* allow only one process who can receive the notification */
30682+ spinlock_t fhsm_spin;
30683+ pid_t fhsm_pid;
30684+ wait_queue_head_t fhsm_wqh;
30685+ atomic_t fhsm_readable;
30686+
c1595e42 30687+ /* these are protected by si_rwsem */
076b876e 30688+ unsigned long fhsm_expire;
c1595e42 30689+ aufs_bindex_t fhsm_bottom;
076b876e
AM
30690+#endif
30691+};
30692+
1facf9fc 30693+struct au_branch;
30694+struct au_sbinfo {
30695+ /* nowait tasks in the system-wide workqueue */
30696+ struct au_nowait_tasks si_nowait;
30697+
b752ccd1 30698+ /*
acd2b654 30699+ * tried sb->s_umount, but failed due to the dependency between i_mutex.
b752ccd1
AM
30700+ * rwsem for au_sbinfo is necessary.
30701+ */
dece6358 30702+ struct au_rwsem si_rwsem;
1facf9fc 30703+
7f207e10 30704+ /*
523b37e3
AM
30705+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
30706+ * remount.
7f207e10 30707+ */
acd2b654 30708+ au_lcnt_t si_ninodes, si_nfiles;
7f207e10 30709+
1facf9fc 30710+ /* branch management */
30711+ unsigned int si_generation;
30712+
2000de60 30713+ /* see AuSi_ flags */
1facf9fc 30714+ unsigned char au_si_status;
30715+
5afbbe0d 30716+ aufs_bindex_t si_bbot;
7f207e10
AM
30717+
30718+ /* dirty trick to keep br_id plus */
30719+ unsigned int si_last_br_id :
30720+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 30721+ struct au_branch **si_branch;
30722+
30723+ /* policy to select a writable branch */
30724+ unsigned char si_wbr_copyup;
30725+ unsigned char si_wbr_create;
30726+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
30727+ struct au_wbr_create_operations *si_wbr_create_ops;
30728+
30729+ /* round robin */
30730+ atomic_t si_wbr_rr_next;
30731+
30732+ /* most free space */
30733+ struct au_wbr_mfs si_wbr_mfs;
30734+
076b876e
AM
30735+ /* File-based Hierarchical Storage Management */
30736+ struct au_fhsm si_fhsm;
30737+
1facf9fc 30738+ /* mount flags */
30739+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
30740+ unsigned int si_mntflags;
30741+
30742+ /* external inode number (bitmap and translation table) */
5527c038
JR
30743+ vfs_readf_t si_xread;
30744+ vfs_writef_t si_xwrite;
acd2b654
AM
30745+ loff_t si_ximaxent; /* max entries in a xino */
30746+
1facf9fc 30747+ struct file *si_xib;
30748+ struct mutex si_xib_mtx; /* protect xib members */
30749+ unsigned long *si_xib_buf;
30750+ unsigned long si_xib_last_pindex;
30751+ int si_xib_next_bit;
acd2b654 30752+
392086de
AM
30753+ unsigned long si_xino_jiffy;
30754+ unsigned long si_xino_expire;
1facf9fc 30755+ /* reserved for future use */
30756+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
30757+
30758+#ifdef CONFIG_AUFS_EXPORT
30759+ /* i_generation */
acd2b654 30760+ /* todo: make xigen file an array to support many inode numbers */
1facf9fc 30761+ struct file *si_xigen;
30762+ atomic_t si_xigen_next;
30763+#endif
30764+
acd2b654 30765+ /* dirty trick to support atomic_open */
8b6a4947 30766+ struct hlist_bl_head si_aopen;
b912730e 30767+
1facf9fc 30768+ /* vdir parameters */
e49829fe 30769+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 30770+ unsigned int si_rdblk; /* deblk size */
30771+ unsigned int si_rdhash; /* hash size */
30772+
30773+ /*
30774+ * If the number of whiteouts are larger than si_dirwh, leave all of
30775+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
30776+ * future fsck.aufs or kernel thread will remove them later.
30777+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
30778+ */
30779+ unsigned int si_dirwh;
30780+
1facf9fc 30781+ /* pseudo_link list */
8b6a4947 30782+ struct hlist_bl_head si_plink[AuPlink_NHASH];
1facf9fc 30783+ wait_queue_head_t si_plink_wq;
4a4d8108 30784+ spinlock_t si_plink_maint_lock;
e49829fe 30785+ pid_t si_plink_maint_pid;
1facf9fc 30786+
523b37e3 30787+ /* file list */
8b6a4947 30788+ struct hlist_bl_head si_files;
523b37e3 30789+
b95c5147
AM
30790+ /* with/without getattr, brother of sb->s_d_op */
30791+ struct inode_operations *si_iop_array;
30792+
1facf9fc 30793+ /*
30794+ * sysfs and lifetime management.
30795+ * this is not a small structure and it may be a waste of memory in case
acd2b654 30796+ * of sysfs is disabled, particularly when many aufs-es are mounted.
1facf9fc 30797+ * but using sysfs is majority.
30798+ */
30799+ struct kobject si_kobj;
30800+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
30801+ struct dentry *si_dbgaufs;
30802+ struct dentry *si_dbgaufs_plink;
30803+ struct dentry *si_dbgaufs_xib;
1facf9fc 30804+#ifdef CONFIG_AUFS_EXPORT
30805+ struct dentry *si_dbgaufs_xigen;
30806+#endif
30807+#endif
30808+
e49829fe 30809+#ifdef CONFIG_AUFS_SBILIST
8b6a4947 30810+ struct hlist_bl_node si_list;
e49829fe
JR
30811+#endif
30812+
1facf9fc 30813+ /* dirty, necessary for unmounting, sysfs and sysrq */
30814+ struct super_block *si_sb;
30815+};
30816+
dece6358
AM
30817+/* sbinfo status flags */
30818+/*
30819+ * set true when refresh_dirs() failed at remount time.
30820+ * then try refreshing dirs at access time again.
062440b3 30821+ * if it is false, refreshing dirs at access time is unnecessary
dece6358 30822+ */
027c5e7a 30823+#define AuSi_FAILED_REFRESH_DIR 1
076b876e 30824+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
79b8bda9 30825+#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */
076b876e
AM
30826+
30827+#ifndef CONFIG_AUFS_FHSM
30828+#undef AuSi_FHSM
30829+#define AuSi_FHSM 0
30830+#endif
30831+
dece6358
AM
30832+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
30833+ unsigned int flag)
30834+{
30835+ AuRwMustAnyLock(&sbi->si_rwsem);
30836+ return sbi->au_si_status & flag;
30837+}
30838+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
30839+#define au_fset_si(sbinfo, name) do { \
30840+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
30841+ (sbinfo)->au_si_status |= AuSi_##name; \
30842+} while (0)
30843+#define au_fclr_si(sbinfo, name) do { \
30844+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
30845+ (sbinfo)->au_si_status &= ~AuSi_##name; \
30846+} while (0)
30847+
1facf9fc 30848+/* ---------------------------------------------------------------------- */
30849+
30850+/* policy to select one among writable branches */
4a4d8108
AM
30851+#define AuWbrCopyup(sbinfo, ...) \
30852+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
30853+#define AuWbrCreate(sbinfo, ...) \
30854+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 30855+
30856+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
30857+#define AuLock_DW 1 /* write-lock dentry */
30858+#define AuLock_IR (1 << 1) /* read-lock inode */
30859+#define AuLock_IW (1 << 2) /* write-lock inode */
30860+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
b95c5147 30861+#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */
f2c43d5f 30862+ /* except RENAME_EXCHANGE */
e49829fe
JR
30863+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
30864+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 30865+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 30866+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
30867+#define au_fset_lock(flags, name) \
30868+ do { (flags) |= AuLock_##name; } while (0)
30869+#define au_fclr_lock(flags, name) \
30870+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 30871+
30872+/* ---------------------------------------------------------------------- */
30873+
30874+/* super.c */
30875+extern struct file_system_type aufs_fs_type;
30876+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
79b8bda9
AM
30877+typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array,
30878+ unsigned long long max, void *arg);
79b8bda9
AM
30879+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
30880+ struct super_block *sb, void *arg);
7f207e10
AM
30881+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
30882+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 30883+
30884+/* sbinfo.c */
30885+void au_si_free(struct kobject *kobj);
30886+int au_si_alloc(struct super_block *sb);
e2f27e51 30887+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink);
1facf9fc 30888+
30889+unsigned int au_sigen_inc(struct super_block *sb);
30890+aufs_bindex_t au_new_br_id(struct super_block *sb);
30891+
e49829fe
JR
30892+int si_read_lock(struct super_block *sb, int flags);
30893+int si_write_lock(struct super_block *sb, int flags);
30894+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 30895+void aufs_read_unlock(struct dentry *dentry, int flags);
30896+void aufs_write_lock(struct dentry *dentry);
30897+void aufs_write_unlock(struct dentry *dentry);
e49829fe 30898+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 30899+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
30900+
30901+/* wbr_policy.c */
30902+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
30903+extern struct au_wbr_create_operations au_wbr_create_ops[];
30904+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2 30905+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
5afbbe0d 30906+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop);
c2b27bf2
AM
30907+
30908+/* mvdown.c */
30909+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 30910+
076b876e
AM
30911+#ifdef CONFIG_AUFS_FHSM
30912+/* fhsm.c */
30913+
30914+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
30915+{
30916+ pid_t pid;
30917+
30918+ spin_lock(&fhsm->fhsm_spin);
30919+ pid = fhsm->fhsm_pid;
30920+ spin_unlock(&fhsm->fhsm_spin);
30921+
30922+ return pid;
30923+}
30924+
30925+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
30926+void au_fhsm_wrote_all(struct super_block *sb, int force);
30927+int au_fhsm_fd(struct super_block *sb, int oflags);
30928+int au_fhsm_br_alloc(struct au_branch *br);
c1595e42 30929+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
076b876e
AM
30930+void au_fhsm_fin(struct super_block *sb);
30931+void au_fhsm_init(struct au_sbinfo *sbinfo);
30932+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
30933+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
30934+#else
30935+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
30936+ int force)
30937+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
30938+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
c1595e42
JR
30939+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
30940+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
30941+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
076b876e
AM
30942+AuStubVoid(au_fhsm_fin, struct super_block *sb)
30943+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
30944+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
30945+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
30946+#endif
30947+
1facf9fc 30948+/* ---------------------------------------------------------------------- */
30949+
30950+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
30951+{
30952+ return sb->s_fs_info;
30953+}
30954+
30955+/* ---------------------------------------------------------------------- */
30956+
30957+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 30958+int au_test_nfsd(void);
1facf9fc 30959+void au_export_init(struct super_block *sb);
b752ccd1 30960+void au_xigen_inc(struct inode *inode);
1facf9fc 30961+int au_xigen_new(struct inode *inode);
062440b3 30962+int au_xigen_set(struct super_block *sb, struct path *path);
1facf9fc 30963+void au_xigen_clr(struct super_block *sb);
30964+
30965+static inline int au_busy_or_stale(void)
30966+{
b752ccd1 30967+ if (!au_test_nfsd())
1facf9fc 30968+ return -EBUSY;
30969+ return -ESTALE;
30970+}
30971+#else
b752ccd1 30972+AuStubInt0(au_test_nfsd, void)
a2a7ad62 30973+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 30974+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108 30975+AuStubInt0(au_xigen_new, struct inode *inode)
062440b3 30976+AuStubInt0(au_xigen_set, struct super_block *sb, struct path *path)
4a4d8108 30977+AuStubVoid(au_xigen_clr, struct super_block *sb)
c1595e42 30978+AuStub(int, au_busy_or_stale, return -EBUSY, void)
1facf9fc 30979+#endif /* CONFIG_AUFS_EXPORT */
30980+
30981+/* ---------------------------------------------------------------------- */
30982+
e49829fe
JR
30983+#ifdef CONFIG_AUFS_SBILIST
30984+/* module.c */
8b6a4947 30985+extern struct hlist_bl_head au_sbilist;
e49829fe
JR
30986+
30987+static inline void au_sbilist_init(void)
30988+{
8b6a4947 30989+ INIT_HLIST_BL_HEAD(&au_sbilist);
e49829fe
JR
30990+}
30991+
30992+static inline void au_sbilist_add(struct super_block *sb)
30993+{
8b6a4947 30994+ au_hbl_add(&au_sbi(sb)->si_list, &au_sbilist);
e49829fe
JR
30995+}
30996+
30997+static inline void au_sbilist_del(struct super_block *sb)
30998+{
8b6a4947 30999+ au_hbl_del(&au_sbi(sb)->si_list, &au_sbilist);
e49829fe 31000+}
53392da6
AM
31001+
31002+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
31003+static inline void au_sbilist_lock(void)
31004+{
8b6a4947 31005+ hlist_bl_lock(&au_sbilist);
53392da6
AM
31006+}
31007+
31008+static inline void au_sbilist_unlock(void)
31009+{
8b6a4947 31010+ hlist_bl_unlock(&au_sbilist);
53392da6
AM
31011+}
31012+#define AuGFP_SBILIST GFP_ATOMIC
31013+#else
31014+AuStubVoid(au_sbilist_lock, void)
31015+AuStubVoid(au_sbilist_unlock, void)
31016+#define AuGFP_SBILIST GFP_NOFS
31017+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
31018+#else
31019+AuStubVoid(au_sbilist_init, void)
c1595e42
JR
31020+AuStubVoid(au_sbilist_add, struct super_block *sb)
31021+AuStubVoid(au_sbilist_del, struct super_block *sb)
53392da6
AM
31022+AuStubVoid(au_sbilist_lock, void)
31023+AuStubVoid(au_sbilist_unlock, void)
31024+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
31025+#endif
31026+
31027+/* ---------------------------------------------------------------------- */
31028+
1facf9fc 31029+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
31030+{
dece6358 31031+ /*
c1595e42 31032+ * This function is a dynamic '__init' function actually,
dece6358
AM
31033+ * so the tiny check for si_rwsem is unnecessary.
31034+ */
31035+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 31036+#ifdef CONFIG_DEBUG_FS
31037+ sbinfo->si_dbgaufs = NULL;
86dc4139 31038+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 31039+ sbinfo->si_dbgaufs_xib = NULL;
31040+#ifdef CONFIG_AUFS_EXPORT
31041+ sbinfo->si_dbgaufs_xigen = NULL;
31042+#endif
31043+#endif
31044+}
31045+
31046+/* ---------------------------------------------------------------------- */
31047+
a2654f78
AM
31048+/* current->atomic_flags */
31049+/* this value should never corrupt the ones defined in linux/sched.h */
31050+#define PFA_AUFS 7
31051+
31052+TASK_PFA_TEST(AUFS, test_aufs) /* task_test_aufs */
31053+TASK_PFA_SET(AUFS, aufs) /* task_set_aufs */
31054+TASK_PFA_CLEAR(AUFS, aufs) /* task_clear_aufs */
b752ccd1
AM
31055+
31056+static inline int si_pid_test(struct super_block *sb)
31057+{
a2654f78 31058+ return !!task_test_aufs(current);
b752ccd1
AM
31059+}
31060+
31061+static inline void si_pid_clr(struct super_block *sb)
31062+{
a2654f78
AM
31063+ AuDebugOn(!task_test_aufs(current));
31064+ task_clear_aufs(current);
b752ccd1
AM
31065+}
31066+
a2654f78
AM
31067+static inline void si_pid_set(struct super_block *sb)
31068+{
31069+ AuDebugOn(task_test_aufs(current));
31070+ task_set_aufs(current);
31071+}
febd17d6 31072+
b752ccd1
AM
31073+/* ---------------------------------------------------------------------- */
31074+
1facf9fc 31075+/* lock superblock. mainly for entry point functions */
8b6a4947
AM
31076+#define __si_read_lock(sb) au_rw_read_lock(&au_sbi(sb)->si_rwsem)
31077+#define __si_write_lock(sb) au_rw_write_lock(&au_sbi(sb)->si_rwsem)
31078+#define __si_read_trylock(sb) au_rw_read_trylock(&au_sbi(sb)->si_rwsem)
31079+#define __si_write_trylock(sb) au_rw_write_trylock(&au_sbi(sb)->si_rwsem)
31080+/*
31081+#define __si_read_trylock_nested(sb) \
31082+ au_rw_read_trylock_nested(&au_sbi(sb)->si_rwsem)
31083+#define __si_write_trylock_nested(sb) \
31084+ au_rw_write_trylock_nested(&au_sbi(sb)->si_rwsem)
31085+*/
31086+
31087+#define __si_read_unlock(sb) au_rw_read_unlock(&au_sbi(sb)->si_rwsem)
31088+#define __si_write_unlock(sb) au_rw_write_unlock(&au_sbi(sb)->si_rwsem)
31089+#define __si_downgrade_lock(sb) au_rw_dgrade_lock(&au_sbi(sb)->si_rwsem)
1facf9fc 31090+
dece6358
AM
31091+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
31092+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
31093+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
31094+
b752ccd1
AM
31095+static inline void si_noflush_read_lock(struct super_block *sb)
31096+{
31097+ __si_read_lock(sb);
31098+ si_pid_set(sb);
31099+}
31100+
31101+static inline int si_noflush_read_trylock(struct super_block *sb)
31102+{
076b876e
AM
31103+ int locked;
31104+
31105+ locked = __si_read_trylock(sb);
b752ccd1
AM
31106+ if (locked)
31107+ si_pid_set(sb);
31108+ return locked;
31109+}
31110+
31111+static inline void si_noflush_write_lock(struct super_block *sb)
31112+{
31113+ __si_write_lock(sb);
31114+ si_pid_set(sb);
31115+}
31116+
31117+static inline int si_noflush_write_trylock(struct super_block *sb)
31118+{
076b876e
AM
31119+ int locked;
31120+
31121+ locked = __si_write_trylock(sb);
b752ccd1
AM
31122+ if (locked)
31123+ si_pid_set(sb);
31124+ return locked;
31125+}
31126+
7e9cd9fe 31127+#if 0 /* reserved */
1facf9fc 31128+static inline int si_read_trylock(struct super_block *sb, int flags)
31129+{
31130+ if (au_ftest_lock(flags, FLUSH))
31131+ au_nwt_flush(&au_sbi(sb)->si_nowait);
31132+ return si_noflush_read_trylock(sb);
31133+}
e49829fe 31134+#endif
1facf9fc 31135+
b752ccd1
AM
31136+static inline void si_read_unlock(struct super_block *sb)
31137+{
31138+ si_pid_clr(sb);
31139+ __si_read_unlock(sb);
31140+}
31141+
7e9cd9fe 31142+#if 0 /* reserved */
1facf9fc 31143+static inline int si_write_trylock(struct super_block *sb, int flags)
31144+{
31145+ if (au_ftest_lock(flags, FLUSH))
31146+ au_nwt_flush(&au_sbi(sb)->si_nowait);
31147+ return si_noflush_write_trylock(sb);
31148+}
b752ccd1
AM
31149+#endif
31150+
31151+static inline void si_write_unlock(struct super_block *sb)
31152+{
31153+ si_pid_clr(sb);
31154+ __si_write_unlock(sb);
31155+}
31156+
7e9cd9fe 31157+#if 0 /* reserved */
b752ccd1
AM
31158+static inline void si_downgrade_lock(struct super_block *sb)
31159+{
31160+ __si_downgrade_lock(sb);
31161+}
31162+#endif
1facf9fc 31163+
31164+/* ---------------------------------------------------------------------- */
31165+
5afbbe0d 31166+static inline aufs_bindex_t au_sbbot(struct super_block *sb)
1facf9fc 31167+{
dece6358 31168+ SiMustAnyLock(sb);
5afbbe0d 31169+ return au_sbi(sb)->si_bbot;
1facf9fc 31170+}
31171+
31172+static inline unsigned int au_mntflags(struct super_block *sb)
31173+{
dece6358 31174+ SiMustAnyLock(sb);
1facf9fc 31175+ return au_sbi(sb)->si_mntflags;
31176+}
31177+
31178+static inline unsigned int au_sigen(struct super_block *sb)
31179+{
dece6358 31180+ SiMustAnyLock(sb);
1facf9fc 31181+ return au_sbi(sb)->si_generation;
31182+}
31183+
31184+static inline struct au_branch *au_sbr(struct super_block *sb,
31185+ aufs_bindex_t bindex)
31186+{
dece6358 31187+ SiMustAnyLock(sb);
1facf9fc 31188+ return au_sbi(sb)->si_branch[0 + bindex];
31189+}
31190+
acd2b654 31191+static inline loff_t au_xi_maxent(struct super_block *sb)
1facf9fc 31192+{
dece6358 31193+ SiMustAnyLock(sb);
acd2b654 31194+ return au_sbi(sb)->si_ximaxent;
1facf9fc 31195+}
31196+
31197+#endif /* __KERNEL__ */
31198+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
31199diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
31200--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 31201+++ linux/fs/aufs/sysaufs.c 2019-03-05 12:13:00.142557771 +0100
062440b3 31202@@ -0,0 +1,93 @@
cd7a4cd9 31203+// SPDX-License-Identifier: GPL-2.0
1facf9fc 31204+/*
ba1aed25 31205+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 31206+ *
31207+ * This program, aufs is free software; you can redistribute it and/or modify
31208+ * it under the terms of the GNU General Public License as published by
31209+ * the Free Software Foundation; either version 2 of the License, or
31210+ * (at your option) any later version.
dece6358
AM
31211+ *
31212+ * This program is distributed in the hope that it will be useful,
31213+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31214+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31215+ * GNU General Public License for more details.
31216+ *
31217+ * You should have received a copy of the GNU General Public License
523b37e3 31218+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31219+ */
31220+
31221+/*
31222+ * sysfs interface and lifetime management
31223+ * they are necessary regardless sysfs is disabled.
31224+ */
31225+
1facf9fc 31226+#include <linux/random.h>
1facf9fc 31227+#include "aufs.h"
31228+
31229+unsigned long sysaufs_si_mask;
e49829fe 31230+struct kset *sysaufs_kset;
1facf9fc 31231+
31232+#define AuSiAttr(_name) { \
31233+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
31234+ .show = sysaufs_si_##_name, \
31235+}
31236+
31237+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
31238+struct attribute *sysaufs_si_attrs[] = {
31239+ &sysaufs_si_attr_xi_path.attr,
31240+ NULL,
31241+};
31242+
4a4d8108 31243+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 31244+ .show = sysaufs_si_show
31245+};
31246+
31247+static struct kobj_type au_sbi_ktype = {
31248+ .release = au_si_free,
31249+ .sysfs_ops = &au_sbi_ops,
31250+ .default_attrs = sysaufs_si_attrs
31251+};
31252+
31253+/* ---------------------------------------------------------------------- */
31254+
31255+int sysaufs_si_init(struct au_sbinfo *sbinfo)
31256+{
31257+ int err;
31258+
e49829fe 31259+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 31260+ /* cf. sysaufs_name() */
31261+ err = kobject_init_and_add
e49829fe 31262+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 31263+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
31264+
1facf9fc 31265+ return err;
31266+}
31267+
31268+void sysaufs_fin(void)
31269+{
e49829fe
JR
31270+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
31271+ kset_unregister(sysaufs_kset);
1facf9fc 31272+}
31273+
31274+int __init sysaufs_init(void)
31275+{
31276+ int err;
31277+
31278+ do {
31279+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
31280+ } while (!sysaufs_si_mask);
31281+
4a4d8108 31282+ err = -EINVAL;
e49829fe
JR
31283+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
31284+ if (unlikely(!sysaufs_kset))
4a4d8108 31285+ goto out;
e49829fe
JR
31286+ err = PTR_ERR(sysaufs_kset);
31287+ if (IS_ERR(sysaufs_kset))
1facf9fc 31288+ goto out;
e49829fe 31289+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
062440b3 31290+ if (unlikely(err))
e49829fe 31291+ kset_unregister(sysaufs_kset);
1facf9fc 31292+
4f0767ce 31293+out:
1facf9fc 31294+ return err;
31295+}
7f207e10
AM
31296diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
31297--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 31298+++ linux/fs/aufs/sysaufs.h 2019-03-05 12:13:00.142557771 +0100
062440b3
AM
31299@@ -0,0 +1,102 @@
31300+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 31301+/*
ba1aed25 31302+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 31303+ *
31304+ * This program, aufs is free software; you can redistribute it and/or modify
31305+ * it under the terms of the GNU General Public License as published by
31306+ * the Free Software Foundation; either version 2 of the License, or
31307+ * (at your option) any later version.
dece6358
AM
31308+ *
31309+ * This program is distributed in the hope that it will be useful,
31310+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31311+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31312+ * GNU General Public License for more details.
31313+ *
31314+ * You should have received a copy of the GNU General Public License
523b37e3 31315+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31316+ */
31317+
31318+/*
31319+ * sysfs interface and mount lifetime management
31320+ */
31321+
31322+#ifndef __SYSAUFS_H__
31323+#define __SYSAUFS_H__
31324+
31325+#ifdef __KERNEL__
31326+
1facf9fc 31327+#include <linux/sysfs.h>
1facf9fc 31328+#include "module.h"
31329+
dece6358
AM
31330+struct super_block;
31331+struct au_sbinfo;
31332+
1facf9fc 31333+struct sysaufs_si_attr {
31334+ struct attribute attr;
31335+ int (*show)(struct seq_file *seq, struct super_block *sb);
31336+};
31337+
31338+/* ---------------------------------------------------------------------- */
31339+
31340+/* sysaufs.c */
31341+extern unsigned long sysaufs_si_mask;
e49829fe 31342+extern struct kset *sysaufs_kset;
1facf9fc 31343+extern struct attribute *sysaufs_si_attrs[];
31344+int sysaufs_si_init(struct au_sbinfo *sbinfo);
31345+int __init sysaufs_init(void);
31346+void sysaufs_fin(void);
31347+
31348+/* ---------------------------------------------------------------------- */
31349+
31350+/* some people doesn't like to show a pointer in kernel */
31351+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
31352+{
31353+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
31354+}
31355+
31356+#define SysaufsSiNamePrefix "si_"
31357+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
31358+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
31359+{
31360+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
31361+ sysaufs_si_id(sbinfo));
31362+}
31363+
31364+struct au_branch;
31365+#ifdef CONFIG_SYSFS
31366+/* sysfs.c */
31367+extern struct attribute_group *sysaufs_attr_group;
31368+
31369+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
31370+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
31371+ char *buf);
076b876e
AM
31372+long au_brinfo_ioctl(struct file *file, unsigned long arg);
31373+#ifdef CONFIG_COMPAT
31374+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
31375+#endif
1facf9fc 31376+
31377+void sysaufs_br_init(struct au_branch *br);
31378+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
31379+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
31380+
31381+#define sysaufs_brs_init() do {} while (0)
31382+
31383+#else
31384+#define sysaufs_attr_group NULL
31385+
4a4d8108 31386+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
c1595e42
JR
31387+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
31388+ struct attribute *attr, char *buf)
4a4d8108
AM
31389+AuStubVoid(sysaufs_br_init, struct au_branch *br)
31390+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
31391+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 31392+
31393+static inline void sysaufs_brs_init(void)
31394+{
31395+ sysaufs_brs = 0;
31396+}
31397+
31398+#endif /* CONFIG_SYSFS */
31399+
31400+#endif /* __KERNEL__ */
31401+#endif /* __SYSAUFS_H__ */
7f207e10
AM
31402diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
31403--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25
AM
31404+++ linux/fs/aufs/sysfs.c 2019-03-05 12:13:00.142557771 +0100
31405@@ -0,0 +1,374 @@
cd7a4cd9 31406+// SPDX-License-Identifier: GPL-2.0
1facf9fc 31407+/*
ba1aed25 31408+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 31409+ *
31410+ * This program, aufs is free software; you can redistribute it and/or modify
31411+ * it under the terms of the GNU General Public License as published by
31412+ * the Free Software Foundation; either version 2 of the License, or
31413+ * (at your option) any later version.
dece6358
AM
31414+ *
31415+ * This program is distributed in the hope that it will be useful,
31416+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31417+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31418+ * GNU General Public License for more details.
31419+ *
31420+ * You should have received a copy of the GNU General Public License
523b37e3 31421+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31422+ */
31423+
31424+/*
31425+ * sysfs interface
31426+ */
31427+
076b876e 31428+#include <linux/compat.h>
1facf9fc 31429+#include <linux/seq_file.h>
1facf9fc 31430+#include "aufs.h"
31431+
4a4d8108
AM
31432+#ifdef CONFIG_AUFS_FS_MODULE
31433+/* this entry violates the "one line per file" policy of sysfs */
31434+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
31435+ char *buf)
31436+{
31437+ ssize_t err;
31438+ static char *conf =
31439+/* this file is generated at compiling */
31440+#include "conf.str"
31441+ ;
31442+
31443+ err = snprintf(buf, PAGE_SIZE, conf);
31444+ if (unlikely(err >= PAGE_SIZE))
31445+ err = -EFBIG;
31446+ return err;
31447+}
31448+
31449+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
31450+#endif
31451+
1facf9fc 31452+static struct attribute *au_attr[] = {
4a4d8108
AM
31453+#ifdef CONFIG_AUFS_FS_MODULE
31454+ &au_config_attr.attr,
31455+#endif
1facf9fc 31456+ NULL, /* need to NULL terminate the list of attributes */
31457+};
31458+
31459+static struct attribute_group sysaufs_attr_group_body = {
31460+ .attrs = au_attr
31461+};
31462+
31463+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
31464+
31465+/* ---------------------------------------------------------------------- */
31466+
31467+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
31468+{
31469+ int err;
31470+
dece6358
AM
31471+ SiMustAnyLock(sb);
31472+
1facf9fc 31473+ err = 0;
31474+ if (au_opt_test(au_mntflags(sb), XINO)) {
31475+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
31476+ seq_putc(seq, '\n');
31477+ }
31478+ return err;
31479+}
31480+
31481+/*
31482+ * the lifetime of branch is independent from the entry under sysfs.
31483+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
31484+ * unlinked.
31485+ */
31486+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 31487+ aufs_bindex_t bindex, int idx)
1facf9fc 31488+{
1e00d052 31489+ int err;
1facf9fc 31490+ struct path path;
31491+ struct dentry *root;
31492+ struct au_branch *br;
076b876e 31493+ au_br_perm_str_t perm;
1facf9fc 31494+
31495+ AuDbg("b%d\n", bindex);
31496+
1e00d052 31497+ err = 0;
1facf9fc 31498+ root = sb->s_root;
31499+ di_read_lock_parent(root, !AuLock_IR);
31500+ br = au_sbr(sb, bindex);
392086de
AM
31501+
31502+ switch (idx) {
31503+ case AuBrSysfs_BR:
31504+ path.mnt = au_br_mnt(br);
31505+ path.dentry = au_h_dptr(root, bindex);
79b8bda9
AM
31506+ err = au_seq_path(seq, &path);
31507+ if (!err) {
31508+ au_optstr_br_perm(&perm, br->br_perm);
31509+ seq_printf(seq, "=%s\n", perm.a);
31510+ }
392086de
AM
31511+ break;
31512+ case AuBrSysfs_BRID:
79b8bda9 31513+ seq_printf(seq, "%d\n", br->br_id);
392086de
AM
31514+ break;
31515+ }
076b876e 31516+ di_read_unlock(root, !AuLock_IR);
79b8bda9 31517+ if (unlikely(err || seq_has_overflowed(seq)))
076b876e 31518+ err = -E2BIG;
392086de 31519+
1e00d052 31520+ return err;
1facf9fc 31521+}
31522+
31523+/* ---------------------------------------------------------------------- */
31524+
31525+static struct seq_file *au_seq(char *p, ssize_t len)
31526+{
31527+ struct seq_file *seq;
31528+
31529+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
31530+ if (seq) {
31531+ /* mutex_init(&seq.lock); */
31532+ seq->buf = p;
31533+ seq->size = len;
31534+ return seq; /* success */
31535+ }
31536+
31537+ seq = ERR_PTR(-ENOMEM);
31538+ return seq;
31539+}
31540+
392086de
AM
31541+#define SysaufsBr_PREFIX "br"
31542+#define SysaufsBrid_PREFIX "brid"
1facf9fc 31543+
31544+/* todo: file size may exceed PAGE_SIZE */
31545+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 31546+ char *buf)
1facf9fc 31547+{
31548+ ssize_t err;
392086de 31549+ int idx;
1facf9fc 31550+ long l;
5afbbe0d 31551+ aufs_bindex_t bbot;
1facf9fc 31552+ struct au_sbinfo *sbinfo;
31553+ struct super_block *sb;
31554+ struct seq_file *seq;
31555+ char *name;
31556+ struct attribute **cattr;
31557+
31558+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
31559+ sb = sbinfo->si_sb;
1308ab2a 31560+
31561+ /*
31562+ * prevent a race condition between sysfs and aufs.
31563+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
31564+ * prohibits maintaining the sysfs entries.
31565+ * hew we acquire read lock after sysfs_get_active_two().
31566+ * on the other hand, the remount process may maintain the sysfs/aufs
31567+ * entries after acquiring write lock.
31568+ * it can cause a deadlock.
31569+ * simply we gave up processing read here.
31570+ */
31571+ err = -EBUSY;
31572+ if (unlikely(!si_noflush_read_trylock(sb)))
31573+ goto out;
1facf9fc 31574+
31575+ seq = au_seq(buf, PAGE_SIZE);
31576+ err = PTR_ERR(seq);
31577+ if (IS_ERR(seq))
1308ab2a 31578+ goto out_unlock;
1facf9fc 31579+
31580+ name = (void *)attr->name;
31581+ cattr = sysaufs_si_attrs;
31582+ while (*cattr) {
31583+ if (!strcmp(name, (*cattr)->name)) {
31584+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
31585+ ->show(seq, sb);
31586+ goto out_seq;
31587+ }
31588+ cattr++;
31589+ }
31590+
392086de
AM
31591+ if (!strncmp(name, SysaufsBrid_PREFIX,
31592+ sizeof(SysaufsBrid_PREFIX) - 1)) {
31593+ idx = AuBrSysfs_BRID;
31594+ name += sizeof(SysaufsBrid_PREFIX) - 1;
31595+ } else if (!strncmp(name, SysaufsBr_PREFIX,
31596+ sizeof(SysaufsBr_PREFIX) - 1)) {
31597+ idx = AuBrSysfs_BR;
1facf9fc 31598+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
31599+ } else
31600+ BUG();
31601+
31602+ err = kstrtol(name, 10, &l);
31603+ if (!err) {
5afbbe0d
AM
31604+ bbot = au_sbbot(sb);
31605+ if (l <= bbot)
392086de
AM
31606+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
31607+ else
31608+ err = -ENOENT;
1facf9fc 31609+ }
1facf9fc 31610+
4f0767ce 31611+out_seq:
1facf9fc 31612+ if (!err) {
31613+ err = seq->count;
31614+ /* sysfs limit */
31615+ if (unlikely(err == PAGE_SIZE))
31616+ err = -EFBIG;
31617+ }
9f237c51 31618+ au_kfree_rcu(seq);
4f0767ce 31619+out_unlock:
1facf9fc 31620+ si_read_unlock(sb);
4f0767ce 31621+out:
1facf9fc 31622+ return err;
31623+}
31624+
31625+/* ---------------------------------------------------------------------- */
31626+
076b876e
AM
31627+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
31628+{
31629+ int err;
31630+ int16_t brid;
5afbbe0d 31631+ aufs_bindex_t bindex, bbot;
076b876e
AM
31632+ size_t sz;
31633+ char *buf;
31634+ struct seq_file *seq;
31635+ struct au_branch *br;
31636+
31637+ si_read_lock(sb, AuLock_FLUSH);
5afbbe0d
AM
31638+ bbot = au_sbbot(sb);
31639+ err = bbot + 1;
076b876e
AM
31640+ if (!arg)
31641+ goto out;
31642+
31643+ err = -ENOMEM;
31644+ buf = (void *)__get_free_page(GFP_NOFS);
31645+ if (unlikely(!buf))
31646+ goto out;
31647+
31648+ seq = au_seq(buf, PAGE_SIZE);
31649+ err = PTR_ERR(seq);
31650+ if (IS_ERR(seq))
31651+ goto out_buf;
31652+
31653+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
5afbbe0d 31654+ for (bindex = 0; bindex <= bbot; bindex++, arg++) {
ba1aed25
AM
31655+ /* VERIFY_WRITE */
31656+ err = !access_ok(arg, sizeof(*arg));
076b876e
AM
31657+ if (unlikely(err))
31658+ break;
31659+
31660+ br = au_sbr(sb, bindex);
31661+ brid = br->br_id;
31662+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
31663+ err = __put_user(brid, &arg->id);
31664+ if (unlikely(err))
31665+ break;
31666+
31667+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
31668+ err = __put_user(br->br_perm, &arg->perm);
31669+ if (unlikely(err))
31670+ break;
31671+
79b8bda9
AM
31672+ err = au_seq_path(seq, &br->br_path);
31673+ if (unlikely(err))
31674+ break;
31675+ seq_putc(seq, '\0');
31676+ if (!seq_has_overflowed(seq)) {
076b876e
AM
31677+ err = copy_to_user(arg->path, seq->buf, seq->count);
31678+ seq->count = 0;
31679+ if (unlikely(err))
31680+ break;
31681+ } else {
31682+ err = -E2BIG;
31683+ goto out_seq;
31684+ }
31685+ }
31686+ if (unlikely(err))
31687+ err = -EFAULT;
31688+
31689+out_seq:
9f237c51 31690+ au_kfree_rcu(seq);
076b876e 31691+out_buf:
1c60b727 31692+ free_page((unsigned long)buf);
076b876e
AM
31693+out:
31694+ si_read_unlock(sb);
31695+ return err;
31696+}
31697+
31698+long au_brinfo_ioctl(struct file *file, unsigned long arg)
31699+{
2000de60 31700+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg);
076b876e
AM
31701+}
31702+
31703+#ifdef CONFIG_COMPAT
31704+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
31705+{
2000de60 31706+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg));
076b876e
AM
31707+}
31708+#endif
31709+
31710+/* ---------------------------------------------------------------------- */
31711+
1facf9fc 31712+void sysaufs_br_init(struct au_branch *br)
31713+{
392086de
AM
31714+ int i;
31715+ struct au_brsysfs *br_sysfs;
31716+ struct attribute *attr;
4a4d8108 31717+
392086de
AM
31718+ br_sysfs = br->br_sysfs;
31719+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31720+ attr = &br_sysfs->attr;
31721+ sysfs_attr_init(attr);
31722+ attr->name = br_sysfs->name;
cd7a4cd9 31723+ attr->mode = 0444;
392086de
AM
31724+ br_sysfs++;
31725+ }
1facf9fc 31726+}
31727+
31728+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
31729+{
31730+ struct au_branch *br;
31731+ struct kobject *kobj;
392086de
AM
31732+ struct au_brsysfs *br_sysfs;
31733+ int i;
5afbbe0d 31734+ aufs_bindex_t bbot;
1facf9fc 31735+
1facf9fc 31736+ if (!sysaufs_brs)
31737+ return;
31738+
31739+ kobj = &au_sbi(sb)->si_kobj;
5afbbe0d
AM
31740+ bbot = au_sbbot(sb);
31741+ for (; bindex <= bbot; bindex++) {
1facf9fc 31742+ br = au_sbr(sb, bindex);
392086de
AM
31743+ br_sysfs = br->br_sysfs;
31744+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31745+ sysfs_remove_file(kobj, &br_sysfs->attr);
31746+ br_sysfs++;
31747+ }
1facf9fc 31748+ }
31749+}
31750+
31751+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
31752+{
392086de 31753+ int err, i;
5afbbe0d 31754+ aufs_bindex_t bbot;
1facf9fc 31755+ struct kobject *kobj;
31756+ struct au_branch *br;
392086de 31757+ struct au_brsysfs *br_sysfs;
1facf9fc 31758+
1facf9fc 31759+ if (!sysaufs_brs)
31760+ return;
31761+
31762+ kobj = &au_sbi(sb)->si_kobj;
5afbbe0d
AM
31763+ bbot = au_sbbot(sb);
31764+ for (; bindex <= bbot; bindex++) {
1facf9fc 31765+ br = au_sbr(sb, bindex);
392086de
AM
31766+ br_sysfs = br->br_sysfs;
31767+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
31768+ SysaufsBr_PREFIX "%d", bindex);
31769+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
31770+ SysaufsBrid_PREFIX "%d", bindex);
31771+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31772+ err = sysfs_create_file(kobj, &br_sysfs->attr);
31773+ if (unlikely(err))
31774+ pr_warn("failed %s under sysfs(%d)\n",
31775+ br_sysfs->name, err);
31776+ br_sysfs++;
31777+ }
1facf9fc 31778+ }
31779+}
7f207e10
AM
31780diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
31781--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 31782+++ linux/fs/aufs/sysrq.c 2019-03-05 12:13:00.142557771 +0100
062440b3 31783@@ -0,0 +1,160 @@
cd7a4cd9 31784+// SPDX-License-Identifier: GPL-2.0
1facf9fc 31785+/*
ba1aed25 31786+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 31787+ *
31788+ * This program, aufs is free software; you can redistribute it and/or modify
31789+ * it under the terms of the GNU General Public License as published by
31790+ * the Free Software Foundation; either version 2 of the License, or
31791+ * (at your option) any later version.
dece6358
AM
31792+ *
31793+ * This program is distributed in the hope that it will be useful,
31794+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31795+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31796+ * GNU General Public License for more details.
31797+ *
31798+ * You should have received a copy of the GNU General Public License
523b37e3 31799+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31800+ */
31801+
31802+/*
acd2b654 31803+ * magic sysrq handler
1facf9fc 31804+ */
31805+
1facf9fc 31806+/* #include <linux/sysrq.h> */
027c5e7a 31807+#include <linux/writeback.h>
1facf9fc 31808+#include "aufs.h"
31809+
31810+/* ---------------------------------------------------------------------- */
31811+
31812+static void sysrq_sb(struct super_block *sb)
31813+{
31814+ char *plevel;
31815+ struct au_sbinfo *sbinfo;
31816+ struct file *file;
8b6a4947
AM
31817+ struct hlist_bl_head *files;
31818+ struct hlist_bl_node *pos;
523b37e3 31819+ struct au_finfo *finfo;
1facf9fc 31820+
31821+ plevel = au_plevel;
31822+ au_plevel = KERN_WARNING;
1facf9fc 31823+
4a4d8108 31824+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
31825+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
31826+
31827+ sbinfo = au_sbi(sb);
4a4d8108 31828+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 31829+ pr("superblock\n");
1facf9fc 31830+ au_dpri_sb(sb);
027c5e7a
AM
31831+
31832+#if 0
c06a8ce3 31833+ pr("root dentry\n");
1facf9fc 31834+ au_dpri_dentry(sb->s_root);
c06a8ce3 31835+ pr("root inode\n");
5527c038 31836+ au_dpri_inode(d_inode(sb->s_root));
027c5e7a
AM
31837+#endif
31838+
1facf9fc 31839+#if 0
027c5e7a
AM
31840+ do {
31841+ int err, i, j, ndentry;
31842+ struct au_dcsub_pages dpages;
31843+ struct au_dpage *dpage;
31844+
31845+ err = au_dpages_init(&dpages, GFP_ATOMIC);
31846+ if (unlikely(err))
31847+ break;
31848+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
31849+ if (!err)
31850+ for (i = 0; i < dpages.ndpage; i++) {
31851+ dpage = dpages.dpages + i;
31852+ ndentry = dpage->ndentry;
31853+ for (j = 0; j < ndentry; j++)
31854+ au_dpri_dentry(dpage->dentries[j]);
31855+ }
31856+ au_dpages_free(&dpages);
31857+ } while (0);
31858+#endif
31859+
31860+#if 1
31861+ {
31862+ struct inode *i;
076b876e 31863+
c06a8ce3 31864+ pr("isolated inode\n");
79b8bda9 31865+ spin_lock(&sb->s_inode_list_lock);
2cbb1c4b
JR
31866+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
31867+ spin_lock(&i->i_lock);
b4510431 31868+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 31869+ au_dpri_inode(i);
2cbb1c4b
JR
31870+ spin_unlock(&i->i_lock);
31871+ }
79b8bda9 31872+ spin_unlock(&sb->s_inode_list_lock);
027c5e7a 31873+ }
1facf9fc 31874+#endif
c06a8ce3 31875+ pr("files\n");
523b37e3 31876+ files = &au_sbi(sb)->si_files;
8b6a4947
AM
31877+ hlist_bl_lock(files);
31878+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) {
4a4d8108 31879+ umode_t mode;
076b876e 31880+
523b37e3 31881+ file = finfo->fi_file;
c06a8ce3 31882+ mode = file_inode(file)->i_mode;
38d290e6 31883+ if (!special_file(mode))
1facf9fc 31884+ au_dpri_file(file);
523b37e3 31885+ }
8b6a4947 31886+ hlist_bl_unlock(files);
c06a8ce3 31887+ pr("done\n");
1facf9fc 31888+
c06a8ce3 31889+#undef pr
1facf9fc 31890+ au_plevel = plevel;
1facf9fc 31891+}
31892+
31893+/* ---------------------------------------------------------------------- */
31894+
31895+/* module parameter */
31896+static char *aufs_sysrq_key = "a";
cd7a4cd9 31897+module_param_named(sysrq, aufs_sysrq_key, charp, 0444);
1facf9fc 31898+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
31899+
0c5527e5 31900+static void au_sysrq(int key __maybe_unused)
1facf9fc 31901+{
1facf9fc 31902+ struct au_sbinfo *sbinfo;
8b6a4947 31903+ struct hlist_bl_node *pos;
1facf9fc 31904+
027c5e7a 31905+ lockdep_off();
53392da6 31906+ au_sbilist_lock();
8b6a4947 31907+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list)
1facf9fc 31908+ sysrq_sb(sbinfo->si_sb);
53392da6 31909+ au_sbilist_unlock();
027c5e7a 31910+ lockdep_on();
1facf9fc 31911+}
31912+
31913+static struct sysrq_key_op au_sysrq_op = {
31914+ .handler = au_sysrq,
31915+ .help_msg = "Aufs",
31916+ .action_msg = "Aufs",
31917+ .enable_mask = SYSRQ_ENABLE_DUMP
31918+};
31919+
31920+/* ---------------------------------------------------------------------- */
31921+
31922+int __init au_sysrq_init(void)
31923+{
31924+ int err;
31925+ char key;
31926+
31927+ err = -1;
31928+ key = *aufs_sysrq_key;
31929+ if ('a' <= key && key <= 'z')
31930+ err = register_sysrq_key(key, &au_sysrq_op);
31931+ if (unlikely(err))
4a4d8108 31932+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 31933+ return err;
31934+}
31935+
31936+void au_sysrq_fin(void)
31937+{
31938+ int err;
076b876e 31939+
1facf9fc 31940+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
31941+ if (unlikely(err))
4a4d8108 31942+ pr_err("err %d (ignored)\n", err);
1facf9fc 31943+}
7f207e10
AM
31944diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
31945--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
31946+++ linux/fs/aufs/vdir.c 2019-05-06 09:03:04.820143837 +0200
31947@@ -0,0 +1,896 @@
cd7a4cd9 31948+// SPDX-License-Identifier: GPL-2.0
1facf9fc 31949+/*
ba1aed25 31950+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 31951+ *
31952+ * This program, aufs is free software; you can redistribute it and/or modify
31953+ * it under the terms of the GNU General Public License as published by
31954+ * the Free Software Foundation; either version 2 of the License, or
31955+ * (at your option) any later version.
dece6358
AM
31956+ *
31957+ * This program is distributed in the hope that it will be useful,
31958+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31959+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31960+ * GNU General Public License for more details.
31961+ *
31962+ * You should have received a copy of the GNU General Public License
523b37e3 31963+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31964+ */
31965+
31966+/*
31967+ * virtual or vertical directory
31968+ */
31969+
eca801bf 31970+#include <linux/iversion.h>
1facf9fc 31971+#include "aufs.h"
31972+
dece6358 31973+static unsigned int calc_size(int nlen)
1facf9fc 31974+{
dece6358 31975+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 31976+}
31977+
31978+static int set_deblk_end(union au_vdir_deblk_p *p,
31979+ union au_vdir_deblk_p *deblk_end)
31980+{
31981+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
31982+ p->de->de_str.len = 0;
31983+ /* smp_mb(); */
31984+ return 0;
31985+ }
31986+ return -1; /* error */
31987+}
31988+
31989+/* returns true or false */
31990+static int is_deblk_end(union au_vdir_deblk_p *p,
31991+ union au_vdir_deblk_p *deblk_end)
31992+{
31993+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
31994+ return !p->de->de_str.len;
31995+ return 1;
31996+}
31997+
31998+static unsigned char *last_deblk(struct au_vdir *vdir)
31999+{
32000+ return vdir->vd_deblk[vdir->vd_nblk - 1];
32001+}
32002+
32003+/* ---------------------------------------------------------------------- */
32004+
79b8bda9 32005+/* estimate the appropriate size for name hash table */
1308ab2a 32006+unsigned int au_rdhash_est(loff_t sz)
32007+{
32008+ unsigned int n;
32009+
32010+ n = UINT_MAX;
32011+ sz >>= 10;
32012+ if (sz < n)
32013+ n = sz;
32014+ if (sz < AUFS_RDHASH_DEF)
32015+ n = AUFS_RDHASH_DEF;
4a4d8108 32016+ /* pr_info("n %u\n", n); */
1308ab2a 32017+ return n;
32018+}
32019+
1facf9fc 32020+/*
32021+ * the allocated memory has to be freed by
dece6358 32022+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 32023+ */
dece6358 32024+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 32025+{
1facf9fc 32026+ struct hlist_head *head;
dece6358 32027+ unsigned int u;
076b876e 32028+ size_t sz;
1facf9fc 32029+
076b876e
AM
32030+ sz = sizeof(*nhash->nh_head) * num_hash;
32031+ head = kmalloc(sz, gfp);
dece6358
AM
32032+ if (head) {
32033+ nhash->nh_num = num_hash;
32034+ nhash->nh_head = head;
32035+ for (u = 0; u < num_hash; u++)
1facf9fc 32036+ INIT_HLIST_HEAD(head++);
dece6358 32037+ return 0; /* success */
1facf9fc 32038+ }
1facf9fc 32039+
dece6358 32040+ return -ENOMEM;
1facf9fc 32041+}
32042+
dece6358
AM
32043+static void nhash_count(struct hlist_head *head)
32044+{
32045+#if 0
32046+ unsigned long n;
32047+ struct hlist_node *pos;
32048+
32049+ n = 0;
32050+ hlist_for_each(pos, head)
32051+ n++;
4a4d8108 32052+ pr_info("%lu\n", n);
dece6358
AM
32053+#endif
32054+}
32055+
32056+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 32057+{
c06a8ce3
AM
32058+ struct au_vdir_wh *pos;
32059+ struct hlist_node *node;
1facf9fc 32060+
c06a8ce3 32061+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
9f237c51 32062+ au_kfree_rcu(pos);
1facf9fc 32063+}
32064+
dece6358 32065+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 32066+{
c06a8ce3
AM
32067+ struct au_vdir_dehstr *pos;
32068+ struct hlist_node *node;
1facf9fc 32069+
c06a8ce3 32070+ hlist_for_each_entry_safe(pos, node, head, hash)
1c60b727 32071+ au_cache_free_vdir_dehstr(pos);
1facf9fc 32072+}
32073+
dece6358
AM
32074+static void au_nhash_do_free(struct au_nhash *nhash,
32075+ void (*free)(struct hlist_head *head))
1facf9fc 32076+{
1308ab2a 32077+ unsigned int n;
1facf9fc 32078+ struct hlist_head *head;
1facf9fc 32079+
dece6358 32080+ n = nhash->nh_num;
1308ab2a 32081+ if (!n)
32082+ return;
32083+
dece6358 32084+ head = nhash->nh_head;
1308ab2a 32085+ while (n-- > 0) {
dece6358
AM
32086+ nhash_count(head);
32087+ free(head++);
1facf9fc 32088+ }
9f237c51 32089+ au_kfree_try_rcu(nhash->nh_head);
1facf9fc 32090+}
32091+
dece6358 32092+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 32093+{
dece6358
AM
32094+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
32095+}
1facf9fc 32096+
dece6358
AM
32097+static void au_nhash_de_free(struct au_nhash *delist)
32098+{
32099+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 32100+}
32101+
32102+/* ---------------------------------------------------------------------- */
32103+
32104+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
32105+ int limit)
32106+{
32107+ int num;
32108+ unsigned int u, n;
32109+ struct hlist_head *head;
c06a8ce3 32110+ struct au_vdir_wh *pos;
1facf9fc 32111+
32112+ num = 0;
32113+ n = whlist->nh_num;
32114+ head = whlist->nh_head;
1308ab2a 32115+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
32116+ hlist_for_each_entry(pos, head, wh_hash)
32117+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 32118+ return 1;
1facf9fc 32119+ return 0;
32120+}
32121+
32122+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 32123+ unsigned char *name,
1facf9fc 32124+ unsigned int len)
32125+{
dece6358
AM
32126+ unsigned int v;
32127+ /* const unsigned int magic_bit = 12; */
32128+
1308ab2a 32129+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
32130+
dece6358 32131+ v = 0;
f0c0a007
AM
32132+ if (len > 8)
32133+ len = 8;
dece6358
AM
32134+ while (len--)
32135+ v += *name++;
32136+ /* v = hash_long(v, magic_bit); */
32137+ v %= nhash->nh_num;
32138+ return nhash->nh_head + v;
32139+}
32140+
32141+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
32142+ int nlen)
32143+{
32144+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 32145+}
32146+
32147+/* returns found or not */
dece6358 32148+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 32149+{
32150+ struct hlist_head *head;
c06a8ce3 32151+ struct au_vdir_wh *pos;
1facf9fc 32152+ struct au_vdir_destr *str;
32153+
dece6358 32154+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
32155+ hlist_for_each_entry(pos, head, wh_hash) {
32156+ str = &pos->wh_str;
1facf9fc 32157+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
32158+ if (au_nhash_test_name(str, name, nlen))
32159+ return 1;
32160+ }
32161+ return 0;
32162+}
32163+
32164+/* returns found(true) or not */
32165+static int test_known(struct au_nhash *delist, char *name, int nlen)
32166+{
32167+ struct hlist_head *head;
c06a8ce3 32168+ struct au_vdir_dehstr *pos;
dece6358
AM
32169+ struct au_vdir_destr *str;
32170+
32171+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
32172+ hlist_for_each_entry(pos, head, hash) {
32173+ str = pos->str;
dece6358
AM
32174+ AuDbg("%.*s\n", str->len, str->name);
32175+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 32176+ return 1;
32177+ }
32178+ return 0;
32179+}
32180+
dece6358
AM
32181+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
32182+ unsigned char d_type)
32183+{
32184+#ifdef CONFIG_AUFS_SHWH
32185+ wh->wh_ino = ino;
32186+ wh->wh_type = d_type;
32187+#endif
32188+}
32189+
32190+/* ---------------------------------------------------------------------- */
32191+
32192+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
32193+ unsigned int d_type, aufs_bindex_t bindex,
32194+ unsigned char shwh)
1facf9fc 32195+{
32196+ int err;
32197+ struct au_vdir_destr *str;
32198+ struct au_vdir_wh *wh;
32199+
dece6358 32200+ AuDbg("%.*s\n", nlen, name);
1308ab2a 32201+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
32202+
1facf9fc 32203+ err = -ENOMEM;
dece6358 32204+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 32205+ if (unlikely(!wh))
32206+ goto out;
32207+
32208+ err = 0;
32209+ wh->wh_bindex = bindex;
dece6358
AM
32210+ if (shwh)
32211+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 32212+ str = &wh->wh_str;
dece6358
AM
32213+ str->len = nlen;
32214+ memcpy(str->name, name, nlen);
32215+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 32216+ /* smp_mb(); */
32217+
4f0767ce 32218+out:
1facf9fc 32219+ return err;
32220+}
32221+
1facf9fc 32222+static int append_deblk(struct au_vdir *vdir)
32223+{
32224+ int err;
dece6358 32225+ unsigned long ul;
1facf9fc 32226+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
32227+ union au_vdir_deblk_p p, deblk_end;
32228+ unsigned char **o;
32229+
32230+ err = -ENOMEM;
e2f27e51
AM
32231+ o = au_krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
32232+ GFP_NOFS, /*may_shrink*/0);
1facf9fc 32233+ if (unlikely(!o))
32234+ goto out;
32235+
32236+ vdir->vd_deblk = o;
32237+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
32238+ if (p.deblk) {
32239+ ul = vdir->vd_nblk++;
32240+ vdir->vd_deblk[ul] = p.deblk;
32241+ vdir->vd_last.ul = ul;
32242+ vdir->vd_last.p.deblk = p.deblk;
32243+ deblk_end.deblk = p.deblk + deblk_sz;
32244+ err = set_deblk_end(&p, &deblk_end);
32245+ }
32246+
4f0767ce 32247+out:
1facf9fc 32248+ return err;
32249+}
32250+
dece6358
AM
32251+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
32252+ unsigned int d_type, struct au_nhash *delist)
32253+{
32254+ int err;
32255+ unsigned int sz;
32256+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
32257+ union au_vdir_deblk_p p, *room, deblk_end;
32258+ struct au_vdir_dehstr *dehstr;
32259+
32260+ p.deblk = last_deblk(vdir);
32261+ deblk_end.deblk = p.deblk + deblk_sz;
32262+ room = &vdir->vd_last.p;
32263+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
32264+ || !is_deblk_end(room, &deblk_end));
32265+
32266+ sz = calc_size(nlen);
32267+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
32268+ err = append_deblk(vdir);
32269+ if (unlikely(err))
32270+ goto out;
32271+
32272+ p.deblk = last_deblk(vdir);
32273+ deblk_end.deblk = p.deblk + deblk_sz;
32274+ /* smp_mb(); */
32275+ AuDebugOn(room->deblk != p.deblk);
32276+ }
32277+
32278+ err = -ENOMEM;
4a4d8108 32279+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
32280+ if (unlikely(!dehstr))
32281+ goto out;
32282+
32283+ dehstr->str = &room->de->de_str;
32284+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
32285+ room->de->de_ino = ino;
32286+ room->de->de_type = d_type;
32287+ room->de->de_str.len = nlen;
32288+ memcpy(room->de->de_str.name, name, nlen);
32289+
32290+ err = 0;
32291+ room->deblk += sz;
32292+ if (unlikely(set_deblk_end(room, &deblk_end)))
32293+ err = append_deblk(vdir);
32294+ /* smp_mb(); */
32295+
4f0767ce 32296+out:
dece6358
AM
32297+ return err;
32298+}
32299+
32300+/* ---------------------------------------------------------------------- */
32301+
1c60b727 32302+void au_vdir_free(struct au_vdir *vdir)
dece6358
AM
32303+{
32304+ unsigned char **deblk;
32305+
32306+ deblk = vdir->vd_deblk;
1c60b727 32307+ while (vdir->vd_nblk--)
9f237c51
AM
32308+ au_kfree_try_rcu(*deblk++);
32309+ au_kfree_try_rcu(vdir->vd_deblk);
1c60b727 32310+ au_cache_free_vdir(vdir);
dece6358
AM
32311+}
32312+
1308ab2a 32313+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 32314+{
32315+ struct au_vdir *vdir;
1308ab2a 32316+ struct super_block *sb;
1facf9fc 32317+ int err;
32318+
2000de60 32319+ sb = file->f_path.dentry->d_sb;
dece6358
AM
32320+ SiMustAnyLock(sb);
32321+
1facf9fc 32322+ err = -ENOMEM;
32323+ vdir = au_cache_alloc_vdir();
32324+ if (unlikely(!vdir))
32325+ goto out;
32326+
32327+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
32328+ if (unlikely(!vdir->vd_deblk))
32329+ goto out_free;
32330+
32331+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 32332+ if (!vdir->vd_deblk_sz) {
79b8bda9 32333+ /* estimate the appropriate size for deblk */
1308ab2a 32334+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 32335+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 32336+ }
1facf9fc 32337+ vdir->vd_nblk = 0;
32338+ vdir->vd_version = 0;
32339+ vdir->vd_jiffy = 0;
32340+ err = append_deblk(vdir);
32341+ if (!err)
32342+ return vdir; /* success */
32343+
9f237c51 32344+ au_kfree_try_rcu(vdir->vd_deblk);
1facf9fc 32345+
4f0767ce 32346+out_free:
1c60b727 32347+ au_cache_free_vdir(vdir);
4f0767ce 32348+out:
1facf9fc 32349+ vdir = ERR_PTR(err);
32350+ return vdir;
32351+}
32352+
32353+static int reinit_vdir(struct au_vdir *vdir)
32354+{
32355+ int err;
32356+ union au_vdir_deblk_p p, deblk_end;
32357+
32358+ while (vdir->vd_nblk > 1) {
9f237c51 32359+ au_kfree_try_rcu(vdir->vd_deblk[vdir->vd_nblk - 1]);
1facf9fc 32360+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
32361+ vdir->vd_nblk--;
32362+ }
32363+ p.deblk = vdir->vd_deblk[0];
32364+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
32365+ err = set_deblk_end(&p, &deblk_end);
32366+ /* keep vd_dblk_sz */
32367+ vdir->vd_last.ul = 0;
32368+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
32369+ vdir->vd_version = 0;
32370+ vdir->vd_jiffy = 0;
32371+ /* smp_mb(); */
32372+ return err;
32373+}
32374+
32375+/* ---------------------------------------------------------------------- */
32376+
1facf9fc 32377+#define AuFillVdir_CALLED 1
32378+#define AuFillVdir_WHABLE (1 << 1)
dece6358 32379+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 32380+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
32381+#define au_fset_fillvdir(flags, name) \
32382+ do { (flags) |= AuFillVdir_##name; } while (0)
32383+#define au_fclr_fillvdir(flags, name) \
32384+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 32385+
dece6358
AM
32386+#ifndef CONFIG_AUFS_SHWH
32387+#undef AuFillVdir_SHWH
32388+#define AuFillVdir_SHWH 0
32389+#endif
32390+
1facf9fc 32391+struct fillvdir_arg {
392086de 32392+ struct dir_context ctx;
1facf9fc 32393+ struct file *file;
32394+ struct au_vdir *vdir;
dece6358
AM
32395+ struct au_nhash delist;
32396+ struct au_nhash whlist;
1facf9fc 32397+ aufs_bindex_t bindex;
32398+ unsigned int flags;
32399+ int err;
32400+};
32401+
392086de 32402+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 32403+ loff_t offset __maybe_unused, u64 h_ino,
32404+ unsigned int d_type)
32405+{
392086de 32406+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 32407+ char *name = (void *)__name;
32408+ struct super_block *sb;
1facf9fc 32409+ ino_t ino;
dece6358 32410+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 32411+
1facf9fc 32412+ arg->err = 0;
2000de60 32413+ sb = arg->file->f_path.dentry->d_sb;
1facf9fc 32414+ au_fset_fillvdir(arg->flags, CALLED);
32415+ /* smp_mb(); */
dece6358 32416+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 32417+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
32418+ if (test_known(&arg->delist, name, nlen)
32419+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
32420+ goto out; /* already exists or whiteouted */
1facf9fc 32421+
dece6358 32422+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
32423+ if (!arg->err) {
32424+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
32425+ d_type = DT_UNKNOWN;
dece6358
AM
32426+ arg->err = append_de(arg->vdir, name, nlen, ino,
32427+ d_type, &arg->delist);
4a4d8108 32428+ }
1facf9fc 32429+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
32430+ name += AUFS_WH_PFX_LEN;
dece6358
AM
32431+ nlen -= AUFS_WH_PFX_LEN;
32432+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
32433+ goto out; /* already whiteouted */
1facf9fc 32434+
acd2b654 32435+ ino = 0; /* just to suppress a warning */
dece6358
AM
32436+ if (shwh)
32437+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
32438+ &ino);
4a4d8108
AM
32439+ if (!arg->err) {
32440+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
32441+ d_type = DT_UNKNOWN;
1facf9fc 32442+ arg->err = au_nhash_append_wh
dece6358
AM
32443+ (&arg->whlist, name, nlen, ino, d_type,
32444+ arg->bindex, shwh);
4a4d8108 32445+ }
1facf9fc 32446+ }
32447+
4f0767ce 32448+out:
1facf9fc 32449+ if (!arg->err)
32450+ arg->vdir->vd_jiffy = jiffies;
32451+ /* smp_mb(); */
32452+ AuTraceErr(arg->err);
32453+ return arg->err;
32454+}
32455+
dece6358
AM
32456+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
32457+ struct au_nhash *whlist, struct au_nhash *delist)
32458+{
32459+#ifdef CONFIG_AUFS_SHWH
32460+ int err;
32461+ unsigned int nh, u;
32462+ struct hlist_head *head;
c06a8ce3
AM
32463+ struct au_vdir_wh *pos;
32464+ struct hlist_node *n;
dece6358
AM
32465+ char *p, *o;
32466+ struct au_vdir_destr *destr;
32467+
32468+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
32469+
32470+ err = -ENOMEM;
537831f9 32471+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
32472+ if (unlikely(!p))
32473+ goto out;
32474+
32475+ err = 0;
32476+ nh = whlist->nh_num;
32477+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
32478+ p += AUFS_WH_PFX_LEN;
32479+ for (u = 0; u < nh; u++) {
32480+ head = whlist->nh_head + u;
c06a8ce3
AM
32481+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
32482+ destr = &pos->wh_str;
dece6358
AM
32483+ memcpy(p, destr->name, destr->len);
32484+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 32485+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
32486+ if (unlikely(err))
32487+ break;
32488+ }
32489+ }
32490+
1c60b727 32491+ free_page((unsigned long)o);
dece6358 32492+
4f0767ce 32493+out:
dece6358
AM
32494+ AuTraceErr(err);
32495+ return err;
32496+#else
32497+ return 0;
32498+#endif
32499+}
32500+
1facf9fc 32501+static int au_do_read_vdir(struct fillvdir_arg *arg)
32502+{
32503+ int err;
dece6358 32504+ unsigned int rdhash;
1facf9fc 32505+ loff_t offset;
5afbbe0d 32506+ aufs_bindex_t bbot, bindex, btop;
dece6358 32507+ unsigned char shwh;
1facf9fc 32508+ struct file *hf, *file;
32509+ struct super_block *sb;
32510+
1facf9fc 32511+ file = arg->file;
2000de60 32512+ sb = file->f_path.dentry->d_sb;
dece6358
AM
32513+ SiMustAnyLock(sb);
32514+
32515+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 32516+ if (!rdhash)
32517+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
32518+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
32519+ if (unlikely(err))
1facf9fc 32520+ goto out;
dece6358
AM
32521+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
32522+ if (unlikely(err))
1facf9fc 32523+ goto out_delist;
32524+
32525+ err = 0;
32526+ arg->flags = 0;
dece6358
AM
32527+ shwh = 0;
32528+ if (au_opt_test(au_mntflags(sb), SHWH)) {
32529+ shwh = 1;
32530+ au_fset_fillvdir(arg->flags, SHWH);
32531+ }
5afbbe0d
AM
32532+ btop = au_fbtop(file);
32533+ bbot = au_fbbot_dir(file);
32534+ for (bindex = btop; !err && bindex <= bbot; bindex++) {
4a4d8108 32535+ hf = au_hf_dir(file, bindex);
1facf9fc 32536+ if (!hf)
32537+ continue;
32538+
32539+ offset = vfsub_llseek(hf, 0, SEEK_SET);
32540+ err = offset;
32541+ if (unlikely(offset))
32542+ break;
32543+
32544+ arg->bindex = bindex;
32545+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358 32546+ if (shwh
5afbbe0d 32547+ || (bindex != bbot
dece6358 32548+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 32549+ au_fset_fillvdir(arg->flags, WHABLE);
32550+ do {
32551+ arg->err = 0;
32552+ au_fclr_fillvdir(arg->flags, CALLED);
32553+ /* smp_mb(); */
392086de 32554+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 32555+ if (err >= 0)
32556+ err = arg->err;
32557+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
32558+
32559+ /*
32560+ * dir_relax() may be good for concurrency, but aufs should not
32561+ * use it since it will cause a lockdep problem.
32562+ */
1facf9fc 32563+ }
dece6358
AM
32564+
32565+ if (!err && shwh)
32566+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
32567+
32568+ au_nhash_wh_free(&arg->whlist);
1facf9fc 32569+
4f0767ce 32570+out_delist:
dece6358 32571+ au_nhash_de_free(&arg->delist);
4f0767ce 32572+out:
1facf9fc 32573+ return err;
32574+}
32575+
32576+static int read_vdir(struct file *file, int may_read)
32577+{
32578+ int err;
32579+ unsigned long expire;
32580+ unsigned char do_read;
392086de
AM
32581+ struct fillvdir_arg arg = {
32582+ .ctx = {
2000de60 32583+ .actor = fillvdir
392086de
AM
32584+ }
32585+ };
1facf9fc 32586+ struct inode *inode;
32587+ struct au_vdir *vdir, *allocated;
32588+
32589+ err = 0;
c06a8ce3 32590+ inode = file_inode(file);
1facf9fc 32591+ IMustLock(inode);
5afbbe0d 32592+ IiMustWriteLock(inode);
dece6358
AM
32593+ SiMustAnyLock(inode->i_sb);
32594+
1facf9fc 32595+ allocated = NULL;
32596+ do_read = 0;
32597+ expire = au_sbi(inode->i_sb)->si_rdcache;
32598+ vdir = au_ivdir(inode);
32599+ if (!vdir) {
32600+ do_read = 1;
1308ab2a 32601+ vdir = alloc_vdir(file);
1facf9fc 32602+ err = PTR_ERR(vdir);
32603+ if (IS_ERR(vdir))
32604+ goto out;
32605+ err = 0;
32606+ allocated = vdir;
32607+ } else if (may_read
be118d29 32608+ && (!inode_eq_iversion(inode, vdir->vd_version)
1facf9fc 32609+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
32610+ do_read = 1;
32611+ err = reinit_vdir(vdir);
32612+ if (unlikely(err))
32613+ goto out;
32614+ }
32615+
32616+ if (!do_read)
32617+ return 0; /* success */
32618+
32619+ arg.file = file;
32620+ arg.vdir = vdir;
32621+ err = au_do_read_vdir(&arg);
32622+ if (!err) {
392086de 32623+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
be118d29 32624+ vdir->vd_version = inode_query_iversion(inode);
1facf9fc 32625+ vdir->vd_last.ul = 0;
32626+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
32627+ if (allocated)
32628+ au_set_ivdir(inode, allocated);
32629+ } else if (allocated)
1c60b727 32630+ au_vdir_free(allocated);
1facf9fc 32631+
4f0767ce 32632+out:
1facf9fc 32633+ return err;
32634+}
32635+
32636+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
32637+{
32638+ int err, rerr;
32639+ unsigned long ul, n;
32640+ const unsigned int deblk_sz = src->vd_deblk_sz;
32641+
32642+ AuDebugOn(tgt->vd_nblk != 1);
32643+
32644+ err = -ENOMEM;
32645+ if (tgt->vd_nblk < src->vd_nblk) {
32646+ unsigned char **p;
32647+
e2f27e51
AM
32648+ p = au_krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
32649+ GFP_NOFS, /*may_shrink*/0);
1facf9fc 32650+ if (unlikely(!p))
32651+ goto out;
32652+ tgt->vd_deblk = p;
32653+ }
32654+
1308ab2a 32655+ if (tgt->vd_deblk_sz != deblk_sz) {
32656+ unsigned char *p;
32657+
32658+ tgt->vd_deblk_sz = deblk_sz;
e2f27e51
AM
32659+ p = au_krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS,
32660+ /*may_shrink*/1);
1308ab2a 32661+ if (unlikely(!p))
32662+ goto out;
32663+ tgt->vd_deblk[0] = p;
32664+ }
1facf9fc 32665+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 32666+ tgt->vd_version = src->vd_version;
32667+ tgt->vd_jiffy = src->vd_jiffy;
32668+
32669+ n = src->vd_nblk;
32670+ for (ul = 1; ul < n; ul++) {
dece6358
AM
32671+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
32672+ GFP_NOFS);
32673+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 32674+ goto out;
1308ab2a 32675+ tgt->vd_nblk++;
1facf9fc 32676+ }
1308ab2a 32677+ tgt->vd_nblk = n;
32678+ tgt->vd_last.ul = tgt->vd_last.ul;
32679+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
32680+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
32681+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 32682+ /* smp_mb(); */
32683+ return 0; /* success */
32684+
4f0767ce 32685+out:
1facf9fc 32686+ rerr = reinit_vdir(tgt);
32687+ BUG_ON(rerr);
32688+ return err;
32689+}
32690+
32691+int au_vdir_init(struct file *file)
32692+{
32693+ int err;
32694+ struct inode *inode;
32695+ struct au_vdir *vdir_cache, *allocated;
32696+
392086de 32697+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 32698+ err = read_vdir(file, !file->f_pos);
32699+ if (unlikely(err))
32700+ goto out;
32701+
32702+ allocated = NULL;
32703+ vdir_cache = au_fvdir_cache(file);
32704+ if (!vdir_cache) {
1308ab2a 32705+ vdir_cache = alloc_vdir(file);
1facf9fc 32706+ err = PTR_ERR(vdir_cache);
32707+ if (IS_ERR(vdir_cache))
32708+ goto out;
32709+ allocated = vdir_cache;
32710+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 32711+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 32712+ err = reinit_vdir(vdir_cache);
32713+ if (unlikely(err))
32714+ goto out;
32715+ } else
32716+ return 0; /* success */
32717+
c06a8ce3 32718+ inode = file_inode(file);
1facf9fc 32719+ err = copy_vdir(vdir_cache, au_ivdir(inode));
32720+ if (!err) {
be118d29 32721+ file->f_version = inode_query_iversion(inode);
1facf9fc 32722+ if (allocated)
32723+ au_set_fvdir_cache(file, allocated);
32724+ } else if (allocated)
1c60b727 32725+ au_vdir_free(allocated);
1facf9fc 32726+
4f0767ce 32727+out:
1facf9fc 32728+ return err;
32729+}
32730+
32731+static loff_t calc_offset(struct au_vdir *vdir)
32732+{
32733+ loff_t offset;
32734+ union au_vdir_deblk_p p;
32735+
32736+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
32737+ offset = vdir->vd_last.p.deblk - p.deblk;
32738+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
32739+ return offset;
32740+}
32741+
32742+/* returns true or false */
392086de 32743+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 32744+{
32745+ int valid;
32746+ unsigned int deblk_sz;
32747+ unsigned long ul, n;
32748+ loff_t offset;
32749+ union au_vdir_deblk_p p, deblk_end;
32750+ struct au_vdir *vdir_cache;
32751+
32752+ valid = 1;
32753+ vdir_cache = au_fvdir_cache(file);
32754+ offset = calc_offset(vdir_cache);
32755+ AuDbg("offset %lld\n", offset);
392086de 32756+ if (ctx->pos == offset)
1facf9fc 32757+ goto out;
32758+
32759+ vdir_cache->vd_last.ul = 0;
32760+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 32761+ if (!ctx->pos)
1facf9fc 32762+ goto out;
32763+
32764+ valid = 0;
32765+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 32766+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 32767+ AuDbg("ul %lu\n", ul);
32768+ if (ul >= vdir_cache->vd_nblk)
32769+ goto out;
32770+
32771+ n = vdir_cache->vd_nblk;
32772+ for (; ul < n; ul++) {
32773+ p.deblk = vdir_cache->vd_deblk[ul];
32774+ deblk_end.deblk = p.deblk + deblk_sz;
32775+ offset = ul;
32776+ offset *= deblk_sz;
392086de 32777+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 32778+ unsigned int l;
32779+
32780+ l = calc_size(p.de->de_str.len);
32781+ offset += l;
32782+ p.deblk += l;
32783+ }
32784+ if (!is_deblk_end(&p, &deblk_end)) {
32785+ valid = 1;
32786+ vdir_cache->vd_last.ul = ul;
32787+ vdir_cache->vd_last.p = p;
32788+ break;
32789+ }
32790+ }
32791+
4f0767ce 32792+out:
1facf9fc 32793+ /* smp_mb(); */
b00004a5
AM
32794+ if (!valid)
32795+ AuDbg("valid %d\n", !valid);
1facf9fc 32796+ return valid;
32797+}
32798+
392086de 32799+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 32800+{
1facf9fc 32801+ unsigned int l, deblk_sz;
32802+ union au_vdir_deblk_p deblk_end;
32803+ struct au_vdir *vdir_cache;
32804+ struct au_vdir_de *de;
32805+
392086de 32806+ if (!seek_vdir(file, ctx))
1facf9fc 32807+ return 0;
32808+
acd2b654 32809+ vdir_cache = au_fvdir_cache(file);
1facf9fc 32810+ deblk_sz = vdir_cache->vd_deblk_sz;
32811+ while (1) {
32812+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
32813+ deblk_end.deblk += deblk_sz;
32814+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
32815+ de = vdir_cache->vd_last.p.de;
32816+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 32817+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 32818+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
32819+ if (unlikely(!dir_emit(ctx, de->de_str.name,
32820+ de->de_str.len, de->de_ino,
32821+ de->de_type))) {
1facf9fc 32822+ /* todo: ignore the error caused by udba? */
32823+ /* return err; */
32824+ return 0;
32825+ }
32826+
32827+ l = calc_size(de->de_str.len);
32828+ vdir_cache->vd_last.p.deblk += l;
392086de 32829+ ctx->pos += l;
1facf9fc 32830+ }
32831+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
32832+ vdir_cache->vd_last.ul++;
32833+ vdir_cache->vd_last.p.deblk
32834+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 32835+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 32836+ continue;
32837+ }
32838+ break;
32839+ }
32840+
32841+ /* smp_mb(); */
32842+ return 0;
32843+}
7f207e10
AM
32844diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
32845--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 32846+++ linux/fs/aufs/vfsub.c 2019-03-05 12:13:00.145891204 +0100
acd2b654 32847@@ -0,0 +1,902 @@
cd7a4cd9 32848+// SPDX-License-Identifier: GPL-2.0
1facf9fc 32849+/*
ba1aed25 32850+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 32851+ *
32852+ * This program, aufs is free software; you can redistribute it and/or modify
32853+ * it under the terms of the GNU General Public License as published by
32854+ * the Free Software Foundation; either version 2 of the License, or
32855+ * (at your option) any later version.
dece6358
AM
32856+ *
32857+ * This program is distributed in the hope that it will be useful,
32858+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32859+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32860+ * GNU General Public License for more details.
32861+ *
32862+ * You should have received a copy of the GNU General Public License
523b37e3 32863+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32864+ */
32865+
32866+/*
32867+ * sub-routines for VFS
32868+ */
32869+
8b6a4947 32870+#include <linux/mnt_namespace.h>
dece6358 32871+#include <linux/namei.h>
8cdd5066 32872+#include <linux/nsproxy.h>
dece6358
AM
32873+#include <linux/security.h>
32874+#include <linux/splice.h>
1facf9fc 32875+#include "aufs.h"
32876+
8cdd5066
JR
32877+#ifdef CONFIG_AUFS_BR_FUSE
32878+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb)
32879+{
8cdd5066
JR
32880+ if (!au_test_fuse(h_sb) || !au_userns)
32881+ return 0;
32882+
8b6a4947 32883+ return is_current_mnt_ns(mnt) ? 0 : -EACCES;
8cdd5066
JR
32884+}
32885+#endif
32886+
a2654f78
AM
32887+int vfsub_sync_filesystem(struct super_block *h_sb, int wait)
32888+{
32889+ int err;
32890+
32891+ lockdep_off();
32892+ down_read(&h_sb->s_umount);
32893+ err = __sync_filesystem(h_sb, wait);
32894+ up_read(&h_sb->s_umount);
32895+ lockdep_on();
32896+
32897+ return err;
32898+}
32899+
8cdd5066
JR
32900+/* ---------------------------------------------------------------------- */
32901+
1facf9fc 32902+int vfsub_update_h_iattr(struct path *h_path, int *did)
32903+{
32904+ int err;
32905+ struct kstat st;
32906+ struct super_block *h_sb;
32907+
32908+ /* for remote fs, leave work for its getattr or d_revalidate */
32909+ /* for bad i_attr fs, handle them in aufs_getattr() */
32910+ /* still some fs may acquire i_mutex. we need to skip them */
32911+ err = 0;
32912+ if (!did)
32913+ did = &err;
32914+ h_sb = h_path->dentry->d_sb;
32915+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
32916+ if (*did)
521ced18 32917+ err = vfsub_getattr(h_path, &st);
1facf9fc 32918+
32919+ return err;
32920+}
32921+
32922+/* ---------------------------------------------------------------------- */
32923+
4a4d8108 32924+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 32925+{
32926+ struct file *file;
32927+
b4510431 32928+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 32929+ current_cred());
2cbb1c4b
JR
32930+ if (!IS_ERR_OR_NULL(file)
32931+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
5527c038 32932+ i_readcount_inc(d_inode(path->dentry));
4a4d8108 32933+
1308ab2a 32934+ return file;
32935+}
32936+
1facf9fc 32937+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
32938+{
32939+ struct file *file;
32940+
2cbb1c4b 32941+ lockdep_off();
7f207e10 32942+ file = filp_open(path,
2cbb1c4b 32943+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 32944+ mode);
2cbb1c4b 32945+ lockdep_on();
1facf9fc 32946+ if (IS_ERR(file))
32947+ goto out;
32948+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
32949+
4f0767ce 32950+out:
1facf9fc 32951+ return file;
32952+}
32953+
b912730e
AM
32954+/*
32955+ * Ideally this function should call VFS:do_last() in order to keep all its
32956+ * checkings. But it is very hard for aufs to regenerate several VFS internal
32957+ * structure such as nameidata. This is a second (or third) best approach.
32958+ * cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open().
32959+ */
32960+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
acd2b654 32961+ struct vfsub_aopen_args *args)
b912730e
AM
32962+{
32963+ int err;
acd2b654 32964+ struct au_branch *br = args->br;
b912730e
AM
32965+ struct file *file = args->file;
32966+ /* copied from linux/fs/namei.c:atomic_open() */
32967+ struct dentry *const DENTRY_NOT_SET = (void *)-1UL;
32968+
32969+ IMustLock(dir);
32970+ AuDebugOn(!dir->i_op->atomic_open);
32971+
32972+ err = au_br_test_oflag(args->open_flag, br);
32973+ if (unlikely(err))
32974+ goto out;
32975+
acd2b654
AM
32976+ au_lcnt_inc(&br->br_nfiles);
32977+ file->f_path.dentry = DENTRY_NOT_SET;
32978+ file->f_path.mnt = au_br_mnt(br);
32979+ AuDbg("%ps\n", dir->i_op->atomic_open);
b912730e 32980+ err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag,
acd2b654
AM
32981+ args->create_mode);
32982+ if (unlikely(err < 0)) {
32983+ au_lcnt_dec(&br->br_nfiles);
b912730e 32984+ goto out;
acd2b654 32985+ }
b912730e 32986+
acd2b654
AM
32987+ /* temporary workaround for nfsv4 branch */
32988+ if (au_test_nfs(dir->i_sb))
32989+ nfs_mark_for_revalidate(dir);
b912730e 32990+
acd2b654
AM
32991+ if (file->f_mode & FMODE_CREATED)
32992+ fsnotify_create(dir, dentry);
32993+ if (!(file->f_mode & FMODE_OPENED)) {
32994+ au_lcnt_dec(&br->br_nfiles);
32995+ goto out;
b912730e
AM
32996+ }
32997+
acd2b654
AM
32998+ /* todo: call VFS:may_open() here */
32999+ /* todo: ima_file_check() too? */
33000+ if (!err && (args->open_flag & __FMODE_EXEC))
33001+ err = deny_write_access(file);
33002+ if (!err)
33003+ fsnotify_open(file);
33004+ else
33005+ au_lcnt_dec(&br->br_nfiles);
33006+ /* note that the file is created and still opened */
b912730e
AM
33007+
33008+out:
33009+ return err;
33010+}
33011+
1facf9fc 33012+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
33013+{
33014+ int err;
33015+
1facf9fc 33016+ err = kern_path(name, flags, path);
5527c038 33017+ if (!err && d_is_positive(path->dentry))
1facf9fc 33018+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
33019+ return err;
33020+}
33021+
febd17d6
JR
33022+struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
33023+ struct dentry *parent, int len)
33024+{
33025+ struct path path = {
33026+ .mnt = NULL
33027+ };
33028+
33029+ path.dentry = lookup_one_len_unlocked(name, parent, len);
33030+ if (IS_ERR(path.dentry))
33031+ goto out;
33032+ if (d_is_positive(path.dentry))
33033+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
33034+
33035+out:
33036+ AuTraceErrPtr(path.dentry);
33037+ return path.dentry;
33038+}
33039+
1facf9fc 33040+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
33041+ int len)
33042+{
33043+ struct path path = {
33044+ .mnt = NULL
33045+ };
33046+
1308ab2a 33047+ /* VFS checks it too, but by WARN_ON_ONCE() */
5527c038 33048+ IMustLock(d_inode(parent));
1facf9fc 33049+
33050+ path.dentry = lookup_one_len(name, parent, len);
33051+ if (IS_ERR(path.dentry))
33052+ goto out;
5527c038 33053+ if (d_is_positive(path.dentry))
1facf9fc 33054+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
33055+
4f0767ce 33056+out:
4a4d8108 33057+ AuTraceErrPtr(path.dentry);
1facf9fc 33058+ return path.dentry;
33059+}
33060+
b4510431 33061+void vfsub_call_lkup_one(void *args)
2cbb1c4b 33062+{
b4510431
AM
33063+ struct vfsub_lkup_one_args *a = args;
33064+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
33065+}
33066+
1facf9fc 33067+/* ---------------------------------------------------------------------- */
33068+
33069+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
33070+ struct dentry *d2, struct au_hinode *hdir2)
33071+{
33072+ struct dentry *d;
33073+
2cbb1c4b 33074+ lockdep_off();
1facf9fc 33075+ d = lock_rename(d1, d2);
2cbb1c4b 33076+ lockdep_on();
4a4d8108 33077+ au_hn_suspend(hdir1);
1facf9fc 33078+ if (hdir1 != hdir2)
4a4d8108 33079+ au_hn_suspend(hdir2);
1facf9fc 33080+
33081+ return d;
33082+}
33083+
33084+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
33085+ struct dentry *d2, struct au_hinode *hdir2)
33086+{
4a4d8108 33087+ au_hn_resume(hdir1);
1facf9fc 33088+ if (hdir1 != hdir2)
4a4d8108 33089+ au_hn_resume(hdir2);
2cbb1c4b 33090+ lockdep_off();
1facf9fc 33091+ unlock_rename(d1, d2);
2cbb1c4b 33092+ lockdep_on();
1facf9fc 33093+}
33094+
33095+/* ---------------------------------------------------------------------- */
33096+
b4510431 33097+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 33098+{
33099+ int err;
33100+ struct dentry *d;
33101+
33102+ IMustLock(dir);
33103+
33104+ d = path->dentry;
33105+ path->dentry = d->d_parent;
b752ccd1 33106+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 33107+ path->dentry = d;
33108+ if (unlikely(err))
33109+ goto out;
33110+
c1595e42 33111+ lockdep_off();
b4510431 33112+ err = vfs_create(dir, path->dentry, mode, want_excl);
c1595e42 33113+ lockdep_on();
1facf9fc 33114+ if (!err) {
33115+ struct path tmp = *path;
33116+ int did;
33117+
33118+ vfsub_update_h_iattr(&tmp, &did);
33119+ if (did) {
33120+ tmp.dentry = path->dentry->d_parent;
33121+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33122+ }
33123+ /*ignore*/
33124+ }
33125+
4f0767ce 33126+out:
1facf9fc 33127+ return err;
33128+}
33129+
33130+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
33131+{
33132+ int err;
33133+ struct dentry *d;
33134+
33135+ IMustLock(dir);
33136+
33137+ d = path->dentry;
33138+ path->dentry = d->d_parent;
b752ccd1 33139+ err = security_path_symlink(path, d, symname);
1facf9fc 33140+ path->dentry = d;
33141+ if (unlikely(err))
33142+ goto out;
33143+
c1595e42 33144+ lockdep_off();
1facf9fc 33145+ err = vfs_symlink(dir, path->dentry, symname);
c1595e42 33146+ lockdep_on();
1facf9fc 33147+ if (!err) {
33148+ struct path tmp = *path;
33149+ int did;
33150+
33151+ vfsub_update_h_iattr(&tmp, &did);
33152+ if (did) {
33153+ tmp.dentry = path->dentry->d_parent;
33154+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33155+ }
33156+ /*ignore*/
33157+ }
33158+
4f0767ce 33159+out:
1facf9fc 33160+ return err;
33161+}
33162+
33163+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
33164+{
33165+ int err;
33166+ struct dentry *d;
33167+
33168+ IMustLock(dir);
33169+
33170+ d = path->dentry;
33171+ path->dentry = d->d_parent;
027c5e7a 33172+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 33173+ path->dentry = d;
33174+ if (unlikely(err))
33175+ goto out;
33176+
c1595e42 33177+ lockdep_off();
1facf9fc 33178+ err = vfs_mknod(dir, path->dentry, mode, dev);
c1595e42 33179+ lockdep_on();
1facf9fc 33180+ if (!err) {
33181+ struct path tmp = *path;
33182+ int did;
33183+
33184+ vfsub_update_h_iattr(&tmp, &did);
33185+ if (did) {
33186+ tmp.dentry = path->dentry->d_parent;
33187+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33188+ }
33189+ /*ignore*/
33190+ }
33191+
4f0767ce 33192+out:
1facf9fc 33193+ return err;
33194+}
33195+
33196+static int au_test_nlink(struct inode *inode)
33197+{
33198+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
33199+
33200+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
33201+ || inode->i_nlink < link_max)
33202+ return 0;
33203+ return -EMLINK;
33204+}
33205+
523b37e3
AM
33206+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
33207+ struct inode **delegated_inode)
1facf9fc 33208+{
33209+ int err;
33210+ struct dentry *d;
33211+
33212+ IMustLock(dir);
33213+
5527c038 33214+ err = au_test_nlink(d_inode(src_dentry));
1facf9fc 33215+ if (unlikely(err))
33216+ return err;
33217+
b4510431 33218+ /* we don't call may_linkat() */
1facf9fc 33219+ d = path->dentry;
33220+ path->dentry = d->d_parent;
b752ccd1 33221+ err = security_path_link(src_dentry, path, d);
1facf9fc 33222+ path->dentry = d;
33223+ if (unlikely(err))
33224+ goto out;
33225+
2cbb1c4b 33226+ lockdep_off();
523b37e3 33227+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 33228+ lockdep_on();
1facf9fc 33229+ if (!err) {
33230+ struct path tmp = *path;
33231+ int did;
33232+
33233+ /* fuse has different memory inode for the same inumber */
33234+ vfsub_update_h_iattr(&tmp, &did);
33235+ if (did) {
33236+ tmp.dentry = path->dentry->d_parent;
33237+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33238+ tmp.dentry = src_dentry;
33239+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33240+ }
33241+ /*ignore*/
33242+ }
33243+
4f0767ce 33244+out:
1facf9fc 33245+ return err;
33246+}
33247+
33248+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3 33249+ struct inode *dir, struct path *path,
f2c43d5f 33250+ struct inode **delegated_inode, unsigned int flags)
1facf9fc 33251+{
33252+ int err;
33253+ struct path tmp = {
33254+ .mnt = path->mnt
33255+ };
33256+ struct dentry *d;
33257+
33258+ IMustLock(dir);
33259+ IMustLock(src_dir);
33260+
33261+ d = path->dentry;
33262+ path->dentry = d->d_parent;
33263+ tmp.dentry = src_dentry->d_parent;
38d290e6 33264+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
1facf9fc 33265+ path->dentry = d;
33266+ if (unlikely(err))
33267+ goto out;
33268+
2cbb1c4b 33269+ lockdep_off();
523b37e3 33270+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
f2c43d5f 33271+ delegated_inode, flags);
2cbb1c4b 33272+ lockdep_on();
1facf9fc 33273+ if (!err) {
33274+ int did;
33275+
33276+ tmp.dentry = d->d_parent;
33277+ vfsub_update_h_iattr(&tmp, &did);
33278+ if (did) {
33279+ tmp.dentry = src_dentry;
33280+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33281+ tmp.dentry = src_dentry->d_parent;
33282+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33283+ }
33284+ /*ignore*/
33285+ }
33286+
4f0767ce 33287+out:
1facf9fc 33288+ return err;
33289+}
33290+
33291+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
33292+{
33293+ int err;
33294+ struct dentry *d;
33295+
33296+ IMustLock(dir);
33297+
33298+ d = path->dentry;
33299+ path->dentry = d->d_parent;
b752ccd1 33300+ err = security_path_mkdir(path, d, mode);
1facf9fc 33301+ path->dentry = d;
33302+ if (unlikely(err))
33303+ goto out;
33304+
c1595e42 33305+ lockdep_off();
1facf9fc 33306+ err = vfs_mkdir(dir, path->dentry, mode);
c1595e42 33307+ lockdep_on();
1facf9fc 33308+ if (!err) {
33309+ struct path tmp = *path;
33310+ int did;
33311+
33312+ vfsub_update_h_iattr(&tmp, &did);
33313+ if (did) {
33314+ tmp.dentry = path->dentry->d_parent;
33315+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33316+ }
33317+ /*ignore*/
33318+ }
33319+
4f0767ce 33320+out:
1facf9fc 33321+ return err;
33322+}
33323+
33324+int vfsub_rmdir(struct inode *dir, struct path *path)
33325+{
33326+ int err;
33327+ struct dentry *d;
33328+
33329+ IMustLock(dir);
33330+
33331+ d = path->dentry;
33332+ path->dentry = d->d_parent;
b752ccd1 33333+ err = security_path_rmdir(path, d);
1facf9fc 33334+ path->dentry = d;
33335+ if (unlikely(err))
33336+ goto out;
33337+
2cbb1c4b 33338+ lockdep_off();
1facf9fc 33339+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 33340+ lockdep_on();
1facf9fc 33341+ if (!err) {
33342+ struct path tmp = {
33343+ .dentry = path->dentry->d_parent,
33344+ .mnt = path->mnt
33345+ };
33346+
33347+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
33348+ }
33349+
4f0767ce 33350+out:
1facf9fc 33351+ return err;
33352+}
33353+
33354+/* ---------------------------------------------------------------------- */
33355+
9dbd164d 33356+/* todo: support mmap_sem? */
1facf9fc 33357+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
33358+ loff_t *ppos)
33359+{
33360+ ssize_t err;
33361+
2cbb1c4b 33362+ lockdep_off();
1facf9fc 33363+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 33364+ lockdep_on();
1facf9fc 33365+ if (err >= 0)
33366+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
33367+ return err;
33368+}
33369+
33370+/* todo: kernel_read()? */
33371+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
33372+ loff_t *ppos)
33373+{
33374+ ssize_t err;
33375+ mm_segment_t oldfs;
b752ccd1
AM
33376+ union {
33377+ void *k;
33378+ char __user *u;
33379+ } buf;
1facf9fc 33380+
b752ccd1 33381+ buf.k = kbuf;
1facf9fc 33382+ oldfs = get_fs();
33383+ set_fs(KERNEL_DS);
b752ccd1 33384+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 33385+ set_fs(oldfs);
33386+ return err;
33387+}
33388+
33389+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
33390+ loff_t *ppos)
33391+{
33392+ ssize_t err;
33393+
2cbb1c4b 33394+ lockdep_off();
1facf9fc 33395+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 33396+ lockdep_on();
1facf9fc 33397+ if (err >= 0)
33398+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
33399+ return err;
33400+}
33401+
33402+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
33403+{
33404+ ssize_t err;
33405+ mm_segment_t oldfs;
b752ccd1
AM
33406+ union {
33407+ void *k;
33408+ const char __user *u;
33409+ } buf;
1facf9fc 33410+
b752ccd1 33411+ buf.k = kbuf;
1facf9fc 33412+ oldfs = get_fs();
33413+ set_fs(KERNEL_DS);
b752ccd1 33414+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 33415+ set_fs(oldfs);
33416+ return err;
33417+}
33418+
4a4d8108
AM
33419+int vfsub_flush(struct file *file, fl_owner_t id)
33420+{
33421+ int err;
33422+
33423+ err = 0;
523b37e3 33424+ if (file->f_op->flush) {
2000de60 33425+ if (!au_test_nfs(file->f_path.dentry->d_sb))
2cbb1c4b
JR
33426+ err = file->f_op->flush(file, id);
33427+ else {
33428+ lockdep_off();
33429+ err = file->f_op->flush(file, id);
33430+ lockdep_on();
33431+ }
4a4d8108
AM
33432+ if (!err)
33433+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
33434+ /*ignore*/
33435+ }
33436+ return err;
33437+}
33438+
392086de 33439+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 33440+{
33441+ int err;
33442+
062440b3 33443+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos);
392086de 33444+
2cbb1c4b 33445+ lockdep_off();
392086de 33446+ err = iterate_dir(file, ctx);
2cbb1c4b 33447+ lockdep_on();
1facf9fc 33448+ if (err >= 0)
33449+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
1c60b727 33450+
1facf9fc 33451+ return err;
33452+}
33453+
33454+long vfsub_splice_to(struct file *in, loff_t *ppos,
33455+ struct pipe_inode_info *pipe, size_t len,
33456+ unsigned int flags)
33457+{
33458+ long err;
33459+
2cbb1c4b 33460+ lockdep_off();
0fc653ad 33461+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 33462+ lockdep_on();
4a4d8108 33463+ file_accessed(in);
1facf9fc 33464+ if (err >= 0)
33465+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
33466+ return err;
33467+}
33468+
33469+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
33470+ loff_t *ppos, size_t len, unsigned int flags)
33471+{
33472+ long err;
33473+
2cbb1c4b 33474+ lockdep_off();
0fc653ad 33475+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 33476+ lockdep_on();
1facf9fc 33477+ if (err >= 0)
33478+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
33479+ return err;
33480+}
33481+
53392da6
AM
33482+int vfsub_fsync(struct file *file, struct path *path, int datasync)
33483+{
33484+ int err;
33485+
33486+ /* file can be NULL */
33487+ lockdep_off();
33488+ err = vfs_fsync(file, datasync);
33489+ lockdep_on();
33490+ if (!err) {
33491+ if (!path) {
33492+ AuDebugOn(!file);
33493+ path = &file->f_path;
33494+ }
33495+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
33496+ }
33497+ return err;
33498+}
33499+
1facf9fc 33500+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
33501+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
33502+ struct file *h_file)
33503+{
33504+ int err;
33505+ struct inode *h_inode;
c06a8ce3 33506+ struct super_block *h_sb;
1facf9fc 33507+
1facf9fc 33508+ if (!h_file) {
c06a8ce3
AM
33509+ err = vfsub_truncate(h_path, length);
33510+ goto out;
1facf9fc 33511+ }
33512+
5527c038 33513+ h_inode = d_inode(h_path->dentry);
c06a8ce3
AM
33514+ h_sb = h_inode->i_sb;
33515+ lockdep_off();
33516+ sb_start_write(h_sb);
33517+ lockdep_on();
1facf9fc 33518+ err = locks_verify_truncate(h_inode, h_file, length);
33519+ if (!err)
953406b4 33520+ err = security_path_truncate(h_path);
2cbb1c4b
JR
33521+ if (!err) {
33522+ lockdep_off();
1facf9fc 33523+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
33524+ lockdep_on();
33525+ }
c06a8ce3
AM
33526+ lockdep_off();
33527+ sb_end_write(h_sb);
33528+ lockdep_on();
1facf9fc 33529+
4f0767ce 33530+out:
1facf9fc 33531+ return err;
33532+}
33533+
33534+/* ---------------------------------------------------------------------- */
33535+
33536+struct au_vfsub_mkdir_args {
33537+ int *errp;
33538+ struct inode *dir;
33539+ struct path *path;
33540+ int mode;
33541+};
33542+
33543+static void au_call_vfsub_mkdir(void *args)
33544+{
33545+ struct au_vfsub_mkdir_args *a = args;
33546+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
33547+}
33548+
33549+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
33550+{
33551+ int err, do_sio, wkq_err;
33552+
33553+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
33554+ if (!do_sio) {
33555+ lockdep_off();
1facf9fc 33556+ err = vfsub_mkdir(dir, path, mode);
c1595e42
JR
33557+ lockdep_on();
33558+ } else {
1facf9fc 33559+ struct au_vfsub_mkdir_args args = {
33560+ .errp = &err,
33561+ .dir = dir,
33562+ .path = path,
33563+ .mode = mode
33564+ };
33565+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
33566+ if (unlikely(wkq_err))
33567+ err = wkq_err;
33568+ }
33569+
33570+ return err;
33571+}
33572+
33573+struct au_vfsub_rmdir_args {
33574+ int *errp;
33575+ struct inode *dir;
33576+ struct path *path;
33577+};
33578+
33579+static void au_call_vfsub_rmdir(void *args)
33580+{
33581+ struct au_vfsub_rmdir_args *a = args;
33582+ *a->errp = vfsub_rmdir(a->dir, a->path);
33583+}
33584+
33585+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
33586+{
33587+ int err, do_sio, wkq_err;
33588+
33589+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
33590+ if (!do_sio) {
33591+ lockdep_off();
1facf9fc 33592+ err = vfsub_rmdir(dir, path);
c1595e42
JR
33593+ lockdep_on();
33594+ } else {
1facf9fc 33595+ struct au_vfsub_rmdir_args args = {
33596+ .errp = &err,
33597+ .dir = dir,
33598+ .path = path
33599+ };
33600+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
33601+ if (unlikely(wkq_err))
33602+ err = wkq_err;
33603+ }
33604+
33605+ return err;
33606+}
33607+
33608+/* ---------------------------------------------------------------------- */
33609+
33610+struct notify_change_args {
33611+ int *errp;
33612+ struct path *path;
33613+ struct iattr *ia;
523b37e3 33614+ struct inode **delegated_inode;
1facf9fc 33615+};
33616+
33617+static void call_notify_change(void *args)
33618+{
33619+ struct notify_change_args *a = args;
33620+ struct inode *h_inode;
33621+
5527c038 33622+ h_inode = d_inode(a->path->dentry);
1facf9fc 33623+ IMustLock(h_inode);
33624+
33625+ *a->errp = -EPERM;
33626+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
c1595e42 33627+ lockdep_off();
523b37e3
AM
33628+ *a->errp = notify_change(a->path->dentry, a->ia,
33629+ a->delegated_inode);
c1595e42 33630+ lockdep_on();
1facf9fc 33631+ if (!*a->errp)
33632+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
33633+ }
33634+ AuTraceErr(*a->errp);
33635+}
33636+
523b37e3
AM
33637+int vfsub_notify_change(struct path *path, struct iattr *ia,
33638+ struct inode **delegated_inode)
1facf9fc 33639+{
33640+ int err;
33641+ struct notify_change_args args = {
523b37e3
AM
33642+ .errp = &err,
33643+ .path = path,
33644+ .ia = ia,
33645+ .delegated_inode = delegated_inode
1facf9fc 33646+ };
33647+
33648+ call_notify_change(&args);
33649+
33650+ return err;
33651+}
33652+
523b37e3
AM
33653+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
33654+ struct inode **delegated_inode)
1facf9fc 33655+{
33656+ int err, wkq_err;
33657+ struct notify_change_args args = {
523b37e3
AM
33658+ .errp = &err,
33659+ .path = path,
33660+ .ia = ia,
33661+ .delegated_inode = delegated_inode
1facf9fc 33662+ };
33663+
33664+ wkq_err = au_wkq_wait(call_notify_change, &args);
33665+ if (unlikely(wkq_err))
33666+ err = wkq_err;
33667+
33668+ return err;
33669+}
33670+
33671+/* ---------------------------------------------------------------------- */
33672+
33673+struct unlink_args {
33674+ int *errp;
33675+ struct inode *dir;
33676+ struct path *path;
523b37e3 33677+ struct inode **delegated_inode;
1facf9fc 33678+};
33679+
33680+static void call_unlink(void *args)
33681+{
33682+ struct unlink_args *a = args;
33683+ struct dentry *d = a->path->dentry;
33684+ struct inode *h_inode;
33685+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
c1595e42 33686+ && au_dcount(d) == 1);
1facf9fc 33687+
33688+ IMustLock(a->dir);
33689+
33690+ a->path->dentry = d->d_parent;
33691+ *a->errp = security_path_unlink(a->path, d);
33692+ a->path->dentry = d;
33693+ if (unlikely(*a->errp))
33694+ return;
33695+
33696+ if (!stop_sillyrename)
33697+ dget(d);
5527c038
JR
33698+ h_inode = NULL;
33699+ if (d_is_positive(d)) {
33700+ h_inode = d_inode(d);
027c5e7a 33701+ ihold(h_inode);
5527c038 33702+ }
1facf9fc 33703+
2cbb1c4b 33704+ lockdep_off();
523b37e3 33705+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 33706+ lockdep_on();
1facf9fc 33707+ if (!*a->errp) {
33708+ struct path tmp = {
33709+ .dentry = d->d_parent,
33710+ .mnt = a->path->mnt
33711+ };
33712+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
33713+ }
33714+
33715+ if (!stop_sillyrename)
33716+ dput(d);
33717+ if (h_inode)
33718+ iput(h_inode);
33719+
33720+ AuTraceErr(*a->errp);
33721+}
33722+
33723+/*
33724+ * @dir: must be locked.
33725+ * @dentry: target dentry.
33726+ */
523b37e3
AM
33727+int vfsub_unlink(struct inode *dir, struct path *path,
33728+ struct inode **delegated_inode, int force)
1facf9fc 33729+{
33730+ int err;
33731+ struct unlink_args args = {
523b37e3
AM
33732+ .errp = &err,
33733+ .dir = dir,
33734+ .path = path,
33735+ .delegated_inode = delegated_inode
1facf9fc 33736+ };
33737+
33738+ if (!force)
33739+ call_unlink(&args);
33740+ else {
33741+ int wkq_err;
33742+
33743+ wkq_err = au_wkq_wait(call_unlink, &args);
33744+ if (unlikely(wkq_err))
33745+ err = wkq_err;
33746+ }
33747+
33748+ return err;
33749+}
7f207e10
AM
33750diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
33751--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
eca801bf
AM
33752+++ linux/fs/aufs/vfsub.h 2019-05-06 09:03:04.820143837 +0200
33753@@ -0,0 +1,354 @@
062440b3 33754+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 33755+/*
ba1aed25 33756+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 33757+ *
33758+ * This program, aufs is free software; you can redistribute it and/or modify
33759+ * it under the terms of the GNU General Public License as published by
33760+ * the Free Software Foundation; either version 2 of the License, or
33761+ * (at your option) any later version.
dece6358
AM
33762+ *
33763+ * This program is distributed in the hope that it will be useful,
33764+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33765+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33766+ * GNU General Public License for more details.
33767+ *
33768+ * You should have received a copy of the GNU General Public License
523b37e3 33769+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33770+ */
33771+
33772+/*
33773+ * sub-routines for VFS
33774+ */
33775+
33776+#ifndef __AUFS_VFSUB_H__
33777+#define __AUFS_VFSUB_H__
33778+
33779+#ifdef __KERNEL__
33780+
33781+#include <linux/fs.h>
b4510431 33782+#include <linux/mount.h>
8cdd5066 33783+#include <linux/posix_acl.h>
c1595e42 33784+#include <linux/xattr.h>
7f207e10 33785+#include "debug.h"
1facf9fc 33786+
7f207e10 33787+/* copied from linux/fs/internal.h */
2cbb1c4b 33788+/* todo: BAD approach!! */
c06a8ce3 33789+extern void __mnt_drop_write(struct vfsmount *);
acd2b654 33790+extern struct file *alloc_empty_file(int, const struct cred *);
7f207e10
AM
33791+
33792+/* ---------------------------------------------------------------------- */
1facf9fc 33793+
33794+/* lock subclass for lower inode */
33795+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
33796+/* reduce? gave up. */
33797+enum {
c1595e42 33798+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
1facf9fc 33799+ AuLsc_I_PARENT, /* lower inode, parent first */
33800+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 33801+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 33802+ AuLsc_I_CHILD,
33803+ AuLsc_I_CHILD2,
33804+ AuLsc_I_End
33805+};
33806+
33807+/* to debug easier, do not make them inlined functions */
33808+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
febd17d6 33809+#define IMustLock(i) AuDebugOn(!inode_is_locked(i))
1facf9fc 33810+
33811+/* ---------------------------------------------------------------------- */
33812+
7f207e10
AM
33813+static inline void vfsub_drop_nlink(struct inode *inode)
33814+{
33815+ AuDebugOn(!inode->i_nlink);
33816+ drop_nlink(inode);
33817+}
33818+
027c5e7a
AM
33819+static inline void vfsub_dead_dir(struct inode *inode)
33820+{
33821+ AuDebugOn(!S_ISDIR(inode->i_mode));
33822+ inode->i_flags |= S_DEAD;
33823+ clear_nlink(inode);
33824+}
33825+
392086de
AM
33826+static inline int vfsub_native_ro(struct inode *inode)
33827+{
8b6a4947 33828+ return sb_rdonly(inode->i_sb)
392086de
AM
33829+ || IS_RDONLY(inode)
33830+ /* || IS_APPEND(inode) */
33831+ || IS_IMMUTABLE(inode);
33832+}
33833+
8cdd5066
JR
33834+#ifdef CONFIG_AUFS_BR_FUSE
33835+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb);
33836+#else
33837+AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb);
33838+#endif
33839+
a2654f78
AM
33840+int vfsub_sync_filesystem(struct super_block *h_sb, int wait);
33841+
7f207e10
AM
33842+/* ---------------------------------------------------------------------- */
33843+
33844+int vfsub_update_h_iattr(struct path *h_path, int *did);
33845+struct file *vfsub_dentry_open(struct path *path, int flags);
33846+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
acd2b654 33847+struct au_branch;
b912730e 33848+struct vfsub_aopen_args {
acd2b654
AM
33849+ struct file *file;
33850+ unsigned int open_flag;
33851+ umode_t create_mode;
33852+ struct au_branch *br;
b912730e 33853+};
b912730e 33854+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
acd2b654 33855+ struct vfsub_aopen_args *args);
1facf9fc 33856+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 33857+
febd17d6
JR
33858+struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
33859+ struct dentry *parent, int len);
1facf9fc 33860+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
33861+ int len);
b4510431
AM
33862+
33863+struct vfsub_lkup_one_args {
33864+ struct dentry **errp;
33865+ struct qstr *name;
33866+ struct dentry *parent;
33867+};
33868+
33869+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
33870+ struct dentry *parent)
33871+{
33872+ return vfsub_lookup_one_len(name->name, parent, name->len);
33873+}
33874+
33875+void vfsub_call_lkup_one(void *args);
33876+
33877+/* ---------------------------------------------------------------------- */
33878+
33879+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
33880+{
33881+ int err;
076b876e 33882+
b4510431
AM
33883+ lockdep_off();
33884+ err = mnt_want_write(mnt);
33885+ lockdep_on();
33886+ return err;
33887+}
33888+
33889+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
33890+{
33891+ lockdep_off();
33892+ mnt_drop_write(mnt);
33893+ lockdep_on();
33894+}
1facf9fc 33895+
7e9cd9fe 33896+#if 0 /* reserved */
c06a8ce3
AM
33897+static inline void vfsub_mnt_drop_write_file(struct file *file)
33898+{
33899+ lockdep_off();
33900+ mnt_drop_write_file(file);
33901+ lockdep_on();
33902+}
7e9cd9fe 33903+#endif
c06a8ce3 33904+
1facf9fc 33905+/* ---------------------------------------------------------------------- */
33906+
33907+struct au_hinode;
33908+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
33909+ struct dentry *d2, struct au_hinode *hdir2);
33910+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
33911+ struct dentry *d2, struct au_hinode *hdir2);
33912+
537831f9
AM
33913+int vfsub_create(struct inode *dir, struct path *path, int mode,
33914+ bool want_excl);
1facf9fc 33915+int vfsub_symlink(struct inode *dir, struct path *path,
33916+ const char *symname);
33917+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
33918+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 33919+ struct path *path, struct inode **delegated_inode);
1facf9fc 33920+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3 33921+ struct inode *hdir, struct path *path,
f2c43d5f 33922+ struct inode **delegated_inode, unsigned int flags);
1facf9fc 33923+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
33924+int vfsub_rmdir(struct inode *dir, struct path *path);
33925+
33926+/* ---------------------------------------------------------------------- */
33927+
33928+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
33929+ loff_t *ppos);
33930+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
33931+ loff_t *ppos);
33932+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
33933+ loff_t *ppos);
33934+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
33935+ loff_t *ppos);
4a4d8108 33936+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
33937+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
33938+
c06a8ce3
AM
33939+static inline loff_t vfsub_f_size_read(struct file *file)
33940+{
33941+ return i_size_read(file_inode(file));
33942+}
33943+
4a4d8108
AM
33944+static inline unsigned int vfsub_file_flags(struct file *file)
33945+{
33946+ unsigned int flags;
33947+
33948+ spin_lock(&file->f_lock);
33949+ flags = file->f_flags;
33950+ spin_unlock(&file->f_lock);
33951+
33952+ return flags;
33953+}
1308ab2a 33954+
f0c0a007
AM
33955+static inline int vfsub_file_execed(struct file *file)
33956+{
33957+ /* todo: direct access f_flags */
33958+ return !!(vfsub_file_flags(file) & __FMODE_EXEC);
33959+}
33960+
7e9cd9fe 33961+#if 0 /* reserved */
1facf9fc 33962+static inline void vfsub_file_accessed(struct file *h_file)
33963+{
33964+ file_accessed(h_file);
33965+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
33966+}
7e9cd9fe 33967+#endif
1facf9fc 33968+
79b8bda9 33969+#if 0 /* reserved */
1facf9fc 33970+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
33971+ struct dentry *h_dentry)
33972+{
33973+ struct path h_path = {
33974+ .dentry = h_dentry,
33975+ .mnt = h_mnt
33976+ };
92d182d2 33977+ touch_atime(&h_path);
1facf9fc 33978+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
33979+}
79b8bda9 33980+#endif
1facf9fc 33981+
cd7a4cd9
AM
33982+static inline int vfsub_update_time(struct inode *h_inode,
33983+ struct timespec64 *ts, int flags)
0c3ec466 33984+{
5afbbe0d 33985+ return update_time(h_inode, ts, flags);
0c3ec466
AM
33986+ /* no vfsub_update_h_iattr() since we don't have struct path */
33987+}
33988+
8cdd5066
JR
33989+#ifdef CONFIG_FS_POSIX_ACL
33990+static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode)
33991+{
33992+ int err;
33993+
33994+ err = posix_acl_chmod(h_inode, h_mode);
33995+ if (err == -EOPNOTSUPP)
33996+ err = 0;
33997+ return err;
33998+}
33999+#else
34000+AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode);
34001+#endif
34002+
4a4d8108
AM
34003+long vfsub_splice_to(struct file *in, loff_t *ppos,
34004+ struct pipe_inode_info *pipe, size_t len,
34005+ unsigned int flags);
34006+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
34007+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
34008+
34009+static inline long vfsub_truncate(struct path *path, loff_t length)
34010+{
34011+ long err;
076b876e 34012+
c06a8ce3
AM
34013+ lockdep_off();
34014+ err = vfs_truncate(path, length);
34015+ lockdep_on();
34016+ return err;
34017+}
34018+
4a4d8108
AM
34019+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
34020+ struct file *h_file);
53392da6 34021+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 34022+
521ced18
JR
34023+/*
34024+ * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such
34025+ * ioctl.
34026+ */
9f237c51
AM
34027+static inline loff_t vfsub_clone_file_range(struct file *src, struct file *dst,
34028+ loff_t len)
521ced18 34029+{
9f237c51 34030+ loff_t err;
521ced18
JR
34031+
34032+ lockdep_off();
9f237c51 34033+ err = vfs_clone_file_range(src, 0, dst, 0, len, /*remap_flags*/0);
521ced18
JR
34034+ lockdep_on();
34035+
34036+ return err;
34037+}
34038+
34039+/* copy_file_range(2) is a systemcall */
34040+static inline ssize_t vfsub_copy_file_range(struct file *src, loff_t src_pos,
34041+ struct file *dst, loff_t dst_pos,
34042+ size_t len, unsigned int flags)
34043+{
34044+ ssize_t ssz;
34045+
34046+ lockdep_off();
34047+ ssz = vfs_copy_file_range(src, src_pos, dst, dst_pos, len, flags);
34048+ lockdep_on();
34049+
34050+ return ssz;
34051+}
34052+
1facf9fc 34053+/* ---------------------------------------------------------------------- */
34054+
34055+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
34056+{
34057+ loff_t err;
34058+
2cbb1c4b 34059+ lockdep_off();
1facf9fc 34060+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 34061+ lockdep_on();
1facf9fc 34062+ return err;
34063+}
34064+
34065+/* ---------------------------------------------------------------------- */
34066+
4a4d8108
AM
34067+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
34068+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
34069+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
34070+ struct inode **delegated_inode);
34071+int vfsub_notify_change(struct path *path, struct iattr *ia,
34072+ struct inode **delegated_inode);
34073+int vfsub_unlink(struct inode *dir, struct path *path,
34074+ struct inode **delegated_inode, int force);
4a4d8108 34075+
521ced18
JR
34076+static inline int vfsub_getattr(const struct path *path, struct kstat *st)
34077+{
34078+ return vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
34079+}
34080+
c1595e42
JR
34081+/* ---------------------------------------------------------------------- */
34082+
34083+static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
34084+ const void *value, size_t size, int flags)
34085+{
34086+ int err;
34087+
34088+ lockdep_off();
34089+ err = vfs_setxattr(dentry, name, value, size, flags);
34090+ lockdep_on();
34091+
34092+ return err;
34093+}
34094+
34095+static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
34096+{
34097+ int err;
34098+
34099+ lockdep_off();
34100+ err = vfs_removexattr(dentry, name);
34101+ lockdep_on();
34102+
34103+ return err;
34104+}
34105+
1facf9fc 34106+#endif /* __KERNEL__ */
34107+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
34108diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
34109--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 34110+++ linux/fs/aufs/wbr_policy.c 2019-03-05 12:13:00.145891204 +0100
cd7a4cd9
AM
34111@@ -0,0 +1,830 @@
34112+// SPDX-License-Identifier: GPL-2.0
1facf9fc 34113+/*
ba1aed25 34114+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 34115+ *
34116+ * This program, aufs is free software; you can redistribute it and/or modify
34117+ * it under the terms of the GNU General Public License as published by
34118+ * the Free Software Foundation; either version 2 of the License, or
34119+ * (at your option) any later version.
dece6358
AM
34120+ *
34121+ * This program is distributed in the hope that it will be useful,
34122+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34123+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34124+ * GNU General Public License for more details.
34125+ *
34126+ * You should have received a copy of the GNU General Public License
523b37e3 34127+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 34128+ */
34129+
34130+/*
34131+ * policies for selecting one among multiple writable branches
34132+ */
34133+
34134+#include <linux/statfs.h>
34135+#include "aufs.h"
34136+
34137+/* subset of cpup_attr() */
34138+static noinline_for_stack
34139+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
34140+{
34141+ int err, sbits;
34142+ struct iattr ia;
34143+ struct inode *h_isrc;
34144+
5527c038 34145+ h_isrc = d_inode(h_src);
1facf9fc 34146+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
34147+ ia.ia_mode = h_isrc->i_mode;
34148+ ia.ia_uid = h_isrc->i_uid;
34149+ ia.ia_gid = h_isrc->i_gid;
34150+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
5527c038 34151+ au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags);
523b37e3
AM
34152+ /* no delegation since it is just created */
34153+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 34154+
34155+ /* is this nfs only? */
34156+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
34157+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
34158+ ia.ia_mode = h_isrc->i_mode;
523b37e3 34159+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 34160+ }
34161+
34162+ return err;
34163+}
34164+
34165+#define AuCpdown_PARENT_OPQ 1
34166+#define AuCpdown_WHED (1 << 1)
34167+#define AuCpdown_MADE_DIR (1 << 2)
34168+#define AuCpdown_DIROPQ (1 << 3)
34169+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
34170+#define au_fset_cpdown(flags, name) \
34171+ do { (flags) |= AuCpdown_##name; } while (0)
34172+#define au_fclr_cpdown(flags, name) \
34173+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 34174+
1facf9fc 34175+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 34176+ unsigned int *flags)
1facf9fc 34177+{
34178+ int err;
34179+ struct dentry *opq_dentry;
34180+
34181+ opq_dentry = au_diropq_create(dentry, bdst);
34182+ err = PTR_ERR(opq_dentry);
34183+ if (IS_ERR(opq_dentry))
34184+ goto out;
34185+ dput(opq_dentry);
c2b27bf2 34186+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 34187+
4f0767ce 34188+out:
1facf9fc 34189+ return err;
34190+}
34191+
34192+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
34193+ struct inode *dir, aufs_bindex_t bdst)
34194+{
34195+ int err;
34196+ struct path h_path;
34197+ struct au_branch *br;
34198+
34199+ br = au_sbr(dentry->d_sb, bdst);
34200+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
34201+ err = PTR_ERR(h_path.dentry);
34202+ if (IS_ERR(h_path.dentry))
34203+ goto out;
34204+
34205+ err = 0;
5527c038 34206+ if (d_is_positive(h_path.dentry)) {
86dc4139 34207+ h_path.mnt = au_br_mnt(br);
1facf9fc 34208+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
34209+ dentry);
34210+ }
34211+ dput(h_path.dentry);
34212+
4f0767ce 34213+out:
1facf9fc 34214+ return err;
34215+}
34216+
34217+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 34218+ struct au_pin *pin,
1facf9fc 34219+ struct dentry *h_parent, void *arg)
34220+{
34221+ int err, rerr;
5afbbe0d 34222+ aufs_bindex_t bopq, btop;
1facf9fc 34223+ struct path h_path;
34224+ struct dentry *parent;
34225+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 34226+ unsigned int *flags = arg;
1facf9fc 34227+
5afbbe0d 34228+ btop = au_dbtop(dentry);
1facf9fc 34229+ /* dentry is di-locked */
34230+ parent = dget_parent(dentry);
5527c038
JR
34231+ dir = d_inode(parent);
34232+ h_dir = d_inode(h_parent);
1facf9fc 34233+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
34234+ IMustLock(h_dir);
34235+
86dc4139 34236+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 34237+ if (unlikely(err < 0))
34238+ goto out;
34239+ h_path.dentry = au_h_dptr(dentry, bdst);
34240+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
cd7a4cd9 34241+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path, 0755);
1facf9fc 34242+ if (unlikely(err))
34243+ goto out_put;
c2b27bf2 34244+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 34245+
1facf9fc 34246+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
34247+ au_fclr_cpdown(*flags, WHED);
34248+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 34249+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
34250+ au_fset_cpdown(*flags, WHED);
34251+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
34252+ au_fset_cpdown(*flags, PARENT_OPQ);
5527c038 34253+ h_inode = d_inode(h_path.dentry);
febd17d6 34254+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
c2b27bf2
AM
34255+ if (au_ftest_cpdown(*flags, WHED)) {
34256+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 34257+ if (unlikely(err)) {
febd17d6 34258+ inode_unlock(h_inode);
1facf9fc 34259+ goto out_dir;
34260+ }
34261+ }
34262+
5afbbe0d 34263+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, btop));
febd17d6 34264+ inode_unlock(h_inode);
1facf9fc 34265+ if (unlikely(err))
34266+ goto out_opq;
34267+
c2b27bf2 34268+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 34269+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
34270+ if (unlikely(err))
34271+ goto out_opq;
34272+ }
34273+
5527c038 34274+ inode = d_inode(dentry);
5afbbe0d
AM
34275+ if (au_ibbot(inode) < bdst)
34276+ au_set_ibbot(inode, bdst);
1facf9fc 34277+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
34278+ au_hi_flags(inode, /*isdir*/1));
076b876e 34279+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
1facf9fc 34280+ goto out; /* success */
34281+
34282+ /* revert */
4f0767ce 34283+out_opq:
c2b27bf2 34284+ if (au_ftest_cpdown(*flags, DIROPQ)) {
febd17d6 34285+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
1facf9fc 34286+ rerr = au_diropq_remove(dentry, bdst);
febd17d6 34287+ inode_unlock(h_inode);
1facf9fc 34288+ if (unlikely(rerr)) {
523b37e3
AM
34289+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
34290+ dentry, bdst, rerr);
1facf9fc 34291+ err = -EIO;
34292+ goto out;
34293+ }
34294+ }
4f0767ce 34295+out_dir:
c2b27bf2 34296+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 34297+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
34298+ if (unlikely(rerr)) {
523b37e3
AM
34299+ AuIOErr("failed removing %pd b%d (%d)\n",
34300+ dentry, bdst, rerr);
1facf9fc 34301+ err = -EIO;
34302+ }
34303+ }
4f0767ce 34304+out_put:
1facf9fc 34305+ au_set_h_dptr(dentry, bdst, NULL);
5afbbe0d
AM
34306+ if (au_dbbot(dentry) == bdst)
34307+ au_update_dbbot(dentry);
4f0767ce 34308+out:
1facf9fc 34309+ dput(parent);
34310+ return err;
34311+}
34312+
34313+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
34314+{
34315+ int err;
c2b27bf2 34316+ unsigned int flags;
1facf9fc 34317+
c2b27bf2
AM
34318+ flags = 0;
34319+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 34320+
34321+ return err;
34322+}
34323+
34324+/* ---------------------------------------------------------------------- */
34325+
34326+/* policies for create */
34327+
c2b27bf2 34328+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
34329+{
34330+ int err, i, j, ndentry;
34331+ aufs_bindex_t bopq;
34332+ struct au_dcsub_pages dpages;
34333+ struct au_dpage *dpage;
34334+ struct dentry **dentries, *parent, *d;
34335+
34336+ err = au_dpages_init(&dpages, GFP_NOFS);
34337+ if (unlikely(err))
34338+ goto out;
34339+ parent = dget_parent(dentry);
027c5e7a 34340+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
34341+ if (unlikely(err))
34342+ goto out_free;
34343+
34344+ err = bindex;
34345+ for (i = 0; i < dpages.ndpage; i++) {
34346+ dpage = dpages.dpages + i;
34347+ dentries = dpage->dentries;
34348+ ndentry = dpage->ndentry;
34349+ for (j = 0; j < ndentry; j++) {
34350+ d = dentries[j];
34351+ di_read_lock_parent2(d, !AuLock_IR);
34352+ bopq = au_dbdiropq(d);
34353+ di_read_unlock(d, !AuLock_IR);
34354+ if (bopq >= 0 && bopq < err)
34355+ err = bopq;
34356+ }
34357+ }
34358+
34359+out_free:
34360+ dput(parent);
34361+ au_dpages_free(&dpages);
34362+out:
34363+ return err;
34364+}
34365+
1facf9fc 34366+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
34367+{
34368+ for (; bindex >= 0; bindex--)
34369+ if (!au_br_rdonly(au_sbr(sb, bindex)))
34370+ return bindex;
34371+ return -EROFS;
34372+}
34373+
34374+/* top down parent */
392086de
AM
34375+static int au_wbr_create_tdp(struct dentry *dentry,
34376+ unsigned int flags __maybe_unused)
1facf9fc 34377+{
34378+ int err;
5afbbe0d 34379+ aufs_bindex_t btop, bindex;
1facf9fc 34380+ struct super_block *sb;
34381+ struct dentry *parent, *h_parent;
34382+
34383+ sb = dentry->d_sb;
5afbbe0d
AM
34384+ btop = au_dbtop(dentry);
34385+ err = btop;
34386+ if (!au_br_rdonly(au_sbr(sb, btop)))
1facf9fc 34387+ goto out;
34388+
34389+ err = -EROFS;
34390+ parent = dget_parent(dentry);
5afbbe0d 34391+ for (bindex = au_dbtop(parent); bindex < btop; bindex++) {
1facf9fc 34392+ h_parent = au_h_dptr(parent, bindex);
5527c038 34393+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 34394+ continue;
34395+
34396+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
34397+ err = bindex;
34398+ break;
34399+ }
34400+ }
34401+ dput(parent);
34402+
34403+ /* bottom up here */
4a4d8108 34404+ if (unlikely(err < 0)) {
5afbbe0d 34405+ err = au_wbr_bu(sb, btop - 1);
4a4d8108
AM
34406+ if (err >= 0)
34407+ err = au_wbr_nonopq(dentry, err);
34408+ }
1facf9fc 34409+
4f0767ce 34410+out:
1facf9fc 34411+ AuDbg("b%d\n", err);
34412+ return err;
34413+}
34414+
34415+/* ---------------------------------------------------------------------- */
34416+
34417+/* an exception for the policy other than tdp */
34418+static int au_wbr_create_exp(struct dentry *dentry)
34419+{
34420+ int err;
34421+ aufs_bindex_t bwh, bdiropq;
34422+ struct dentry *parent;
34423+
34424+ err = -1;
34425+ bwh = au_dbwh(dentry);
34426+ parent = dget_parent(dentry);
34427+ bdiropq = au_dbdiropq(parent);
34428+ if (bwh >= 0) {
34429+ if (bdiropq >= 0)
34430+ err = min(bdiropq, bwh);
34431+ else
34432+ err = bwh;
34433+ AuDbg("%d\n", err);
34434+ } else if (bdiropq >= 0) {
34435+ err = bdiropq;
34436+ AuDbg("%d\n", err);
34437+ }
34438+ dput(parent);
34439+
4a4d8108
AM
34440+ if (err >= 0)
34441+ err = au_wbr_nonopq(dentry, err);
34442+
1facf9fc 34443+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
34444+ err = -1;
34445+
34446+ AuDbg("%d\n", err);
34447+ return err;
34448+}
34449+
34450+/* ---------------------------------------------------------------------- */
34451+
34452+/* round robin */
34453+static int au_wbr_create_init_rr(struct super_block *sb)
34454+{
34455+ int err;
34456+
5afbbe0d 34457+ err = au_wbr_bu(sb, au_sbbot(sb));
1facf9fc 34458+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 34459+ /* smp_mb(); */
1facf9fc 34460+
34461+ AuDbg("b%d\n", err);
34462+ return err;
34463+}
34464+
392086de 34465+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 34466+{
34467+ int err, nbr;
34468+ unsigned int u;
5afbbe0d 34469+ aufs_bindex_t bindex, bbot;
1facf9fc 34470+ struct super_block *sb;
34471+ atomic_t *next;
34472+
34473+ err = au_wbr_create_exp(dentry);
34474+ if (err >= 0)
34475+ goto out;
34476+
34477+ sb = dentry->d_sb;
34478+ next = &au_sbi(sb)->si_wbr_rr_next;
5afbbe0d
AM
34479+ bbot = au_sbbot(sb);
34480+ nbr = bbot + 1;
34481+ for (bindex = 0; bindex <= bbot; bindex++) {
392086de 34482+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 34483+ err = atomic_dec_return(next) + 1;
34484+ /* modulo for 0 is meaningless */
34485+ if (unlikely(!err))
34486+ err = atomic_dec_return(next) + 1;
34487+ } else
34488+ err = atomic_read(next);
34489+ AuDbg("%d\n", err);
34490+ u = err;
34491+ err = u % nbr;
34492+ AuDbg("%d\n", err);
34493+ if (!au_br_rdonly(au_sbr(sb, err)))
34494+ break;
34495+ err = -EROFS;
34496+ }
34497+
4a4d8108
AM
34498+ if (err >= 0)
34499+ err = au_wbr_nonopq(dentry, err);
34500+
4f0767ce 34501+out:
1facf9fc 34502+ AuDbg("%d\n", err);
34503+ return err;
34504+}
34505+
34506+/* ---------------------------------------------------------------------- */
34507+
34508+/* most free space */
392086de 34509+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 34510+{
34511+ struct super_block *sb;
34512+ struct au_branch *br;
34513+ struct au_wbr_mfs *mfs;
392086de 34514+ struct dentry *h_parent;
5afbbe0d 34515+ aufs_bindex_t bindex, bbot;
1facf9fc 34516+ int err;
34517+ unsigned long long b, bavail;
7f207e10 34518+ struct path h_path;
1facf9fc 34519+ /* reduce the stack usage */
34520+ struct kstatfs *st;
34521+
34522+ st = kmalloc(sizeof(*st), GFP_NOFS);
34523+ if (unlikely(!st)) {
34524+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
34525+ return;
34526+ }
34527+
34528+ bavail = 0;
34529+ sb = dentry->d_sb;
34530+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 34531+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 34532+ mfs->mfs_bindex = -EROFS;
34533+ mfs->mfsrr_bytes = 0;
392086de
AM
34534+ if (!parent) {
34535+ bindex = 0;
5afbbe0d 34536+ bbot = au_sbbot(sb);
392086de 34537+ } else {
5afbbe0d
AM
34538+ bindex = au_dbtop(parent);
34539+ bbot = au_dbtaildir(parent);
392086de
AM
34540+ }
34541+
5afbbe0d 34542+ for (; bindex <= bbot; bindex++) {
392086de
AM
34543+ if (parent) {
34544+ h_parent = au_h_dptr(parent, bindex);
5527c038 34545+ if (!h_parent || d_is_negative(h_parent))
392086de
AM
34546+ continue;
34547+ }
1facf9fc 34548+ br = au_sbr(sb, bindex);
34549+ if (au_br_rdonly(br))
34550+ continue;
34551+
34552+ /* sb->s_root for NFS is unreliable */
86dc4139 34553+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
34554+ h_path.dentry = h_path.mnt->mnt_root;
34555+ err = vfs_statfs(&h_path, st);
1facf9fc 34556+ if (unlikely(err)) {
34557+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
34558+ continue;
34559+ }
34560+
34561+ /* when the available size is equal, select the lower one */
34562+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
34563+ || sizeof(b) < sizeof(st->f_bsize));
34564+ b = st->f_bavail * st->f_bsize;
34565+ br->br_wbr->wbr_bytes = b;
34566+ if (b >= bavail) {
34567+ bavail = b;
34568+ mfs->mfs_bindex = bindex;
34569+ mfs->mfs_jiffy = jiffies;
34570+ }
34571+ }
34572+
34573+ mfs->mfsrr_bytes = bavail;
34574+ AuDbg("b%d\n", mfs->mfs_bindex);
9f237c51 34575+ au_kfree_rcu(st);
1facf9fc 34576+}
34577+
392086de 34578+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 34579+{
34580+ int err;
392086de 34581+ struct dentry *parent;
1facf9fc 34582+ struct super_block *sb;
34583+ struct au_wbr_mfs *mfs;
34584+
34585+ err = au_wbr_create_exp(dentry);
34586+ if (err >= 0)
34587+ goto out;
34588+
34589+ sb = dentry->d_sb;
392086de
AM
34590+ parent = NULL;
34591+ if (au_ftest_wbr(flags, PARENT))
34592+ parent = dget_parent(dentry);
1facf9fc 34593+ mfs = &au_sbi(sb)->si_wbr_mfs;
34594+ mutex_lock(&mfs->mfs_lock);
34595+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
34596+ || mfs->mfs_bindex < 0
34597+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 34598+ au_mfs(dentry, parent);
1facf9fc 34599+ mutex_unlock(&mfs->mfs_lock);
34600+ err = mfs->mfs_bindex;
392086de 34601+ dput(parent);
1facf9fc 34602+
4a4d8108
AM
34603+ if (err >= 0)
34604+ err = au_wbr_nonopq(dentry, err);
34605+
4f0767ce 34606+out:
1facf9fc 34607+ AuDbg("b%d\n", err);
34608+ return err;
34609+}
34610+
34611+static int au_wbr_create_init_mfs(struct super_block *sb)
34612+{
34613+ struct au_wbr_mfs *mfs;
34614+
34615+ mfs = &au_sbi(sb)->si_wbr_mfs;
34616+ mutex_init(&mfs->mfs_lock);
34617+ mfs->mfs_jiffy = 0;
34618+ mfs->mfs_bindex = -EROFS;
34619+
34620+ return 0;
34621+}
34622+
34623+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
34624+{
34625+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
34626+ return 0;
34627+}
34628+
34629+/* ---------------------------------------------------------------------- */
34630+
f2c43d5f
AM
34631+/* top down regardless parent, and then mfs */
34632+static int au_wbr_create_tdmfs(struct dentry *dentry,
34633+ unsigned int flags __maybe_unused)
34634+{
34635+ int err;
34636+ aufs_bindex_t bwh, btail, bindex, bfound, bmfs;
34637+ unsigned long long watermark;
34638+ struct super_block *sb;
34639+ struct au_wbr_mfs *mfs;
34640+ struct au_branch *br;
34641+ struct dentry *parent;
34642+
34643+ sb = dentry->d_sb;
34644+ mfs = &au_sbi(sb)->si_wbr_mfs;
34645+ mutex_lock(&mfs->mfs_lock);
34646+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
34647+ || mfs->mfs_bindex < 0)
34648+ au_mfs(dentry, /*parent*/NULL);
34649+ watermark = mfs->mfsrr_watermark;
34650+ bmfs = mfs->mfs_bindex;
34651+ mutex_unlock(&mfs->mfs_lock);
34652+
34653+ /* another style of au_wbr_create_exp() */
34654+ bwh = au_dbwh(dentry);
34655+ parent = dget_parent(dentry);
34656+ btail = au_dbtaildir(parent);
34657+ if (bwh >= 0 && bwh < btail)
34658+ btail = bwh;
34659+
34660+ err = au_wbr_nonopq(dentry, btail);
34661+ if (unlikely(err < 0))
34662+ goto out;
34663+ btail = err;
34664+ bfound = -1;
34665+ for (bindex = 0; bindex <= btail; bindex++) {
34666+ br = au_sbr(sb, bindex);
34667+ if (au_br_rdonly(br))
34668+ continue;
34669+ if (br->br_wbr->wbr_bytes > watermark) {
34670+ bfound = bindex;
34671+ break;
34672+ }
34673+ }
34674+ err = bfound;
34675+ if (err < 0)
34676+ err = bmfs;
34677+
34678+out:
34679+ dput(parent);
34680+ AuDbg("b%d\n", err);
34681+ return err;
34682+}
34683+
34684+/* ---------------------------------------------------------------------- */
34685+
1facf9fc 34686+/* most free space and then round robin */
392086de 34687+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 34688+{
34689+ int err;
34690+ struct au_wbr_mfs *mfs;
34691+
392086de 34692+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 34693+ if (err >= 0) {
34694+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 34695+ mutex_lock(&mfs->mfs_lock);
1facf9fc 34696+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 34697+ err = au_wbr_create_rr(dentry, flags);
dece6358 34698+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 34699+ }
34700+
34701+ AuDbg("b%d\n", err);
34702+ return err;
34703+}
34704+
34705+static int au_wbr_create_init_mfsrr(struct super_block *sb)
34706+{
34707+ int err;
34708+
34709+ au_wbr_create_init_mfs(sb); /* ignore */
34710+ err = au_wbr_create_init_rr(sb);
34711+
34712+ return err;
34713+}
34714+
34715+/* ---------------------------------------------------------------------- */
34716+
34717+/* top down parent and most free space */
392086de 34718+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 34719+{
34720+ int err, e2;
34721+ unsigned long long b;
5afbbe0d 34722+ aufs_bindex_t bindex, btop, bbot;
1facf9fc 34723+ struct super_block *sb;
34724+ struct dentry *parent, *h_parent;
34725+ struct au_branch *br;
34726+
392086de 34727+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 34728+ if (unlikely(err < 0))
34729+ goto out;
34730+ parent = dget_parent(dentry);
5afbbe0d
AM
34731+ btop = au_dbtop(parent);
34732+ bbot = au_dbtaildir(parent);
34733+ if (btop == bbot)
1facf9fc 34734+ goto out_parent; /* success */
34735+
392086de 34736+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 34737+ if (e2 < 0)
34738+ goto out_parent; /* success */
34739+
34740+ /* when the available size is equal, select upper one */
34741+ sb = dentry->d_sb;
34742+ br = au_sbr(sb, err);
34743+ b = br->br_wbr->wbr_bytes;
34744+ AuDbg("b%d, %llu\n", err, b);
34745+
5afbbe0d 34746+ for (bindex = btop; bindex <= bbot; bindex++) {
1facf9fc 34747+ h_parent = au_h_dptr(parent, bindex);
5527c038 34748+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 34749+ continue;
34750+
34751+ br = au_sbr(sb, bindex);
34752+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
34753+ b = br->br_wbr->wbr_bytes;
34754+ err = bindex;
34755+ AuDbg("b%d, %llu\n", err, b);
34756+ }
34757+ }
34758+
4a4d8108
AM
34759+ if (err >= 0)
34760+ err = au_wbr_nonopq(dentry, err);
34761+
4f0767ce 34762+out_parent:
1facf9fc 34763+ dput(parent);
4f0767ce 34764+out:
1facf9fc 34765+ AuDbg("b%d\n", err);
34766+ return err;
34767+}
34768+
34769+/* ---------------------------------------------------------------------- */
34770+
392086de
AM
34771+/*
34772+ * - top down parent
34773+ * - most free space with parent
34774+ * - most free space round-robin regardless parent
34775+ */
34776+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
34777+{
34778+ int err;
34779+ unsigned long long watermark;
34780+ struct super_block *sb;
34781+ struct au_branch *br;
34782+ struct au_wbr_mfs *mfs;
34783+
34784+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
34785+ if (unlikely(err < 0))
34786+ goto out;
34787+
34788+ sb = dentry->d_sb;
34789+ br = au_sbr(sb, err);
34790+ mfs = &au_sbi(sb)->si_wbr_mfs;
34791+ mutex_lock(&mfs->mfs_lock);
34792+ watermark = mfs->mfsrr_watermark;
34793+ mutex_unlock(&mfs->mfs_lock);
34794+ if (br->br_wbr->wbr_bytes < watermark)
34795+ /* regardless the parent dir */
34796+ err = au_wbr_create_mfsrr(dentry, flags);
34797+
34798+out:
34799+ AuDbg("b%d\n", err);
34800+ return err;
34801+}
34802+
34803+/* ---------------------------------------------------------------------- */
34804+
1facf9fc 34805+/* policies for copyup */
34806+
34807+/* top down parent */
34808+static int au_wbr_copyup_tdp(struct dentry *dentry)
34809+{
392086de 34810+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 34811+}
34812+
34813+/* bottom up parent */
34814+static int au_wbr_copyup_bup(struct dentry *dentry)
34815+{
34816+ int err;
5afbbe0d 34817+ aufs_bindex_t bindex, btop;
1facf9fc 34818+ struct dentry *parent, *h_parent;
34819+ struct super_block *sb;
34820+
34821+ err = -EROFS;
34822+ sb = dentry->d_sb;
34823+ parent = dget_parent(dentry);
5afbbe0d
AM
34824+ btop = au_dbtop(parent);
34825+ for (bindex = au_dbtop(dentry); bindex >= btop; bindex--) {
1facf9fc 34826+ h_parent = au_h_dptr(parent, bindex);
5527c038 34827+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 34828+ continue;
34829+
34830+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
34831+ err = bindex;
34832+ break;
34833+ }
34834+ }
34835+ dput(parent);
34836+
34837+ /* bottom up here */
34838+ if (unlikely(err < 0))
5afbbe0d 34839+ err = au_wbr_bu(sb, btop - 1);
1facf9fc 34840+
34841+ AuDbg("b%d\n", err);
34842+ return err;
34843+}
34844+
34845+/* bottom up */
5afbbe0d 34846+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop)
1facf9fc 34847+{
34848+ int err;
34849+
5afbbe0d 34850+ err = au_wbr_bu(dentry->d_sb, btop);
4a4d8108 34851+ AuDbg("b%d\n", err);
5afbbe0d 34852+ if (err > btop)
4a4d8108 34853+ err = au_wbr_nonopq(dentry, err);
1facf9fc 34854+
34855+ AuDbg("b%d\n", err);
34856+ return err;
34857+}
34858+
076b876e
AM
34859+static int au_wbr_copyup_bu(struct dentry *dentry)
34860+{
34861+ int err;
5afbbe0d 34862+ aufs_bindex_t btop;
076b876e 34863+
5afbbe0d
AM
34864+ btop = au_dbtop(dentry);
34865+ err = au_wbr_do_copyup_bu(dentry, btop);
076b876e
AM
34866+ return err;
34867+}
34868+
1facf9fc 34869+/* ---------------------------------------------------------------------- */
34870+
34871+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
34872+ [AuWbrCopyup_TDP] = {
34873+ .copyup = au_wbr_copyup_tdp
34874+ },
34875+ [AuWbrCopyup_BUP] = {
34876+ .copyup = au_wbr_copyup_bup
34877+ },
34878+ [AuWbrCopyup_BU] = {
34879+ .copyup = au_wbr_copyup_bu
34880+ }
34881+};
34882+
34883+struct au_wbr_create_operations au_wbr_create_ops[] = {
34884+ [AuWbrCreate_TDP] = {
34885+ .create = au_wbr_create_tdp
34886+ },
34887+ [AuWbrCreate_RR] = {
34888+ .create = au_wbr_create_rr,
34889+ .init = au_wbr_create_init_rr
34890+ },
34891+ [AuWbrCreate_MFS] = {
34892+ .create = au_wbr_create_mfs,
34893+ .init = au_wbr_create_init_mfs,
34894+ .fin = au_wbr_create_fin_mfs
34895+ },
34896+ [AuWbrCreate_MFSV] = {
34897+ .create = au_wbr_create_mfs,
34898+ .init = au_wbr_create_init_mfs,
34899+ .fin = au_wbr_create_fin_mfs
34900+ },
34901+ [AuWbrCreate_MFSRR] = {
34902+ .create = au_wbr_create_mfsrr,
34903+ .init = au_wbr_create_init_mfsrr,
34904+ .fin = au_wbr_create_fin_mfs
34905+ },
34906+ [AuWbrCreate_MFSRRV] = {
34907+ .create = au_wbr_create_mfsrr,
34908+ .init = au_wbr_create_init_mfsrr,
34909+ .fin = au_wbr_create_fin_mfs
34910+ },
f2c43d5f
AM
34911+ [AuWbrCreate_TDMFS] = {
34912+ .create = au_wbr_create_tdmfs,
34913+ .init = au_wbr_create_init_mfs,
34914+ .fin = au_wbr_create_fin_mfs
34915+ },
34916+ [AuWbrCreate_TDMFSV] = {
34917+ .create = au_wbr_create_tdmfs,
34918+ .init = au_wbr_create_init_mfs,
34919+ .fin = au_wbr_create_fin_mfs
34920+ },
1facf9fc 34921+ [AuWbrCreate_PMFS] = {
34922+ .create = au_wbr_create_pmfs,
34923+ .init = au_wbr_create_init_mfs,
34924+ .fin = au_wbr_create_fin_mfs
34925+ },
34926+ [AuWbrCreate_PMFSV] = {
34927+ .create = au_wbr_create_pmfs,
34928+ .init = au_wbr_create_init_mfs,
34929+ .fin = au_wbr_create_fin_mfs
392086de
AM
34930+ },
34931+ [AuWbrCreate_PMFSRR] = {
34932+ .create = au_wbr_create_pmfsrr,
34933+ .init = au_wbr_create_init_mfsrr,
34934+ .fin = au_wbr_create_fin_mfs
34935+ },
34936+ [AuWbrCreate_PMFSRRV] = {
34937+ .create = au_wbr_create_pmfsrr,
34938+ .init = au_wbr_create_init_mfsrr,
34939+ .fin = au_wbr_create_fin_mfs
1facf9fc 34940+ }
34941+};
7f207e10
AM
34942diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
34943--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 34944+++ linux/fs/aufs/whout.c 2019-03-05 12:13:00.145891204 +0100
062440b3 34945@@ -0,0 +1,1062 @@
cd7a4cd9 34946+// SPDX-License-Identifier: GPL-2.0
1facf9fc 34947+/*
ba1aed25 34948+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 34949+ *
34950+ * This program, aufs is free software; you can redistribute it and/or modify
34951+ * it under the terms of the GNU General Public License as published by
34952+ * the Free Software Foundation; either version 2 of the License, or
34953+ * (at your option) any later version.
dece6358
AM
34954+ *
34955+ * This program is distributed in the hope that it will be useful,
34956+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34957+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34958+ * GNU General Public License for more details.
34959+ *
34960+ * You should have received a copy of the GNU General Public License
523b37e3 34961+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 34962+ */
34963+
34964+/*
34965+ * whiteout for logical deletion and opaque directory
34966+ */
34967+
1facf9fc 34968+#include "aufs.h"
34969+
cd7a4cd9 34970+#define WH_MASK 0444
1facf9fc 34971+
34972+/*
34973+ * If a directory contains this file, then it is opaque. We start with the
34974+ * .wh. flag so that it is blocked by lookup.
34975+ */
0c3ec466
AM
34976+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
34977+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 34978+
34979+/*
34980+ * generate whiteout name, which is NOT terminated by NULL.
34981+ * @name: original d_name.name
34982+ * @len: original d_name.len
34983+ * @wh: whiteout qstr
34984+ * returns zero when succeeds, otherwise error.
34985+ * succeeded value as wh->name should be freed by kfree().
34986+ */
34987+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
34988+{
34989+ char *p;
34990+
34991+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
34992+ return -ENAMETOOLONG;
34993+
34994+ wh->len = name->len + AUFS_WH_PFX_LEN;
34995+ p = kmalloc(wh->len, GFP_NOFS);
34996+ wh->name = p;
34997+ if (p) {
34998+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
34999+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
35000+ /* smp_mb(); */
35001+ return 0;
35002+ }
35003+ return -ENOMEM;
35004+}
35005+
35006+/* ---------------------------------------------------------------------- */
35007+
35008+/*
35009+ * test if the @wh_name exists under @h_parent.
35010+ * @try_sio specifies the necessary of super-io.
35011+ */
076b876e 35012+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
1facf9fc 35013+{
35014+ int err;
35015+ struct dentry *wh_dentry;
1facf9fc 35016+
1facf9fc 35017+ if (!try_sio)
b4510431 35018+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 35019+ else
076b876e 35020+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
1facf9fc 35021+ err = PTR_ERR(wh_dentry);
2000de60
JR
35022+ if (IS_ERR(wh_dentry)) {
35023+ if (err == -ENAMETOOLONG)
35024+ err = 0;
1facf9fc 35025+ goto out;
2000de60 35026+ }
1facf9fc 35027+
35028+ err = 0;
5527c038 35029+ if (d_is_negative(wh_dentry))
1facf9fc 35030+ goto out_wh; /* success */
35031+
35032+ err = 1;
7e9cd9fe 35033+ if (d_is_reg(wh_dentry))
1facf9fc 35034+ goto out_wh; /* success */
35035+
35036+ err = -EIO;
523b37e3 35037+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
5527c038 35038+ wh_dentry, d_inode(wh_dentry)->i_mode);
1facf9fc 35039+
4f0767ce 35040+out_wh:
1facf9fc 35041+ dput(wh_dentry);
4f0767ce 35042+out:
1facf9fc 35043+ return err;
35044+}
35045+
35046+/*
35047+ * test if the @h_dentry sets opaque or not.
35048+ */
076b876e 35049+int au_diropq_test(struct dentry *h_dentry)
1facf9fc 35050+{
35051+ int err;
35052+ struct inode *h_dir;
35053+
5527c038 35054+ h_dir = d_inode(h_dentry);
076b876e 35055+ err = au_wh_test(h_dentry, &diropq_name,
1facf9fc 35056+ au_test_h_perm_sio(h_dir, MAY_EXEC));
35057+ return err;
35058+}
35059+
35060+/*
35061+ * returns a negative dentry whose name is unique and temporary.
35062+ */
35063+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
35064+ struct qstr *prefix)
35065+{
1facf9fc 35066+ struct dentry *dentry;
35067+ int i;
027c5e7a 35068+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 35069+ *name, *p;
027c5e7a 35070+ /* strict atomic_t is unnecessary here */
1facf9fc 35071+ static unsigned short cnt;
35072+ struct qstr qs;
35073+
4a4d8108
AM
35074+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
35075+
1facf9fc 35076+ name = defname;
027c5e7a
AM
35077+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
35078+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 35079+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 35080+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 35081+ goto out;
35082+ dentry = ERR_PTR(-ENOMEM);
35083+ name = kmalloc(qs.len + 1, GFP_NOFS);
35084+ if (unlikely(!name))
35085+ goto out;
35086+ }
35087+
35088+ /* doubly whiteout-ed */
35089+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
35090+ p = name + AUFS_WH_PFX_LEN * 2;
35091+ memcpy(p, prefix->name, prefix->len);
35092+ p += prefix->len;
35093+ *p++ = '.';
4a4d8108 35094+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 35095+
35096+ qs.name = name;
35097+ for (i = 0; i < 3; i++) {
b752ccd1 35098+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
076b876e 35099+ dentry = au_sio_lkup_one(&qs, h_parent);
5527c038 35100+ if (IS_ERR(dentry) || d_is_negative(dentry))
1facf9fc 35101+ goto out_name;
35102+ dput(dentry);
35103+ }
0c3ec466 35104+ /* pr_warn("could not get random name\n"); */
1facf9fc 35105+ dentry = ERR_PTR(-EEXIST);
35106+ AuDbg("%.*s\n", AuLNPair(&qs));
35107+ BUG();
35108+
4f0767ce 35109+out_name:
1facf9fc 35110+ if (name != defname)
9f237c51 35111+ au_kfree_try_rcu(name);
4f0767ce 35112+out:
4a4d8108 35113+ AuTraceErrPtr(dentry);
1facf9fc 35114+ return dentry;
1facf9fc 35115+}
35116+
35117+/*
35118+ * rename the @h_dentry on @br to the whiteouted temporary name.
35119+ */
35120+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
35121+{
35122+ int err;
35123+ struct path h_path = {
86dc4139 35124+ .mnt = au_br_mnt(br)
1facf9fc 35125+ };
523b37e3 35126+ struct inode *h_dir, *delegated;
1facf9fc 35127+ struct dentry *h_parent;
35128+
35129+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5527c038 35130+ h_dir = d_inode(h_parent);
1facf9fc 35131+ IMustLock(h_dir);
35132+
35133+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
35134+ err = PTR_ERR(h_path.dentry);
35135+ if (IS_ERR(h_path.dentry))
35136+ goto out;
35137+
35138+ /* under the same dir, no need to lock_rename() */
523b37e3 35139+ delegated = NULL;
f2c43d5f
AM
35140+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated,
35141+ /*flags*/0);
1facf9fc 35142+ AuTraceErr(err);
523b37e3
AM
35143+ if (unlikely(err == -EWOULDBLOCK)) {
35144+ pr_warn("cannot retry for NFSv4 delegation"
35145+ " for an internal rename\n");
35146+ iput(delegated);
35147+ }
1facf9fc 35148+ dput(h_path.dentry);
35149+
4f0767ce 35150+out:
4a4d8108 35151+ AuTraceErr(err);
1facf9fc 35152+ return err;
35153+}
35154+
35155+/* ---------------------------------------------------------------------- */
35156+/*
35157+ * functions for removing a whiteout
35158+ */
35159+
35160+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
35161+{
523b37e3
AM
35162+ int err, force;
35163+ struct inode *delegated;
1facf9fc 35164+
35165+ /*
35166+ * forces superio when the dir has a sticky bit.
35167+ * this may be a violation of unix fs semantics.
35168+ */
35169+ force = (h_dir->i_mode & S_ISVTX)
5527c038 35170+ && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid);
523b37e3
AM
35171+ delegated = NULL;
35172+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
35173+ if (unlikely(err == -EWOULDBLOCK)) {
35174+ pr_warn("cannot retry for NFSv4 delegation"
35175+ " for an internal unlink\n");
35176+ iput(delegated);
35177+ }
35178+ return err;
1facf9fc 35179+}
35180+
35181+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
35182+ struct dentry *dentry)
35183+{
35184+ int err;
35185+
35186+ err = do_unlink_wh(h_dir, h_path);
35187+ if (!err && dentry)
35188+ au_set_dbwh(dentry, -1);
35189+
35190+ return err;
35191+}
35192+
35193+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
35194+ struct au_branch *br)
35195+{
35196+ int err;
35197+ struct path h_path = {
86dc4139 35198+ .mnt = au_br_mnt(br)
1facf9fc 35199+ };
35200+
35201+ err = 0;
b4510431 35202+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 35203+ if (IS_ERR(h_path.dentry))
35204+ err = PTR_ERR(h_path.dentry);
35205+ else {
5527c038
JR
35206+ if (d_is_reg(h_path.dentry))
35207+ err = do_unlink_wh(d_inode(h_parent), &h_path);
1facf9fc 35208+ dput(h_path.dentry);
35209+ }
35210+
35211+ return err;
35212+}
35213+
35214+/* ---------------------------------------------------------------------- */
35215+/*
35216+ * initialize/clean whiteout for a branch
35217+ */
35218+
35219+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
35220+ const int isdir)
35221+{
35222+ int err;
523b37e3 35223+ struct inode *delegated;
1facf9fc 35224+
5527c038 35225+ if (d_is_negative(whpath->dentry))
1facf9fc 35226+ return;
35227+
86dc4139
AM
35228+ if (isdir)
35229+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
35230+ else {
35231+ delegated = NULL;
35232+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
35233+ if (unlikely(err == -EWOULDBLOCK)) {
35234+ pr_warn("cannot retry for NFSv4 delegation"
35235+ " for an internal unlink\n");
35236+ iput(delegated);
35237+ }
35238+ }
1facf9fc 35239+ if (unlikely(err))
523b37e3
AM
35240+ pr_warn("failed removing %pd (%d), ignored.\n",
35241+ whpath->dentry, err);
1facf9fc 35242+}
35243+
35244+static int test_linkable(struct dentry *h_root)
35245+{
5527c038 35246+ struct inode *h_dir = d_inode(h_root);
1facf9fc 35247+
35248+ if (h_dir->i_op->link)
35249+ return 0;
35250+
523b37e3
AM
35251+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
35252+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 35253+ return -ENOSYS;
35254+}
35255+
35256+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
35257+static int au_whdir(struct inode *h_dir, struct path *path)
35258+{
35259+ int err;
35260+
35261+ err = -EEXIST;
5527c038 35262+ if (d_is_negative(path->dentry)) {
cd7a4cd9 35263+ int mode = 0700;
1facf9fc 35264+
35265+ if (au_test_nfs(path->dentry->d_sb))
cd7a4cd9 35266+ mode |= 0111;
86dc4139 35267+ err = vfsub_mkdir(h_dir, path, mode);
2000de60 35268+ } else if (d_is_dir(path->dentry))
1facf9fc 35269+ err = 0;
35270+ else
523b37e3 35271+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 35272+
35273+ return err;
35274+}
35275+
35276+struct au_wh_base {
35277+ const struct qstr *name;
35278+ struct dentry *dentry;
35279+};
35280+
35281+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
35282+ struct path *h_path)
35283+{
35284+ h_path->dentry = base[AuBrWh_BASE].dentry;
35285+ au_wh_clean(h_dir, h_path, /*isdir*/0);
35286+ h_path->dentry = base[AuBrWh_PLINK].dentry;
35287+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35288+ h_path->dentry = base[AuBrWh_ORPH].dentry;
35289+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35290+}
35291+
35292+/*
35293+ * returns tri-state,
c1595e42 35294+ * minus: error, caller should print the message
acd2b654 35295+ * zero: success
c1595e42 35296+ * plus: error, caller should NOT print the message
1facf9fc 35297+ */
35298+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
35299+ int do_plink, struct au_wh_base base[],
35300+ struct path *h_path)
35301+{
35302+ int err;
35303+ struct inode *h_dir;
35304+
5527c038 35305+ h_dir = d_inode(h_root);
1facf9fc 35306+ h_path->dentry = base[AuBrWh_BASE].dentry;
35307+ au_wh_clean(h_dir, h_path, /*isdir*/0);
35308+ h_path->dentry = base[AuBrWh_PLINK].dentry;
35309+ if (do_plink) {
35310+ err = test_linkable(h_root);
35311+ if (unlikely(err)) {
35312+ err = 1;
35313+ goto out;
35314+ }
35315+
35316+ err = au_whdir(h_dir, h_path);
35317+ if (unlikely(err))
35318+ goto out;
35319+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
35320+ } else
35321+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35322+ h_path->dentry = base[AuBrWh_ORPH].dentry;
35323+ err = au_whdir(h_dir, h_path);
35324+ if (unlikely(err))
35325+ goto out;
35326+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
35327+
4f0767ce 35328+out:
1facf9fc 35329+ return err;
35330+}
35331+
35332+/*
35333+ * for the moment, aufs supports the branch filesystem which does not support
35334+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
35335+ * copyup failed. finally, such filesystem will not be used as the writable
35336+ * branch.
35337+ *
35338+ * returns tri-state, see above.
35339+ */
35340+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
35341+ int do_plink, struct au_wh_base base[],
35342+ struct path *h_path)
35343+{
35344+ int err;
35345+ struct inode *h_dir;
35346+
1308ab2a 35347+ WbrWhMustWriteLock(wbr);
35348+
1facf9fc 35349+ err = test_linkable(h_root);
35350+ if (unlikely(err)) {
35351+ err = 1;
35352+ goto out;
35353+ }
35354+
35355+ /*
35356+ * todo: should this create be done in /sbin/mount.aufs helper?
35357+ */
35358+ err = -EEXIST;
5527c038
JR
35359+ h_dir = d_inode(h_root);
35360+ if (d_is_negative(base[AuBrWh_BASE].dentry)) {
86dc4139
AM
35361+ h_path->dentry = base[AuBrWh_BASE].dentry;
35362+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
7e9cd9fe 35363+ } else if (d_is_reg(base[AuBrWh_BASE].dentry))
1facf9fc 35364+ err = 0;
35365+ else
523b37e3 35366+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 35367+ if (unlikely(err))
35368+ goto out;
35369+
35370+ h_path->dentry = base[AuBrWh_PLINK].dentry;
35371+ if (do_plink) {
35372+ err = au_whdir(h_dir, h_path);
35373+ if (unlikely(err))
35374+ goto out;
35375+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
35376+ } else
35377+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35378+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
35379+
35380+ h_path->dentry = base[AuBrWh_ORPH].dentry;
35381+ err = au_whdir(h_dir, h_path);
35382+ if (unlikely(err))
35383+ goto out;
35384+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
35385+
4f0767ce 35386+out:
1facf9fc 35387+ return err;
35388+}
35389+
35390+/*
35391+ * initialize the whiteout base file/dir for @br.
35392+ */
86dc4139 35393+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 35394+{
35395+ int err, i;
35396+ const unsigned char do_plink
35397+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 35398+ struct inode *h_dir;
86dc4139
AM
35399+ struct path path = br->br_path;
35400+ struct dentry *h_root = path.dentry;
1facf9fc 35401+ struct au_wbr *wbr = br->br_wbr;
35402+ static const struct qstr base_name[] = {
0c3ec466
AM
35403+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
35404+ sizeof(AUFS_BASE_NAME) - 1),
35405+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
35406+ sizeof(AUFS_PLINKDIR_NAME) - 1),
35407+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
35408+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 35409+ };
35410+ struct au_wh_base base[] = {
35411+ [AuBrWh_BASE] = {
35412+ .name = base_name + AuBrWh_BASE,
35413+ .dentry = NULL
35414+ },
35415+ [AuBrWh_PLINK] = {
35416+ .name = base_name + AuBrWh_PLINK,
35417+ .dentry = NULL
35418+ },
35419+ [AuBrWh_ORPH] = {
35420+ .name = base_name + AuBrWh_ORPH,
35421+ .dentry = NULL
35422+ }
35423+ };
35424+
1308ab2a 35425+ if (wbr)
35426+ WbrWhMustWriteLock(wbr);
1facf9fc 35427+
1facf9fc 35428+ for (i = 0; i < AuBrWh_Last; i++) {
35429+ /* doubly whiteouted */
35430+ struct dentry *d;
35431+
35432+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
35433+ err = PTR_ERR(d);
35434+ if (IS_ERR(d))
35435+ goto out;
35436+
35437+ base[i].dentry = d;
35438+ AuDebugOn(wbr
35439+ && wbr->wbr_wh[i]
35440+ && wbr->wbr_wh[i] != base[i].dentry);
35441+ }
35442+
35443+ if (wbr)
35444+ for (i = 0; i < AuBrWh_Last; i++) {
35445+ dput(wbr->wbr_wh[i]);
35446+ wbr->wbr_wh[i] = NULL;
35447+ }
35448+
35449+ err = 0;
1e00d052 35450+ if (!au_br_writable(br->br_perm)) {
5527c038 35451+ h_dir = d_inode(h_root);
1facf9fc 35452+ au_wh_init_ro(h_dir, base, &path);
1e00d052 35453+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 35454+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
35455+ if (err > 0)
35456+ goto out;
35457+ else if (err)
35458+ goto out_err;
1e00d052 35459+ } else {
1facf9fc 35460+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
35461+ if (err > 0)
35462+ goto out;
35463+ else if (err)
35464+ goto out_err;
1facf9fc 35465+ }
35466+ goto out; /* success */
35467+
4f0767ce 35468+out_err:
523b37e3
AM
35469+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
35470+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 35471+out:
1facf9fc 35472+ for (i = 0; i < AuBrWh_Last; i++)
35473+ dput(base[i].dentry);
35474+ return err;
35475+}
35476+
35477+/* ---------------------------------------------------------------------- */
35478+/*
35479+ * whiteouts are all hard-linked usually.
35480+ * when its link count reaches a ceiling, we create a new whiteout base
35481+ * asynchronously.
35482+ */
35483+
35484+struct reinit_br_wh {
35485+ struct super_block *sb;
35486+ struct au_branch *br;
35487+};
35488+
35489+static void reinit_br_wh(void *arg)
35490+{
35491+ int err;
35492+ aufs_bindex_t bindex;
35493+ struct path h_path;
35494+ struct reinit_br_wh *a = arg;
35495+ struct au_wbr *wbr;
523b37e3 35496+ struct inode *dir, *delegated;
1facf9fc 35497+ struct dentry *h_root;
35498+ struct au_hinode *hdir;
35499+
35500+ err = 0;
35501+ wbr = a->br->br_wbr;
35502+ /* big aufs lock */
35503+ si_noflush_write_lock(a->sb);
35504+ if (!au_br_writable(a->br->br_perm))
35505+ goto out;
35506+ bindex = au_br_index(a->sb, a->br->br_id);
35507+ if (unlikely(bindex < 0))
35508+ goto out;
35509+
1308ab2a 35510+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
5527c038 35511+ dir = d_inode(a->sb->s_root);
1facf9fc 35512+ hdir = au_hi(dir, bindex);
35513+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 35514+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 35515+
5afbbe0d 35516+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 35517+ wbr_wh_write_lock(wbr);
35518+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
35519+ h_root, a->br);
35520+ if (!err) {
86dc4139
AM
35521+ h_path.dentry = wbr->wbr_whbase;
35522+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
35523+ delegated = NULL;
35524+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
35525+ /*force*/0);
35526+ if (unlikely(err == -EWOULDBLOCK)) {
35527+ pr_warn("cannot retry for NFSv4 delegation"
35528+ " for an internal unlink\n");
35529+ iput(delegated);
35530+ }
1facf9fc 35531+ } else {
523b37e3 35532+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 35533+ err = 0;
35534+ }
35535+ dput(wbr->wbr_whbase);
35536+ wbr->wbr_whbase = NULL;
35537+ if (!err)
86dc4139 35538+ err = au_wh_init(a->br, a->sb);
1facf9fc 35539+ wbr_wh_write_unlock(wbr);
5afbbe0d 35540+ au_hn_inode_unlock(hdir);
1308ab2a 35541+ di_read_unlock(a->sb->s_root, AuLock_IR);
076b876e
AM
35542+ if (!err)
35543+ au_fhsm_wrote(a->sb, bindex, /*force*/0);
1facf9fc 35544+
4f0767ce 35545+out:
1facf9fc 35546+ if (wbr)
35547+ atomic_dec(&wbr->wbr_wh_running);
acd2b654 35548+ au_lcnt_dec(&a->br->br_count);
1facf9fc 35549+ si_write_unlock(a->sb);
027c5e7a 35550+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
9f237c51 35551+ au_kfree_rcu(a);
1facf9fc 35552+ if (unlikely(err))
35553+ AuIOErr("err %d\n", err);
35554+}
35555+
35556+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
35557+{
35558+ int do_dec, wkq_err;
35559+ struct reinit_br_wh *arg;
35560+
35561+ do_dec = 1;
35562+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
35563+ goto out;
35564+
35565+ /* ignore ENOMEM */
35566+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
35567+ if (arg) {
35568+ /*
35569+ * dec(wh_running), kfree(arg) and dec(br_count)
35570+ * in reinit function
35571+ */
35572+ arg->sb = sb;
35573+ arg->br = br;
acd2b654 35574+ au_lcnt_inc(&br->br_count);
53392da6 35575+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 35576+ if (unlikely(wkq_err)) {
35577+ atomic_dec(&br->br_wbr->wbr_wh_running);
acd2b654 35578+ au_lcnt_dec(&br->br_count);
9f237c51 35579+ au_kfree_rcu(arg);
1facf9fc 35580+ }
35581+ do_dec = 0;
35582+ }
35583+
4f0767ce 35584+out:
1facf9fc 35585+ if (do_dec)
35586+ atomic_dec(&br->br_wbr->wbr_wh_running);
35587+}
35588+
35589+/* ---------------------------------------------------------------------- */
35590+
35591+/*
35592+ * create the whiteout @wh.
35593+ */
35594+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
35595+ struct dentry *wh)
35596+{
35597+ int err;
35598+ struct path h_path = {
35599+ .dentry = wh
35600+ };
35601+ struct au_branch *br;
35602+ struct au_wbr *wbr;
35603+ struct dentry *h_parent;
523b37e3 35604+ struct inode *h_dir, *delegated;
1facf9fc 35605+
35606+ h_parent = wh->d_parent; /* dir inode is locked */
5527c038 35607+ h_dir = d_inode(h_parent);
1facf9fc 35608+ IMustLock(h_dir);
35609+
35610+ br = au_sbr(sb, bindex);
86dc4139 35611+ h_path.mnt = au_br_mnt(br);
1facf9fc 35612+ wbr = br->br_wbr;
35613+ wbr_wh_read_lock(wbr);
35614+ if (wbr->wbr_whbase) {
523b37e3
AM
35615+ delegated = NULL;
35616+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
35617+ if (unlikely(err == -EWOULDBLOCK)) {
35618+ pr_warn("cannot retry for NFSv4 delegation"
35619+ " for an internal link\n");
35620+ iput(delegated);
35621+ }
1facf9fc 35622+ if (!err || err != -EMLINK)
35623+ goto out;
35624+
35625+ /* link count full. re-initialize br_whbase. */
35626+ kick_reinit_br_wh(sb, br);
35627+ }
35628+
35629+ /* return this error in this context */
b4510431 35630+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
076b876e
AM
35631+ if (!err)
35632+ au_fhsm_wrote(sb, bindex, /*force*/0);
1facf9fc 35633+
4f0767ce 35634+out:
1facf9fc 35635+ wbr_wh_read_unlock(wbr);
35636+ return err;
35637+}
35638+
35639+/* ---------------------------------------------------------------------- */
35640+
35641+/*
35642+ * create or remove the diropq.
35643+ */
35644+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
35645+ unsigned int flags)
35646+{
35647+ struct dentry *opq_dentry, *h_dentry;
35648+ struct super_block *sb;
35649+ struct au_branch *br;
35650+ int err;
35651+
35652+ sb = dentry->d_sb;
35653+ br = au_sbr(sb, bindex);
35654+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 35655+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 35656+ if (IS_ERR(opq_dentry))
35657+ goto out;
35658+
35659+ if (au_ftest_diropq(flags, CREATE)) {
35660+ err = link_or_create_wh(sb, bindex, opq_dentry);
35661+ if (!err) {
35662+ au_set_dbdiropq(dentry, bindex);
35663+ goto out; /* success */
35664+ }
35665+ } else {
35666+ struct path tmp = {
35667+ .dentry = opq_dentry,
86dc4139 35668+ .mnt = au_br_mnt(br)
1facf9fc 35669+ };
5527c038 35670+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp);
1facf9fc 35671+ if (!err)
35672+ au_set_dbdiropq(dentry, -1);
35673+ }
35674+ dput(opq_dentry);
35675+ opq_dentry = ERR_PTR(err);
35676+
4f0767ce 35677+out:
1facf9fc 35678+ return opq_dentry;
35679+}
35680+
35681+struct do_diropq_args {
35682+ struct dentry **errp;
35683+ struct dentry *dentry;
35684+ aufs_bindex_t bindex;
35685+ unsigned int flags;
35686+};
35687+
35688+static void call_do_diropq(void *args)
35689+{
35690+ struct do_diropq_args *a = args;
35691+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
35692+}
35693+
35694+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
35695+ unsigned int flags)
35696+{
35697+ struct dentry *diropq, *h_dentry;
35698+
35699+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 35700+ if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE))
1facf9fc 35701+ diropq = do_diropq(dentry, bindex, flags);
35702+ else {
35703+ int wkq_err;
35704+ struct do_diropq_args args = {
35705+ .errp = &diropq,
35706+ .dentry = dentry,
35707+ .bindex = bindex,
35708+ .flags = flags
35709+ };
35710+
35711+ wkq_err = au_wkq_wait(call_do_diropq, &args);
35712+ if (unlikely(wkq_err))
35713+ diropq = ERR_PTR(wkq_err);
35714+ }
35715+
35716+ return diropq;
35717+}
35718+
35719+/* ---------------------------------------------------------------------- */
35720+
35721+/*
35722+ * lookup whiteout dentry.
35723+ * @h_parent: lower parent dentry which must exist and be locked
35724+ * @base_name: name of dentry which will be whiteouted
35725+ * returns dentry for whiteout.
35726+ */
35727+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
35728+ struct au_branch *br)
35729+{
35730+ int err;
35731+ struct qstr wh_name;
35732+ struct dentry *wh_dentry;
35733+
35734+ err = au_wh_name_alloc(&wh_name, base_name);
35735+ wh_dentry = ERR_PTR(err);
35736+ if (!err) {
b4510431 35737+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
9f237c51 35738+ au_kfree_try_rcu(wh_name.name);
1facf9fc 35739+ }
35740+ return wh_dentry;
35741+}
35742+
35743+/*
35744+ * link/create a whiteout for @dentry on @bindex.
35745+ */
35746+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
35747+ struct dentry *h_parent)
35748+{
35749+ struct dentry *wh_dentry;
35750+ struct super_block *sb;
35751+ int err;
35752+
35753+ sb = dentry->d_sb;
35754+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
5527c038 35755+ if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) {
1facf9fc 35756+ err = link_or_create_wh(sb, bindex, wh_dentry);
076b876e 35757+ if (!err) {
1facf9fc 35758+ au_set_dbwh(dentry, bindex);
076b876e
AM
35759+ au_fhsm_wrote(sb, bindex, /*force*/0);
35760+ } else {
1facf9fc 35761+ dput(wh_dentry);
35762+ wh_dentry = ERR_PTR(err);
35763+ }
35764+ }
35765+
35766+ return wh_dentry;
35767+}
35768+
35769+/* ---------------------------------------------------------------------- */
35770+
35771+/* Delete all whiteouts in this directory on branch bindex. */
35772+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
35773+ aufs_bindex_t bindex, struct au_branch *br)
35774+{
35775+ int err;
35776+ unsigned long ul, n;
35777+ struct qstr wh_name;
35778+ char *p;
35779+ struct hlist_head *head;
c06a8ce3 35780+ struct au_vdir_wh *pos;
1facf9fc 35781+ struct au_vdir_destr *str;
35782+
35783+ err = -ENOMEM;
537831f9 35784+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 35785+ wh_name.name = p;
35786+ if (unlikely(!wh_name.name))
35787+ goto out;
35788+
35789+ err = 0;
35790+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
35791+ p += AUFS_WH_PFX_LEN;
35792+ n = whlist->nh_num;
35793+ head = whlist->nh_head;
35794+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
35795+ hlist_for_each_entry(pos, head, wh_hash) {
35796+ if (pos->wh_bindex != bindex)
1facf9fc 35797+ continue;
35798+
c06a8ce3 35799+ str = &pos->wh_str;
1facf9fc 35800+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
35801+ memcpy(p, str->name, str->len);
35802+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
35803+ err = unlink_wh_name(h_dentry, &wh_name, br);
35804+ if (!err)
35805+ continue;
35806+ break;
35807+ }
35808+ AuIOErr("whiteout name too long %.*s\n",
35809+ str->len, str->name);
35810+ err = -EIO;
35811+ break;
35812+ }
35813+ }
1c60b727 35814+ free_page((unsigned long)wh_name.name);
1facf9fc 35815+
4f0767ce 35816+out:
1facf9fc 35817+ return err;
35818+}
35819+
35820+struct del_wh_children_args {
35821+ int *errp;
35822+ struct dentry *h_dentry;
1308ab2a 35823+ struct au_nhash *whlist;
1facf9fc 35824+ aufs_bindex_t bindex;
35825+ struct au_branch *br;
35826+};
35827+
35828+static void call_del_wh_children(void *args)
35829+{
35830+ struct del_wh_children_args *a = args;
1308ab2a 35831+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 35832+}
35833+
35834+/* ---------------------------------------------------------------------- */
35835+
35836+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
35837+{
35838+ struct au_whtmp_rmdir *whtmp;
dece6358 35839+ int err;
1308ab2a 35840+ unsigned int rdhash;
dece6358
AM
35841+
35842+ SiMustAnyLock(sb);
1facf9fc 35843+
be52b249 35844+ whtmp = kzalloc(sizeof(*whtmp), gfp);
dece6358
AM
35845+ if (unlikely(!whtmp)) {
35846+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 35847+ goto out;
dece6358 35848+ }
1facf9fc 35849+
1308ab2a 35850+ /* no estimation for dir size */
35851+ rdhash = au_sbi(sb)->si_rdhash;
35852+ if (!rdhash)
35853+ rdhash = AUFS_RDHASH_DEF;
35854+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
35855+ if (unlikely(err)) {
9f237c51 35856+ au_kfree_rcu(whtmp);
1308ab2a 35857+ whtmp = ERR_PTR(err);
35858+ }
dece6358 35859+
4f0767ce 35860+out:
dece6358 35861+ return whtmp;
1facf9fc 35862+}
35863+
35864+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
35865+{
027c5e7a 35866+ if (whtmp->br)
acd2b654 35867+ au_lcnt_dec(&whtmp->br->br_count);
1facf9fc 35868+ dput(whtmp->wh_dentry);
35869+ iput(whtmp->dir);
dece6358 35870+ au_nhash_wh_free(&whtmp->whlist);
9f237c51 35871+ au_kfree_rcu(whtmp);
1facf9fc 35872+}
35873+
35874+/*
35875+ * rmdir the whiteouted temporary named dir @h_dentry.
35876+ * @whlist: whiteouted children.
35877+ */
35878+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
35879+ struct dentry *wh_dentry, struct au_nhash *whlist)
35880+{
35881+ int err;
2000de60 35882+ unsigned int h_nlink;
1facf9fc 35883+ struct path h_tmp;
35884+ struct inode *wh_inode, *h_dir;
35885+ struct au_branch *br;
35886+
5527c038 35887+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
1facf9fc 35888+ IMustLock(h_dir);
35889+
35890+ br = au_sbr(dir->i_sb, bindex);
5527c038 35891+ wh_inode = d_inode(wh_dentry);
febd17d6 35892+ inode_lock_nested(wh_inode, AuLsc_I_CHILD);
1facf9fc 35893+
35894+ /*
35895+ * someone else might change some whiteouts while we were sleeping.
35896+ * it means this whlist may have an obsoleted entry.
35897+ */
35898+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
35899+ err = del_wh_children(wh_dentry, whlist, bindex, br);
35900+ else {
35901+ int wkq_err;
35902+ struct del_wh_children_args args = {
35903+ .errp = &err,
35904+ .h_dentry = wh_dentry,
1308ab2a 35905+ .whlist = whlist,
1facf9fc 35906+ .bindex = bindex,
35907+ .br = br
35908+ };
35909+
35910+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
35911+ if (unlikely(wkq_err))
35912+ err = wkq_err;
35913+ }
febd17d6 35914+ inode_unlock(wh_inode);
1facf9fc 35915+
35916+ if (!err) {
35917+ h_tmp.dentry = wh_dentry;
86dc4139 35918+ h_tmp.mnt = au_br_mnt(br);
2000de60 35919+ h_nlink = h_dir->i_nlink;
1facf9fc 35920+ err = vfsub_rmdir(h_dir, &h_tmp);
2000de60
JR
35921+ /* some fs doesn't change the parent nlink in some cases */
35922+ h_nlink -= h_dir->i_nlink;
1facf9fc 35923+ }
35924+
35925+ if (!err) {
5afbbe0d 35926+ if (au_ibtop(dir) == bindex) {
7f207e10 35927+ /* todo: dir->i_mutex is necessary */
1facf9fc 35928+ au_cpup_attr_timesizes(dir);
2000de60
JR
35929+ if (h_nlink)
35930+ vfsub_drop_nlink(dir);
1facf9fc 35931+ }
35932+ return 0; /* success */
35933+ }
35934+
523b37e3 35935+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 35936+ return err;
35937+}
35938+
35939+static void call_rmdir_whtmp(void *args)
35940+{
35941+ int err;
e49829fe 35942+ aufs_bindex_t bindex;
1facf9fc 35943+ struct au_whtmp_rmdir *a = args;
35944+ struct super_block *sb;
35945+ struct dentry *h_parent;
35946+ struct inode *h_dir;
1facf9fc 35947+ struct au_hinode *hdir;
35948+
35949+ /* rmdir by nfsd may cause deadlock with this i_mutex */
febd17d6 35950+ /* inode_lock(a->dir); */
e49829fe 35951+ err = -EROFS;
1facf9fc 35952+ sb = a->dir->i_sb;
e49829fe
JR
35953+ si_read_lock(sb, !AuLock_FLUSH);
35954+ if (!au_br_writable(a->br->br_perm))
35955+ goto out;
35956+ bindex = au_br_index(sb, a->br->br_id);
35957+ if (unlikely(bindex < 0))
1facf9fc 35958+ goto out;
35959+
35960+ err = -EIO;
1facf9fc 35961+ ii_write_lock_parent(a->dir);
35962+ h_parent = dget_parent(a->wh_dentry);
5527c038 35963+ h_dir = d_inode(h_parent);
e49829fe 35964+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
35965+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
35966+ if (unlikely(err))
35967+ goto out_mnt;
5afbbe0d 35968+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
35969+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
35970+ a->br);
86dc4139
AM
35971+ if (!err)
35972+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
5afbbe0d 35973+ au_hn_inode_unlock(hdir);
86dc4139
AM
35974+ vfsub_mnt_drop_write(au_br_mnt(a->br));
35975+
35976+out_mnt:
1facf9fc 35977+ dput(h_parent);
35978+ ii_write_unlock(a->dir);
4f0767ce 35979+out:
febd17d6 35980+ /* inode_unlock(a->dir); */
1facf9fc 35981+ au_whtmp_rmdir_free(a);
027c5e7a
AM
35982+ si_read_unlock(sb);
35983+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 35984+ if (unlikely(err))
35985+ AuIOErr("err %d\n", err);
35986+}
35987+
35988+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
35989+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
35990+{
35991+ int wkq_err;
e49829fe 35992+ struct super_block *sb;
1facf9fc 35993+
35994+ IMustLock(dir);
35995+
35996+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 35997+ sb = dir->i_sb;
1facf9fc 35998+ args->dir = au_igrab(dir);
e49829fe 35999+ args->br = au_sbr(sb, bindex);
acd2b654 36000+ au_lcnt_inc(&args->br->br_count);
1facf9fc 36001+ args->wh_dentry = dget(wh_dentry);
53392da6 36002+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 36003+ if (unlikely(wkq_err)) {
523b37e3 36004+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 36005+ au_whtmp_rmdir_free(args);
36006+ }
36007+}
7f207e10
AM
36008diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
36009--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 36010+++ linux/fs/aufs/whout.h 2019-03-05 12:13:00.145891204 +0100
062440b3
AM
36011@@ -0,0 +1,86 @@
36012+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 36013+/*
ba1aed25 36014+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 36015+ *
36016+ * This program, aufs is free software; you can redistribute it and/or modify
36017+ * it under the terms of the GNU General Public License as published by
36018+ * the Free Software Foundation; either version 2 of the License, or
36019+ * (at your option) any later version.
dece6358
AM
36020+ *
36021+ * This program is distributed in the hope that it will be useful,
36022+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36023+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36024+ * GNU General Public License for more details.
36025+ *
36026+ * You should have received a copy of the GNU General Public License
523b37e3 36027+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 36028+ */
36029+
36030+/*
36031+ * whiteout for logical deletion and opaque directory
36032+ */
36033+
36034+#ifndef __AUFS_WHOUT_H__
36035+#define __AUFS_WHOUT_H__
36036+
36037+#ifdef __KERNEL__
36038+
1facf9fc 36039+#include "dir.h"
36040+
36041+/* whout.c */
36042+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
076b876e
AM
36043+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
36044+int au_diropq_test(struct dentry *h_dentry);
3c1bdaff 36045+struct au_branch;
1facf9fc 36046+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
36047+ struct qstr *prefix);
36048+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
36049+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
36050+ struct dentry *dentry);
86dc4139 36051+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 36052+
36053+/* diropq flags */
36054+#define AuDiropq_CREATE 1
36055+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
36056+#define au_fset_diropq(flags, name) \
36057+ do { (flags) |= AuDiropq_##name; } while (0)
36058+#define au_fclr_diropq(flags, name) \
36059+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 36060+
36061+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
36062+ unsigned int flags);
36063+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
36064+ struct au_branch *br);
36065+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
36066+ struct dentry *h_parent);
36067+
36068+/* real rmdir for the whiteout-ed dir */
36069+struct au_whtmp_rmdir {
36070+ struct inode *dir;
e49829fe 36071+ struct au_branch *br;
1facf9fc 36072+ struct dentry *wh_dentry;
dece6358 36073+ struct au_nhash whlist;
1facf9fc 36074+};
36075+
36076+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
36077+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
36078+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
36079+ struct dentry *wh_dentry, struct au_nhash *whlist);
36080+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
36081+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
36082+
36083+/* ---------------------------------------------------------------------- */
36084+
36085+static inline struct dentry *au_diropq_create(struct dentry *dentry,
36086+ aufs_bindex_t bindex)
36087+{
36088+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
36089+}
36090+
36091+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
36092+{
36093+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
36094+}
36095+
36096+#endif /* __KERNEL__ */
36097+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
36098diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
36099--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 36100+++ linux/fs/aufs/wkq.c 2019-03-05 12:13:00.145891204 +0100
acd2b654 36101@@ -0,0 +1,392 @@
cd7a4cd9 36102+// SPDX-License-Identifier: GPL-2.0
1facf9fc 36103+/*
ba1aed25 36104+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 36105+ *
36106+ * This program, aufs is free software; you can redistribute it and/or modify
36107+ * it under the terms of the GNU General Public License as published by
36108+ * the Free Software Foundation; either version 2 of the License, or
36109+ * (at your option) any later version.
dece6358
AM
36110+ *
36111+ * This program is distributed in the hope that it will be useful,
36112+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36113+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36114+ * GNU General Public License for more details.
36115+ *
36116+ * You should have received a copy of the GNU General Public License
523b37e3 36117+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 36118+ */
36119+
36120+/*
36121+ * workqueue for asynchronous/super-io operations
acd2b654 36122+ * todo: try new credential scheme
1facf9fc 36123+ */
36124+
dece6358 36125+#include <linux/module.h>
1facf9fc 36126+#include "aufs.h"
36127+
9dbd164d 36128+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 36129+
9dbd164d 36130+static struct workqueue_struct *au_wkq;
1facf9fc 36131+
36132+struct au_wkinfo {
36133+ struct work_struct wk;
7f207e10 36134+ struct kobject *kobj;
1facf9fc 36135+
36136+ unsigned int flags; /* see wkq.h */
36137+
36138+ au_wkq_func_t func;
36139+ void *args;
36140+
8b6a4947
AM
36141+#ifdef CONFIG_LOCKDEP
36142+ int dont_check;
36143+ struct held_lock **hlock;
36144+#endif
36145+
1facf9fc 36146+ struct completion *comp;
36147+};
36148+
36149+/* ---------------------------------------------------------------------- */
8b6a4947
AM
36150+/*
36151+ * Aufs passes some operations to the workqueue such as the internal copyup.
36152+ * This scheme looks rather unnatural for LOCKDEP debugging feature, since the
36153+ * job run by workqueue depends upon the locks acquired in the other task.
36154+ * Delegating a small operation to the workqueue, aufs passes its lockdep
36155+ * information too. And the job in the workqueue restores the info in order to
36156+ * pretend as if it acquired those locks. This is just to make LOCKDEP work
36157+ * correctly and expectedly.
36158+ */
36159+
36160+#ifndef CONFIG_LOCKDEP
36161+AuStubInt0(au_wkq_lockdep_alloc, struct au_wkinfo *wkinfo);
36162+AuStubVoid(au_wkq_lockdep_free, struct au_wkinfo *wkinfo);
36163+AuStubVoid(au_wkq_lockdep_pre, struct au_wkinfo *wkinfo);
36164+AuStubVoid(au_wkq_lockdep_post, struct au_wkinfo *wkinfo);
36165+AuStubVoid(au_wkq_lockdep_init, struct au_wkinfo *wkinfo);
36166+#else
36167+static void au_wkq_lockdep_init(struct au_wkinfo *wkinfo)
36168+{
36169+ wkinfo->hlock = NULL;
36170+ wkinfo->dont_check = 0;
36171+}
36172+
36173+/*
36174+ * 1: matched
36175+ * 0: unmatched
36176+ */
36177+static int au_wkq_lockdep_test(struct lock_class_key *key, const char *name)
36178+{
36179+ static DEFINE_SPINLOCK(spin);
36180+ static struct {
36181+ char *name;
36182+ struct lock_class_key *key;
36183+ } a[] = {
36184+ { .name = "&sbinfo->si_rwsem" },
36185+ { .name = "&finfo->fi_rwsem" },
36186+ { .name = "&dinfo->di_rwsem" },
36187+ { .name = "&iinfo->ii_rwsem" }
36188+ };
36189+ static int set;
36190+ int i;
36191+
36192+ /* lockless read from 'set.' see below */
36193+ if (set == ARRAY_SIZE(a)) {
36194+ for (i = 0; i < ARRAY_SIZE(a); i++)
36195+ if (a[i].key == key)
36196+ goto match;
36197+ goto unmatch;
36198+ }
36199+
36200+ spin_lock(&spin);
36201+ if (set)
36202+ for (i = 0; i < ARRAY_SIZE(a); i++)
36203+ if (a[i].key == key) {
36204+ spin_unlock(&spin);
36205+ goto match;
36206+ }
36207+ for (i = 0; i < ARRAY_SIZE(a); i++) {
36208+ if (a[i].key) {
36209+ if (unlikely(a[i].key == key)) { /* rare but possible */
36210+ spin_unlock(&spin);
36211+ goto match;
36212+ } else
36213+ continue;
36214+ }
36215+ if (strstr(a[i].name, name)) {
36216+ /*
36217+ * the order of these three lines is important for the
36218+ * lockless read above.
36219+ */
36220+ a[i].key = key;
36221+ spin_unlock(&spin);
36222+ set++;
36223+ /* AuDbg("%d, %s\n", set, name); */
36224+ goto match;
36225+ }
36226+ }
36227+ spin_unlock(&spin);
36228+ goto unmatch;
36229+
36230+match:
36231+ return 1;
36232+unmatch:
36233+ return 0;
36234+}
36235+
36236+static int au_wkq_lockdep_alloc(struct au_wkinfo *wkinfo)
36237+{
36238+ int err, n;
36239+ struct task_struct *curr;
36240+ struct held_lock **hl, *held_locks, *p;
36241+
36242+ err = 0;
36243+ curr = current;
36244+ wkinfo->dont_check = lockdep_recursing(curr);
36245+ if (wkinfo->dont_check)
36246+ goto out;
36247+ n = curr->lockdep_depth;
36248+ if (!n)
36249+ goto out;
36250+
36251+ err = -ENOMEM;
36252+ wkinfo->hlock = kmalloc_array(n + 1, sizeof(*wkinfo->hlock), GFP_NOFS);
36253+ if (unlikely(!wkinfo->hlock))
36254+ goto out;
36255+
36256+ err = 0;
36257+#if 0
36258+ if (0 && au_debug_test()) /* left for debugging */
36259+ lockdep_print_held_locks(curr);
36260+#endif
36261+ held_locks = curr->held_locks;
36262+ hl = wkinfo->hlock;
36263+ while (n--) {
36264+ p = held_locks++;
36265+ if (au_wkq_lockdep_test(p->instance->key, p->instance->name))
36266+ *hl++ = p;
36267+ }
36268+ *hl = NULL;
36269+
36270+out:
36271+ return err;
36272+}
36273+
36274+static void au_wkq_lockdep_free(struct au_wkinfo *wkinfo)
36275+{
9f237c51 36276+ au_kfree_try_rcu(wkinfo->hlock);
8b6a4947
AM
36277+}
36278+
36279+static void au_wkq_lockdep_pre(struct au_wkinfo *wkinfo)
36280+{
36281+ struct held_lock *p, **hl = wkinfo->hlock;
36282+ int subclass;
36283+
36284+ if (wkinfo->dont_check)
36285+ lockdep_off();
36286+ if (!hl)
36287+ return;
36288+ while ((p = *hl++)) { /* assignment */
36289+ subclass = lockdep_hlock_class(p)->subclass;
36290+ /* AuDbg("%s, %d\n", p->instance->name, subclass); */
36291+ if (p->read)
36292+ rwsem_acquire_read(p->instance, subclass, 0,
36293+ /*p->acquire_ip*/_RET_IP_);
36294+ else
36295+ rwsem_acquire(p->instance, subclass, 0,
36296+ /*p->acquire_ip*/_RET_IP_);
36297+ }
36298+}
36299+
36300+static void au_wkq_lockdep_post(struct au_wkinfo *wkinfo)
36301+{
36302+ struct held_lock *p, **hl = wkinfo->hlock;
36303+
36304+ if (wkinfo->dont_check)
36305+ lockdep_on();
36306+ if (!hl)
36307+ return;
36308+ while ((p = *hl++)) /* assignment */
36309+ rwsem_release(p->instance, 0, /*p->acquire_ip*/_RET_IP_);
36310+}
36311+#endif
1facf9fc 36312+
1facf9fc 36313+static void wkq_func(struct work_struct *wk)
36314+{
36315+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
36316+
2dfbb274 36317+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
36318+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
36319+
8b6a4947 36320+ au_wkq_lockdep_pre(wkinfo);
1facf9fc 36321+ wkinfo->func(wkinfo->args);
8b6a4947 36322+ au_wkq_lockdep_post(wkinfo);
1facf9fc 36323+ if (au_ftest_wkq(wkinfo->flags, WAIT))
36324+ complete(wkinfo->comp);
36325+ else {
7f207e10 36326+ kobject_put(wkinfo->kobj);
9dbd164d 36327+ module_put(THIS_MODULE); /* todo: ?? */
9f237c51 36328+ au_kfree_rcu(wkinfo);
1facf9fc 36329+ }
36330+}
36331+
36332+/*
36333+ * Since struct completion is large, try allocating it dynamically.
36334+ */
c2b27bf2 36335+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 36336+#define AuWkqCompDeclare(name) struct completion *comp = NULL
36337+
36338+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
36339+{
36340+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
36341+ if (*comp) {
36342+ init_completion(*comp);
36343+ wkinfo->comp = *comp;
36344+ return 0;
36345+ }
36346+ return -ENOMEM;
36347+}
36348+
36349+static void au_wkq_comp_free(struct completion *comp)
36350+{
9f237c51 36351+ au_kfree_rcu(comp);
1facf9fc 36352+}
36353+
36354+#else
36355+
36356+/* no braces */
36357+#define AuWkqCompDeclare(name) \
36358+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
36359+ struct completion *comp = &_ ## name
36360+
36361+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
36362+{
36363+ wkinfo->comp = *comp;
36364+ return 0;
36365+}
36366+
36367+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
36368+{
36369+ /* empty */
36370+}
36371+#endif /* 4KSTACKS */
36372+
53392da6 36373+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 36374+{
53392da6
AM
36375+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
36376+ if (au_wkq_test()) {
38d290e6 36377+ AuWarn1("wkq from wkq, unless silly-rename on NFS,"
acd2b654
AM
36378+ " due to a dead dir by UDBA,"
36379+ " or async xino write?\n");
53392da6
AM
36380+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
36381+ }
36382+ } else
36383+ au_dbg_verify_kthread();
36384+
36385+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 36386+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 36387+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
36388+ } else {
36389+ INIT_WORK(&wkinfo->wk, wkq_func);
36390+ schedule_work(&wkinfo->wk);
36391+ }
1facf9fc 36392+}
36393+
7f207e10
AM
36394+/*
36395+ * Be careful. It is easy to make deadlock happen.
36396+ * processA: lock, wkq and wait
36397+ * processB: wkq and wait, lock in wkq
36398+ * --> deadlock
36399+ */
b752ccd1 36400+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 36401+{
36402+ int err;
36403+ AuWkqCompDeclare(comp);
36404+ struct au_wkinfo wkinfo = {
b752ccd1 36405+ .flags = flags,
1facf9fc 36406+ .func = func,
36407+ .args = args
36408+ };
36409+
36410+ err = au_wkq_comp_alloc(&wkinfo, &comp);
8b6a4947
AM
36411+ if (unlikely(err))
36412+ goto out;
36413+ err = au_wkq_lockdep_alloc(&wkinfo);
36414+ if (unlikely(err))
36415+ goto out_comp;
1facf9fc 36416+ if (!err) {
53392da6 36417+ au_wkq_run(&wkinfo);
1facf9fc 36418+ /* no timeout, no interrupt */
36419+ wait_for_completion(wkinfo.comp);
1facf9fc 36420+ }
8b6a4947 36421+ au_wkq_lockdep_free(&wkinfo);
1facf9fc 36422+
8b6a4947
AM
36423+out_comp:
36424+ au_wkq_comp_free(comp);
36425+out:
36426+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 36427+ return err;
1facf9fc 36428+}
36429+
027c5e7a
AM
36430+/*
36431+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
36432+ * problem in a concurrent umounting.
36433+ */
53392da6
AM
36434+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
36435+ unsigned int flags)
1facf9fc 36436+{
36437+ int err;
36438+ struct au_wkinfo *wkinfo;
36439+
f0c0a007 36440+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
1facf9fc 36441+
36442+ /*
36443+ * wkq_func() must free this wkinfo.
36444+ * it highly depends upon the implementation of workqueue.
36445+ */
36446+ err = 0;
36447+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
36448+ if (wkinfo) {
7f207e10 36449+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 36450+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 36451+ wkinfo->func = func;
36452+ wkinfo->args = args;
36453+ wkinfo->comp = NULL;
8b6a4947 36454+ au_wkq_lockdep_init(wkinfo);
7f207e10 36455+ kobject_get(wkinfo->kobj);
9dbd164d 36456+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 36457+
53392da6 36458+ au_wkq_run(wkinfo);
1facf9fc 36459+ } else {
36460+ err = -ENOMEM;
e49829fe 36461+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 36462+ }
36463+
36464+ return err;
36465+}
36466+
36467+/* ---------------------------------------------------------------------- */
36468+
36469+void au_nwt_init(struct au_nowait_tasks *nwt)
36470+{
f0c0a007
AM
36471+ atomic_set(&nwt->nw_len, 0);
36472+ /* smp_mb(); */ /* atomic_set */
1facf9fc 36473+ init_waitqueue_head(&nwt->nw_wq);
36474+}
36475+
36476+void au_wkq_fin(void)
36477+{
9dbd164d 36478+ destroy_workqueue(au_wkq);
1facf9fc 36479+}
36480+
36481+int __init au_wkq_init(void)
36482+{
9dbd164d 36483+ int err;
b752ccd1
AM
36484+
36485+ err = 0;
86dc4139 36486+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
36487+ if (IS_ERR(au_wkq))
36488+ err = PTR_ERR(au_wkq);
36489+ else if (!au_wkq)
36490+ err = -ENOMEM;
b752ccd1
AM
36491+
36492+ return err;
1facf9fc 36493+}
7f207e10
AM
36494diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
36495--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
ba1aed25 36496+++ linux/fs/aufs/wkq.h 2019-03-05 12:13:00.145891204 +0100
acd2b654 36497@@ -0,0 +1,89 @@
062440b3 36498+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 36499+/*
ba1aed25 36500+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 36501+ *
36502+ * This program, aufs is free software; you can redistribute it and/or modify
36503+ * it under the terms of the GNU General Public License as published by
36504+ * the Free Software Foundation; either version 2 of the License, or
36505+ * (at your option) any later version.
dece6358
AM
36506+ *
36507+ * This program is distributed in the hope that it will be useful,
36508+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36509+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36510+ * GNU General Public License for more details.
36511+ *
36512+ * You should have received a copy of the GNU General Public License
523b37e3 36513+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 36514+ */
36515+
36516+/*
36517+ * workqueue for asynchronous/super-io operations
36518+ * todo: try new credentials management scheme
36519+ */
36520+
36521+#ifndef __AUFS_WKQ_H__
36522+#define __AUFS_WKQ_H__
36523+
36524+#ifdef __KERNEL__
36525+
8b6a4947 36526+#include <linux/wait.h>
5afbbe0d 36527+
dece6358
AM
36528+struct super_block;
36529+
1facf9fc 36530+/* ---------------------------------------------------------------------- */
36531+
36532+/*
36533+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
36534+ */
36535+struct au_nowait_tasks {
f0c0a007 36536+ atomic_t nw_len;
1facf9fc 36537+ wait_queue_head_t nw_wq;
36538+};
36539+
36540+/* ---------------------------------------------------------------------- */
36541+
36542+typedef void (*au_wkq_func_t)(void *args);
36543+
36544+/* wkq flags */
36545+#define AuWkq_WAIT 1
9dbd164d 36546+#define AuWkq_NEST (1 << 1)
1facf9fc 36547+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
36548+#define au_fset_wkq(flags, name) \
36549+ do { (flags) |= AuWkq_##name; } while (0)
36550+#define au_fclr_wkq(flags, name) \
36551+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 36552+
36553+/* wkq.c */
b752ccd1 36554+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
36555+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
36556+ unsigned int flags);
1facf9fc 36557+void au_nwt_init(struct au_nowait_tasks *nwt);
36558+int __init au_wkq_init(void);
36559+void au_wkq_fin(void);
36560+
36561+/* ---------------------------------------------------------------------- */
36562+
53392da6
AM
36563+static inline int au_wkq_test(void)
36564+{
36565+ return current->flags & PF_WQ_WORKER;
36566+}
36567+
b752ccd1 36568+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 36569+{
b752ccd1 36570+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 36571+}
36572+
36573+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
36574+{
f0c0a007 36575+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 36576+ wake_up_all(&nwt->nw_wq);
36577+}
36578+
36579+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
36580+{
f0c0a007 36581+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
1facf9fc 36582+ return 0;
36583+}
36584+
36585+#endif /* __KERNEL__ */
36586+#endif /* __AUFS_WKQ_H__ */
c1595e42
JR
36587diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
36588--- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 36589+++ linux/fs/aufs/xattr.c 2019-03-05 12:13:00.145891204 +0100
062440b3 36590@@ -0,0 +1,356 @@
cd7a4cd9 36591+// SPDX-License-Identifier: GPL-2.0
c1595e42 36592+/*
ba1aed25 36593+ * Copyright (C) 2014-2019 Junjiro R. Okajima
c1595e42
JR
36594+ *
36595+ * This program, aufs is free software; you can redistribute it and/or modify
36596+ * it under the terms of the GNU General Public License as published by
36597+ * the Free Software Foundation; either version 2 of the License, or
36598+ * (at your option) any later version.
36599+ *
36600+ * This program is distributed in the hope that it will be useful,
36601+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36602+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36603+ * GNU General Public License for more details.
36604+ *
36605+ * You should have received a copy of the GNU General Public License
36606+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
36607+ */
36608+
36609+/*
36610+ * handling xattr functions
36611+ */
36612+
a2654f78
AM
36613+#include <linux/fs.h>
36614+#include <linux/posix_acl_xattr.h>
c1595e42
JR
36615+#include <linux/xattr.h>
36616+#include "aufs.h"
36617+
36618+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
36619+{
36620+ if (!ignore_flags)
36621+ goto out;
36622+ switch (err) {
36623+ case -ENOMEM:
36624+ case -EDQUOT:
36625+ goto out;
36626+ }
36627+
36628+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
36629+ err = 0;
36630+ goto out;
36631+ }
36632+
36633+#define cmp(brattr, prefix) do { \
36634+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \
36635+ XATTR_##prefix##_PREFIX_LEN)) { \
36636+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \
36637+ err = 0; \
36638+ goto out; \
36639+ } \
36640+ } while (0)
36641+
36642+ cmp(SEC, SECURITY);
36643+ cmp(SYS, SYSTEM);
36644+ cmp(TR, TRUSTED);
36645+ cmp(USR, USER);
36646+#undef cmp
36647+
36648+ if (ignore_flags & AuBrAttr_ICEX_OTH)
36649+ err = 0;
36650+
36651+out:
36652+ return err;
36653+}
36654+
36655+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
36656+
36657+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe
AM
36658+ char *name, char **buf, unsigned int ignore_flags,
36659+ unsigned int verbose)
c1595e42
JR
36660+{
36661+ int err;
36662+ ssize_t ssz;
36663+ struct inode *h_idst;
36664+
36665+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
36666+ err = ssz;
36667+ if (unlikely(err <= 0)) {
c1595e42
JR
36668+ if (err == -ENODATA
36669+ || (err == -EOPNOTSUPP
b912730e 36670+ && ((ignore_flags & au_xattr_out_of_list)
5527c038 36671+ || (au_test_nfs_noacl(d_inode(h_src))
b912730e
AM
36672+ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)
36673+ || !strcmp(name,
36674+ XATTR_NAME_POSIX_ACL_DEFAULT))))
36675+ ))
c1595e42 36676+ err = 0;
b912730e
AM
36677+ if (err && (verbose || au_debug_test()))
36678+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
36679+ goto out;
36680+ }
36681+
36682+ /* unlock it temporary */
5527c038 36683+ h_idst = d_inode(h_dst);
febd17d6 36684+ inode_unlock(h_idst);
c1595e42 36685+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
febd17d6 36686+ inode_lock_nested(h_idst, AuLsc_I_CHILD2);
c1595e42 36687+ if (unlikely(err)) {
7e9cd9fe
AM
36688+ if (verbose || au_debug_test())
36689+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
36690+ err = au_xattr_ignore(err, name, ignore_flags);
36691+ }
36692+
36693+out:
36694+ return err;
36695+}
36696+
7e9cd9fe
AM
36697+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
36698+ unsigned int verbose)
c1595e42
JR
36699+{
36700+ int err, unlocked, acl_access, acl_default;
36701+ ssize_t ssz;
36702+ struct inode *h_isrc, *h_idst;
36703+ char *value, *p, *o, *e;
36704+
36705+ /* try stopping to update the source inode while we are referencing */
7e9cd9fe 36706+ /* there should not be the parent-child relationship between them */
5527c038
JR
36707+ h_isrc = d_inode(h_src);
36708+ h_idst = d_inode(h_dst);
febd17d6 36709+ inode_unlock(h_idst);
be118d29 36710+ inode_lock_shared_nested(h_isrc, AuLsc_I_CHILD);
febd17d6 36711+ inode_lock_nested(h_idst, AuLsc_I_CHILD2);
c1595e42
JR
36712+ unlocked = 0;
36713+
36714+ /* some filesystems don't list POSIX ACL, for example tmpfs */
36715+ ssz = vfs_listxattr(h_src, NULL, 0);
36716+ err = ssz;
36717+ if (unlikely(err < 0)) {
36718+ AuTraceErr(err);
36719+ if (err == -ENODATA
36720+ || err == -EOPNOTSUPP)
36721+ err = 0; /* ignore */
36722+ goto out;
36723+ }
36724+
36725+ err = 0;
36726+ p = NULL;
36727+ o = NULL;
36728+ if (ssz) {
36729+ err = -ENOMEM;
36730+ p = kmalloc(ssz, GFP_NOFS);
36731+ o = p;
36732+ if (unlikely(!p))
36733+ goto out;
36734+ err = vfs_listxattr(h_src, p, ssz);
36735+ }
3c1bdaff 36736+ inode_unlock_shared(h_isrc);
c1595e42
JR
36737+ unlocked = 1;
36738+ AuDbg("err %d, ssz %zd\n", err, ssz);
36739+ if (unlikely(err < 0))
36740+ goto out_free;
36741+
36742+ err = 0;
36743+ e = p + ssz;
36744+ value = NULL;
36745+ acl_access = 0;
36746+ acl_default = 0;
36747+ while (!err && p < e) {
36748+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
36749+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
36750+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
36751+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
36752+ - 1);
7e9cd9fe
AM
36753+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags,
36754+ verbose);
c1595e42
JR
36755+ p += strlen(p) + 1;
36756+ }
36757+ AuTraceErr(err);
36758+ ignore_flags |= au_xattr_out_of_list;
36759+ if (!err && !acl_access) {
36760+ err = au_do_cpup_xattr(h_dst, h_src,
36761+ XATTR_NAME_POSIX_ACL_ACCESS, &value,
7e9cd9fe 36762+ ignore_flags, verbose);
c1595e42
JR
36763+ AuTraceErr(err);
36764+ }
36765+ if (!err && !acl_default) {
36766+ err = au_do_cpup_xattr(h_dst, h_src,
36767+ XATTR_NAME_POSIX_ACL_DEFAULT, &value,
7e9cd9fe 36768+ ignore_flags, verbose);
c1595e42
JR
36769+ AuTraceErr(err);
36770+ }
36771+
9f237c51 36772+ au_kfree_try_rcu(value);
c1595e42
JR
36773+
36774+out_free:
9f237c51 36775+ au_kfree_try_rcu(o);
c1595e42
JR
36776+out:
36777+ if (!unlocked)
3c1bdaff 36778+ inode_unlock_shared(h_isrc);
c1595e42
JR
36779+ AuTraceErr(err);
36780+ return err;
36781+}
36782+
36783+/* ---------------------------------------------------------------------- */
36784+
a2654f78
AM
36785+static int au_smack_reentering(struct super_block *sb)
36786+{
36787+#if IS_ENABLED(CONFIG_SECURITY_SMACK)
36788+ /*
36789+ * as a part of lookup, smack_d_instantiate() is called, and it calls
36790+ * i_op->getxattr(). ouch.
36791+ */
36792+ return si_pid_test(sb);
36793+#else
36794+ return 0;
36795+#endif
36796+}
36797+
c1595e42
JR
36798+enum {
36799+ AU_XATTR_LIST,
36800+ AU_XATTR_GET
36801+};
36802+
36803+struct au_lgxattr {
36804+ int type;
36805+ union {
36806+ struct {
36807+ char *list;
36808+ size_t size;
36809+ } list;
36810+ struct {
36811+ const char *name;
36812+ void *value;
36813+ size_t size;
36814+ } get;
36815+ } u;
36816+};
36817+
36818+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
36819+{
36820+ ssize_t err;
a2654f78 36821+ int reenter;
c1595e42
JR
36822+ struct path h_path;
36823+ struct super_block *sb;
36824+
36825+ sb = dentry->d_sb;
a2654f78
AM
36826+ reenter = au_smack_reentering(sb);
36827+ if (!reenter) {
36828+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
36829+ if (unlikely(err))
36830+ goto out;
36831+ }
36832+ err = au_h_path_getattr(dentry, /*force*/1, &h_path, reenter);
c1595e42
JR
36833+ if (unlikely(err))
36834+ goto out_si;
36835+ if (unlikely(!h_path.dentry))
36836+ /* illegally overlapped or something */
36837+ goto out_di; /* pretending success */
36838+
36839+ /* always topmost entry only */
36840+ switch (arg->type) {
36841+ case AU_XATTR_LIST:
36842+ err = vfs_listxattr(h_path.dentry,
36843+ arg->u.list.list, arg->u.list.size);
36844+ break;
36845+ case AU_XATTR_GET:
5afbbe0d 36846+ AuDebugOn(d_is_negative(h_path.dentry));
c1595e42
JR
36847+ err = vfs_getxattr(h_path.dentry,
36848+ arg->u.get.name, arg->u.get.value,
36849+ arg->u.get.size);
36850+ break;
36851+ }
36852+
36853+out_di:
a2654f78
AM
36854+ if (!reenter)
36855+ di_read_unlock(dentry, AuLock_IR);
c1595e42 36856+out_si:
a2654f78
AM
36857+ if (!reenter)
36858+ si_read_unlock(sb);
c1595e42
JR
36859+out:
36860+ AuTraceErr(err);
36861+ return err;
36862+}
36863+
36864+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
36865+{
36866+ struct au_lgxattr arg = {
36867+ .type = AU_XATTR_LIST,
36868+ .u.list = {
36869+ .list = list,
36870+ .size = size
36871+ },
36872+ };
36873+
36874+ return au_lgxattr(dentry, &arg);
36875+}
36876+
f2c43d5f
AM
36877+static ssize_t au_getxattr(struct dentry *dentry,
36878+ struct inode *inode __maybe_unused,
36879+ const char *name, void *value, size_t size)
c1595e42
JR
36880+{
36881+ struct au_lgxattr arg = {
36882+ .type = AU_XATTR_GET,
36883+ .u.get = {
36884+ .name = name,
36885+ .value = value,
36886+ .size = size
36887+ },
36888+ };
36889+
36890+ return au_lgxattr(dentry, &arg);
36891+}
36892+
f2c43d5f
AM
36893+static int au_setxattr(struct dentry *dentry, struct inode *inode,
36894+ const char *name, const void *value, size_t size,
36895+ int flags)
c1595e42 36896+{
f2c43d5f 36897+ struct au_sxattr arg = {
c1595e42
JR
36898+ .type = AU_XATTR_SET,
36899+ .u.set = {
36900+ .name = name,
36901+ .value = value,
36902+ .size = size,
36903+ .flags = flags
36904+ },
36905+ };
36906+
f2c43d5f 36907+ return au_sxattr(dentry, inode, &arg);
c1595e42
JR
36908+}
36909+
36910+/* ---------------------------------------------------------------------- */
36911+
f2c43d5f
AM
36912+static int au_xattr_get(const struct xattr_handler *handler,
36913+ struct dentry *dentry, struct inode *inode,
36914+ const char *name, void *buffer, size_t size)
c1595e42 36915+{
f2c43d5f 36916+ return au_getxattr(dentry, inode, name, buffer, size);
c1595e42
JR
36917+}
36918+
f2c43d5f
AM
36919+static int au_xattr_set(const struct xattr_handler *handler,
36920+ struct dentry *dentry, struct inode *inode,
36921+ const char *name, const void *value, size_t size,
36922+ int flags)
c1595e42 36923+{
f2c43d5f 36924+ return au_setxattr(dentry, inode, name, value, size, flags);
c1595e42
JR
36925+}
36926+
36927+static const struct xattr_handler au_xattr_handler = {
f2c43d5f
AM
36928+ .name = "",
36929+ .prefix = "",
c1595e42
JR
36930+ .get = au_xattr_get,
36931+ .set = au_xattr_set
c1595e42
JR
36932+};
36933+
36934+static const struct xattr_handler *au_xattr_handlers[] = {
a2654f78
AM
36935+#ifdef CONFIG_FS_POSIX_ACL
36936+ &posix_acl_access_xattr_handler,
36937+ &posix_acl_default_xattr_handler,
36938+#endif
36939+ &au_xattr_handler, /* must be last */
f2c43d5f 36940+ NULL
c1595e42
JR
36941+};
36942+
36943+void au_xattr_init(struct super_block *sb)
36944+{
f2c43d5f 36945+ sb->s_xattr = au_xattr_handlers;
c1595e42 36946+}
7f207e10
AM
36947diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
36948--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
ba1aed25 36949+++ linux/fs/aufs/xino.c 2019-03-05 12:13:00.145891204 +0100
9f237c51 36950@@ -0,0 +1,1956 @@
cd7a4cd9 36951+// SPDX-License-Identifier: GPL-2.0
1facf9fc 36952+/*
ba1aed25 36953+ * Copyright (C) 2005-2019 Junjiro R. Okajima
1facf9fc 36954+ *
36955+ * This program, aufs is free software; you can redistribute it and/or modify
36956+ * it under the terms of the GNU General Public License as published by
36957+ * the Free Software Foundation; either version 2 of the License, or
36958+ * (at your option) any later version.
dece6358
AM
36959+ *
36960+ * This program is distributed in the hope that it will be useful,
36961+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36962+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36963+ * GNU General Public License for more details.
36964+ *
36965+ * You should have received a copy of the GNU General Public License
523b37e3 36966+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 36967+ */
36968+
36969+/*
36970+ * external inode number translation table and bitmap
062440b3
AM
36971+ *
36972+ * things to consider
36973+ * - the lifetime
36974+ * + au_xino object
36975+ * + XINO files (xino, xib, xigen)
36976+ * + dynamic debugfs entries (xiN)
36977+ * + static debugfs entries (xib, xigen)
36978+ * + static sysfs entry (xi_path)
36979+ * - several entry points to handle them.
36980+ * + mount(2) without xino option (default)
36981+ * + mount(2) with xino option
36982+ * + mount(2) with noxino option
36983+ * + umount(2)
36984+ * + remount with add/del branches
36985+ * + remount with xino/noxino options
1facf9fc 36986+ */
36987+
36988+#include <linux/seq_file.h>
392086de 36989+#include <linux/statfs.h>
1facf9fc 36990+#include "aufs.h"
36991+
062440b3
AM
36992+static aufs_bindex_t sbr_find_shared(struct super_block *sb, aufs_bindex_t btop,
36993+ aufs_bindex_t bbot,
36994+ struct super_block *h_sb)
1facf9fc 36995+{
062440b3
AM
36996+ /* todo: try binary-search if the branches are many */
36997+ for (; btop <= bbot; btop++)
36998+ if (h_sb == au_sbr_sb(sb, btop))
36999+ return btop;
37000+ return -1;
be52b249
AM
37001+}
37002+
062440b3
AM
37003+/*
37004+ * find another branch who is on the same filesystem of the specified
37005+ * branch{@btgt}. search until @bbot.
37006+ */
37007+static aufs_bindex_t is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
37008+ aufs_bindex_t bbot)
1facf9fc 37009+{
062440b3
AM
37010+ aufs_bindex_t bindex;
37011+ struct super_block *tgt_sb;
1facf9fc 37012+
062440b3
AM
37013+ tgt_sb = au_sbr_sb(sb, btgt);
37014+ bindex = sbr_find_shared(sb, /*btop*/0, btgt - 1, tgt_sb);
37015+ if (bindex < 0)
37016+ bindex = sbr_find_shared(sb, btgt + 1, bbot, tgt_sb);
1facf9fc 37017+
062440b3 37018+ return bindex;
1facf9fc 37019+}
37020+
37021+/* ---------------------------------------------------------------------- */
37022+
37023+/*
062440b3 37024+ * stop unnecessary notify events at creating xino files
1facf9fc 37025+ */
acd2b654
AM
37026+
37027+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry)
37028+{
37029+ aufs_bindex_t bfound, bindex, bbot;
37030+ struct dentry *parent;
37031+ struct au_branch *br;
37032+
37033+ bfound = -1;
37034+ parent = dentry->d_parent; /* safe d_parent access */
37035+ bbot = au_sbbot(sb);
37036+ for (bindex = 0; bindex <= bbot; bindex++) {
37037+ br = au_sbr(sb, bindex);
37038+ if (au_br_dentry(br) == parent) {
37039+ bfound = bindex;
37040+ break;
37041+ }
37042+ }
37043+
37044+ AuDbg("bfound b%d\n", bfound);
37045+ return bfound;
37046+}
37047+
062440b3
AM
37048+struct au_xino_lock_dir {
37049+ struct au_hinode *hdir;
37050+ struct dentry *parent;
37051+ struct inode *dir;
37052+};
37053+
37054+static struct dentry *au_dget_parent_lock(struct dentry *dentry,
37055+ unsigned int lsc)
1facf9fc 37056+{
062440b3
AM
37057+ struct dentry *parent;
37058+ struct inode *dir;
1facf9fc 37059+
062440b3 37060+ parent = dget_parent(dentry);
5527c038 37061+ dir = d_inode(parent);
062440b3
AM
37062+ inode_lock_nested(dir, lsc);
37063+#if 0 /* it should not happen */
37064+ spin_lock(&dentry->d_lock);
37065+ if (unlikely(dentry->d_parent != parent)) {
37066+ spin_unlock(&dentry->d_lock);
37067+ inode_unlock(dir);
37068+ dput(parent);
37069+ parent = NULL;
1facf9fc 37070+ goto out;
37071+ }
062440b3 37072+ spin_unlock(&dentry->d_lock);
1facf9fc 37073+
4f0767ce 37074+out:
062440b3
AM
37075+#endif
37076+ return parent;
1facf9fc 37077+}
37078+
062440b3 37079+static void au_xino_lock_dir(struct super_block *sb, struct path *xipath,
1facf9fc 37080+ struct au_xino_lock_dir *ldir)
37081+{
acd2b654 37082+ aufs_bindex_t bindex;
1facf9fc 37083+
37084+ ldir->hdir = NULL;
acd2b654 37085+ bindex = au_xi_root(sb, xipath->dentry);
1facf9fc 37086+ if (bindex >= 0) {
062440b3 37087+ /* rw branch root */
5527c038 37088+ ldir->hdir = au_hi(d_inode(sb->s_root), bindex);
5afbbe0d 37089+ au_hn_inode_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 37090+ } else {
062440b3
AM
37091+ /* other */
37092+ ldir->parent = au_dget_parent_lock(xipath->dentry,
37093+ AuLsc_I_PARENT);
febd17d6 37094+ ldir->dir = d_inode(ldir->parent);
1facf9fc 37095+ }
37096+}
37097+
37098+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
37099+{
37100+ if (ldir->hdir)
5afbbe0d 37101+ au_hn_inode_unlock(ldir->hdir);
1facf9fc 37102+ else {
febd17d6 37103+ inode_unlock(ldir->dir);
1facf9fc 37104+ dput(ldir->parent);
37105+ }
37106+}
37107+
37108+/* ---------------------------------------------------------------------- */
37109+
062440b3
AM
37110+/*
37111+ * create and set a new xino file
37112+ */
37113+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent)
37114+{
37115+ struct file *file;
37116+ struct dentry *h_parent, *d;
37117+ struct inode *h_dir, *inode;
37118+ int err;
37119+
37120+ /*
37121+ * at mount-time, and the xino file is the default path,
37122+ * hnotify is disabled so we have no notify events to ignore.
37123+ * when a user specified the xino, we cannot get au_hdir to be ignored.
37124+ */
37125+ file = vfsub_filp_open(fpath, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
37126+ /* | __FMODE_NONOTIFY */,
cd7a4cd9 37127+ 0666);
062440b3
AM
37128+ if (IS_ERR(file)) {
37129+ if (!silent)
37130+ pr_err("open %s(%ld)\n", fpath, PTR_ERR(file));
37131+ return file;
37132+ }
37133+
37134+ /* keep file count */
37135+ err = 0;
37136+ d = file->f_path.dentry;
37137+ h_parent = au_dget_parent_lock(d, AuLsc_I_PARENT);
37138+ /* mnt_want_write() is unnecessary here */
37139+ h_dir = d_inode(h_parent);
37140+ inode = file_inode(file);
37141+ /* no delegation since it is just created */
37142+ if (inode->i_nlink)
37143+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL,
37144+ /*force*/0);
37145+ inode_unlock(h_dir);
37146+ dput(h_parent);
37147+ if (unlikely(err)) {
37148+ if (!silent)
37149+ pr_err("unlink %s(%d)\n", fpath, err);
37150+ goto out;
37151+ }
37152+
37153+ err = -EINVAL;
37154+ if (unlikely(sb == d->d_sb)) {
37155+ if (!silent)
37156+ pr_err("%s must be outside\n", fpath);
37157+ goto out;
37158+ }
37159+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
37160+ if (!silent)
37161+ pr_err("xino doesn't support %s(%s)\n",
37162+ fpath, au_sbtype(d->d_sb));
37163+ goto out;
37164+ }
37165+ return file; /* success */
37166+
37167+out:
37168+ fput(file);
37169+ file = ERR_PTR(err);
37170+ return file;
37171+}
37172+
37173+/*
37174+ * create a new xinofile at the same place/path as @base.
37175+ */
37176+struct file *au_xino_create2(struct super_block *sb, struct path *base,
37177+ struct file *copy_src)
37178+{
37179+ struct file *file;
37180+ struct dentry *dentry, *parent;
37181+ struct inode *dir, *delegated;
37182+ struct qstr *name;
37183+ struct path path;
37184+ int err, do_unlock;
37185+ struct au_xino_lock_dir ldir;
37186+
37187+ do_unlock = 1;
37188+ au_xino_lock_dir(sb, base, &ldir);
37189+ dentry = base->dentry;
37190+ parent = dentry->d_parent; /* dir inode is locked */
37191+ dir = d_inode(parent);
37192+ IMustLock(dir);
37193+
37194+ name = &dentry->d_name;
37195+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
37196+ if (IS_ERR(path.dentry)) {
37197+ file = (void *)path.dentry;
37198+ pr_err("%pd lookup err %ld\n", dentry, PTR_ERR(path.dentry));
37199+ goto out;
37200+ }
37201+
37202+ /* no need to mnt_want_write() since we call dentry_open() later */
cd7a4cd9 37203+ err = vfs_create(dir, path.dentry, 0666, NULL);
062440b3
AM
37204+ if (unlikely(err)) {
37205+ file = ERR_PTR(err);
37206+ pr_err("%pd create err %d\n", dentry, err);
37207+ goto out_dput;
37208+ }
37209+
37210+ path.mnt = base->mnt;
37211+ file = vfsub_dentry_open(&path,
37212+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
37213+ /* | __FMODE_NONOTIFY */);
37214+ if (IS_ERR(file)) {
37215+ pr_err("%pd open err %ld\n", dentry, PTR_ERR(file));
37216+ goto out_dput;
37217+ }
37218+
37219+ delegated = NULL;
37220+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
37221+ au_xino_unlock_dir(&ldir);
37222+ do_unlock = 0;
37223+ if (unlikely(err == -EWOULDBLOCK)) {
37224+ pr_warn("cannot retry for NFSv4 delegation"
37225+ " for an internal unlink\n");
37226+ iput(delegated);
37227+ }
37228+ if (unlikely(err)) {
37229+ pr_err("%pd unlink err %d\n", dentry, err);
37230+ goto out_fput;
37231+ }
37232+
37233+ if (copy_src) {
37234+ /* no one can touch copy_src xino */
37235+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
37236+ if (unlikely(err)) {
37237+ pr_err("%pd copy err %d\n", dentry, err);
37238+ goto out_fput;
37239+ }
37240+ }
37241+ goto out_dput; /* success */
1facf9fc 37242+
062440b3
AM
37243+out_fput:
37244+ fput(file);
37245+ file = ERR_PTR(err);
37246+out_dput:
37247+ dput(path.dentry);
37248+out:
37249+ if (do_unlock)
37250+ au_xino_unlock_dir(&ldir);
37251+ return file;
37252+}
37253+
acd2b654
AM
37254+struct file *au_xino_file1(struct au_xino *xi)
37255+{
37256+ struct file *file;
37257+ unsigned int u, nfile;
37258+
37259+ file = NULL;
37260+ nfile = xi->xi_nfile;
37261+ for (u = 0; u < nfile; u++) {
37262+ file = xi->xi_file[u];
37263+ if (file)
37264+ break;
37265+ }
37266+
37267+ return file;
37268+}
37269+
37270+static int au_xino_file_set(struct au_xino *xi, int idx, struct file *file)
37271+{
37272+ int err;
37273+ struct file *f;
37274+ void *p;
37275+
37276+ if (file)
37277+ get_file(file);
37278+
37279+ err = 0;
37280+ f = NULL;
37281+ if (idx < xi->xi_nfile) {
37282+ f = xi->xi_file[idx];
37283+ if (f)
37284+ fput(f);
37285+ } else {
37286+ p = au_kzrealloc(xi->xi_file,
37287+ sizeof(*xi->xi_file) * xi->xi_nfile,
37288+ sizeof(*xi->xi_file) * (idx + 1),
37289+ GFP_NOFS, /*may_shrink*/0);
37290+ if (p) {
37291+ MtxMustLock(&xi->xi_mtx);
37292+ xi->xi_file = p;
37293+ xi->xi_nfile = idx + 1;
37294+ } else {
37295+ err = -ENOMEM;
37296+ if (file)
37297+ fput(file);
37298+ goto out;
37299+ }
37300+ }
37301+ xi->xi_file[idx] = file;
37302+
37303+out:
37304+ return err;
37305+}
37306+
37307+/*
37308+ * if @xinew->xi is not set, then create new xigen file.
37309+ */
37310+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew)
37311+{
37312+ struct file *file;
37313+ int err;
37314+
37315+ SiMustAnyLock(sb);
37316+
37317+ file = au_xino_create2(sb, xinew->base, xinew->copy_src);
37318+ if (IS_ERR(file)) {
37319+ err = PTR_ERR(file);
37320+ pr_err("%s[%d], err %d\n",
37321+ xinew->xi ? "xino" : "xigen",
37322+ xinew->idx, err);
37323+ goto out;
37324+ }
37325+
37326+ if (xinew->xi)
37327+ err = au_xino_file_set(xinew->xi, xinew->idx, file);
37328+ else {
37329+ BUG();
37330+ /* todo: make xigen file an array */
37331+ /* err = au_xigen_file_set(sb, xinew->idx, file); */
37332+ }
37333+ fput(file);
37334+ if (unlikely(err))
37335+ file = ERR_PTR(err);
37336+
37337+out:
37338+ return file;
37339+}
37340+
062440b3
AM
37341+/* ---------------------------------------------------------------------- */
37342+
37343+/*
37344+ * truncate xino files
37345+ */
acd2b654
AM
37346+static int au_xino_do_trunc(struct super_block *sb, aufs_bindex_t bindex,
37347+ int idx, struct kstatfs *st)
1facf9fc 37348+{
37349+ int err;
392086de 37350+ blkcnt_t blocks;
acd2b654
AM
37351+ struct file *file, *new_xino;
37352+ struct au_xi_new xinew = {
37353+ .idx = idx
37354+ };
37355+
37356+ err = 0;
37357+ xinew.xi = au_sbr(sb, bindex)->br_xino;
37358+ file = au_xino_file(xinew.xi, idx);
37359+ if (!file)
37360+ goto out;
37361+
37362+ xinew.base = &file->f_path;
37363+ err = vfs_statfs(xinew.base, st);
37364+ if (unlikely(err)) {
37365+ AuErr1("statfs err %d, ignored\n", err);
37366+ err = 0;
37367+ goto out;
37368+ }
37369+
37370+ blocks = file_inode(file)->i_blocks;
37371+ pr_info("begin truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n",
37372+ bindex, idx, (u64)blocks, st->f_bfree, st->f_blocks);
37373+
37374+ xinew.copy_src = file;
37375+ new_xino = au_xi_new(sb, &xinew);
37376+ if (IS_ERR(new_xino)) {
37377+ err = PTR_ERR(new_xino);
37378+ pr_err("xino(b%d-%d), err %d, ignored\n", bindex, idx, err);
37379+ goto out;
37380+ }
37381+
37382+ err = vfs_statfs(&new_xino->f_path, st);
37383+ if (!err)
37384+ pr_info("end truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n",
37385+ bindex, idx, (u64)file_inode(new_xino)->i_blocks,
37386+ st->f_bfree, st->f_blocks);
37387+ else {
37388+ AuErr1("statfs err %d, ignored\n", err);
37389+ err = 0;
37390+ }
37391+
37392+out:
37393+ return err;
37394+}
37395+
37396+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin)
37397+{
37398+ int err, i;
37399+ unsigned long jiffy;
062440b3 37400+ aufs_bindex_t bbot;
392086de 37401+ struct kstatfs *st;
1facf9fc 37402+ struct au_branch *br;
acd2b654 37403+ struct au_xino *xi;
1facf9fc 37404+
392086de 37405+ err = -ENOMEM;
be52b249 37406+ st = kmalloc(sizeof(*st), GFP_NOFS);
392086de
AM
37407+ if (unlikely(!st))
37408+ goto out;
37409+
1facf9fc 37410+ err = -EINVAL;
5afbbe0d
AM
37411+ bbot = au_sbbot(sb);
37412+ if (unlikely(bindex < 0 || bbot < bindex))
392086de 37413+ goto out_st;
392086de 37414+
1facf9fc 37415+ err = 0;
acd2b654
AM
37416+ jiffy = jiffies;
37417+ br = au_sbr(sb, bindex);
37418+ xi = br->br_xino;
37419+ for (i = idx_begin; !err && i < xi->xi_nfile; i++)
37420+ err = au_xino_do_trunc(sb, bindex, i, st);
37421+ if (!err)
37422+ au_sbi(sb)->si_xino_jiffy = jiffy;
392086de
AM
37423+
37424+out_st:
9f237c51 37425+ au_kfree_rcu(st);
4f0767ce 37426+out:
1facf9fc 37427+ return err;
37428+}
37429+
37430+struct xino_do_trunc_args {
37431+ struct super_block *sb;
37432+ struct au_branch *br;
acd2b654 37433+ int idx;
1facf9fc 37434+};
37435+
37436+static void xino_do_trunc(void *_args)
37437+{
37438+ struct xino_do_trunc_args *args = _args;
37439+ struct super_block *sb;
37440+ struct au_branch *br;
37441+ struct inode *dir;
acd2b654 37442+ int err, idx;
1facf9fc 37443+ aufs_bindex_t bindex;
37444+
37445+ err = 0;
37446+ sb = args->sb;
5527c038 37447+ dir = d_inode(sb->s_root);
1facf9fc 37448+ br = args->br;
acd2b654 37449+ idx = args->idx;
1facf9fc 37450+
37451+ si_noflush_write_lock(sb);
37452+ ii_read_lock_parent(dir);
37453+ bindex = au_br_index(sb, br->br_id);
acd2b654 37454+ err = au_xino_trunc(sb, bindex, idx);
1facf9fc 37455+ ii_read_unlock(dir);
37456+ if (unlikely(err))
392086de 37457+ pr_warn("err b%d, (%d)\n", bindex, err);
062440b3 37458+ atomic_dec(&br->br_xino->xi_truncating);
acd2b654 37459+ au_lcnt_dec(&br->br_count);
1facf9fc 37460+ si_write_unlock(sb);
027c5e7a 37461+ au_nwt_done(&au_sbi(sb)->si_nowait);
9f237c51 37462+ au_kfree_rcu(args);
1facf9fc 37463+}
37464+
acd2b654
AM
37465+/*
37466+ * returns the index in the xi_file array whose corresponding file is necessary
37467+ * to truncate, or -1 which means no need to truncate.
37468+ */
392086de
AM
37469+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
37470+{
37471+ int err;
acd2b654 37472+ unsigned int u;
392086de
AM
37473+ struct kstatfs st;
37474+ struct au_sbinfo *sbinfo;
acd2b654 37475+ struct au_xino *xi;
062440b3 37476+ struct file *file;
392086de
AM
37477+
37478+ /* todo: si_xino_expire and the ratio should be customizable */
37479+ sbinfo = au_sbi(sb);
37480+ if (time_before(jiffies,
37481+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
acd2b654 37482+ return -1;
392086de
AM
37483+
37484+ /* truncation border */
acd2b654
AM
37485+ xi = br->br_xino;
37486+ for (u = 0; u < xi->xi_nfile; u++) {
37487+ file = au_xino_file(xi, u);
37488+ if (!file)
37489+ continue;
37490+
37491+ err = vfs_statfs(&file->f_path, &st);
37492+ if (unlikely(err)) {
37493+ AuErr1("statfs err %d, ignored\n", err);
37494+ return -1;
37495+ }
37496+ if (div64_u64(st.f_bfree * 100, st.f_blocks)
37497+ >= AUFS_XINO_DEF_TRUNC)
37498+ return u;
392086de 37499+ }
392086de 37500+
acd2b654 37501+ return -1;
392086de
AM
37502+}
37503+
1facf9fc 37504+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
37505+{
acd2b654 37506+ int idx;
1facf9fc 37507+ struct xino_do_trunc_args *args;
37508+ int wkq_err;
37509+
acd2b654
AM
37510+ idx = xino_trunc_test(sb, br);
37511+ if (idx < 0)
1facf9fc 37512+ return;
37513+
062440b3 37514+ if (atomic_inc_return(&br->br_xino->xi_truncating) > 1)
1facf9fc 37515+ goto out;
37516+
37517+ /* lock and kfree() will be called in trunc_xino() */
37518+ args = kmalloc(sizeof(*args), GFP_NOFS);
37519+ if (unlikely(!args)) {
37520+ AuErr1("no memory\n");
f0c0a007 37521+ goto out;
1facf9fc 37522+ }
37523+
acd2b654 37524+ au_lcnt_inc(&br->br_count);
1facf9fc 37525+ args->sb = sb;
37526+ args->br = br;
acd2b654 37527+ args->idx = idx;
53392da6 37528+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 37529+ if (!wkq_err)
37530+ return; /* success */
37531+
4a4d8108 37532+ pr_err("wkq %d\n", wkq_err);
acd2b654 37533+ au_lcnt_dec(&br->br_count);
9f237c51 37534+ au_kfree_rcu(args);
1facf9fc 37535+
4f0767ce 37536+out:
062440b3 37537+ atomic_dec(&br->br_xino->xi_truncating);
1facf9fc 37538+}
37539+
37540+/* ---------------------------------------------------------------------- */
37541+
acd2b654
AM
37542+struct au_xi_calc {
37543+ int idx;
37544+ loff_t pos;
37545+};
37546+
37547+static void au_xi_calc(struct super_block *sb, ino_t h_ino,
37548+ struct au_xi_calc *calc)
37549+{
37550+ loff_t maxent;
37551+
37552+ maxent = au_xi_maxent(sb);
37553+ calc->idx = div64_u64_rem(h_ino, maxent, &calc->pos);
37554+ calc->pos *= sizeof(ino_t);
37555+}
37556+
37557+static int au_xino_do_new_async(struct super_block *sb, struct au_branch *br,
37558+ struct au_xi_calc *calc)
37559+{
37560+ int err;
37561+ struct file *file;
37562+ struct au_xino *xi = br->br_xino;
37563+ struct au_xi_new xinew = {
37564+ .xi = xi
37565+ };
37566+
37567+ SiMustAnyLock(sb);
37568+
37569+ err = 0;
37570+ if (!xi)
37571+ goto out;
37572+
37573+ mutex_lock(&xi->xi_mtx);
37574+ file = au_xino_file(xi, calc->idx);
37575+ if (file)
37576+ goto out_mtx;
37577+
37578+ file = au_xino_file(xi, /*idx*/-1);
37579+ AuDebugOn(!file);
37580+ xinew.idx = calc->idx;
37581+ xinew.base = &file->f_path;
37582+ /* xinew.copy_src = NULL; */
37583+ file = au_xi_new(sb, &xinew);
37584+ if (IS_ERR(file))
37585+ err = PTR_ERR(file);
37586+
37587+out_mtx:
37588+ mutex_unlock(&xi->xi_mtx);
37589+out:
37590+ return err;
37591+}
37592+
37593+struct au_xino_do_new_async_args {
37594+ struct super_block *sb;
37595+ struct au_branch *br;
37596+ struct au_xi_calc calc;
37597+ ino_t ino;
37598+};
37599+
9f237c51
AM
37600+struct au_xi_writing {
37601+ struct hlist_bl_node node;
37602+ ino_t h_ino, ino;
37603+};
37604+
acd2b654
AM
37605+static int au_xino_do_write(vfs_writef_t write, struct file *file,
37606+ struct au_xi_calc *calc, ino_t ino);
37607+
37608+static void au_xino_call_do_new_async(void *args)
37609+{
37610+ struct au_xino_do_new_async_args *a = args;
37611+ struct au_branch *br;
37612+ struct super_block *sb;
37613+ struct au_sbinfo *sbi;
37614+ struct inode *root;
37615+ struct file *file;
9f237c51
AM
37616+ struct au_xi_writing *del, *p;
37617+ struct hlist_bl_head *hbl;
37618+ struct hlist_bl_node *pos;
acd2b654
AM
37619+ int err;
37620+
37621+ br = a->br;
37622+ sb = a->sb;
37623+ sbi = au_sbi(sb);
37624+ si_noflush_read_lock(sb);
37625+ root = d_inode(sb->s_root);
37626+ ii_read_lock_child(root);
37627+ err = au_xino_do_new_async(sb, br, &a->calc);
9f237c51
AM
37628+ if (unlikely(err)) {
37629+ AuIOErr("err %d\n", err);
37630+ goto out;
37631+ }
37632+
37633+ file = au_xino_file(br->br_xino, a->calc.idx);
37634+ AuDebugOn(!file);
37635+ err = au_xino_do_write(sbi->si_xwrite, file, &a->calc, a->ino);
37636+ if (unlikely(err)) {
acd2b654 37637+ AuIOErr("err %d\n", err);
9f237c51
AM
37638+ goto out;
37639+ }
37640+
37641+ del = NULL;
37642+ hbl = &br->br_xino->xi_writing;
37643+ hlist_bl_lock(hbl);
37644+ au_hbl_for_each(pos, hbl) {
37645+ p = container_of(pos, struct au_xi_writing, node);
37646+ if (p->ino == a->ino) {
37647+ del = p;
37648+ hlist_bl_del(&p->node);
37649+ break;
37650+ }
37651+ }
37652+ hlist_bl_unlock(hbl);
37653+ au_kfree_rcu(del);
37654+
37655+out:
acd2b654
AM
37656+ au_lcnt_dec(&br->br_count);
37657+ ii_read_unlock(root);
37658+ si_read_unlock(sb);
37659+ au_nwt_done(&sbi->si_nowait);
9f237c51 37660+ au_kfree_rcu(a);
acd2b654
AM
37661+}
37662+
37663+/*
37664+ * create a new xino file asynchronously
37665+ */
37666+static int au_xino_new_async(struct super_block *sb, struct au_branch *br,
37667+ struct au_xi_calc *calc, ino_t ino)
37668+{
37669+ int err;
37670+ struct au_xino_do_new_async_args *arg;
37671+
37672+ err = -ENOMEM;
37673+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
37674+ if (unlikely(!arg))
37675+ goto out;
37676+
37677+ arg->sb = sb;
37678+ arg->br = br;
37679+ arg->calc = *calc;
37680+ arg->ino = ino;
37681+ au_lcnt_inc(&br->br_count);
37682+ err = au_wkq_nowait(au_xino_call_do_new_async, arg, sb, AuWkq_NEST);
37683+ if (unlikely(err)) {
37684+ pr_err("wkq %d\n", err);
37685+ au_lcnt_dec(&br->br_count);
9f237c51 37686+ au_kfree_rcu(arg);
acd2b654
AM
37687+ }
37688+
37689+out:
37690+ return err;
37691+}
37692+
062440b3
AM
37693+/*
37694+ * read @ino from xinofile for the specified branch{@sb, @bindex}
37695+ * at the position of @h_ino.
37696+ */
37697+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
37698+ ino_t *ino)
37699+{
37700+ int err;
37701+ ssize_t sz;
acd2b654 37702+ struct au_xi_calc calc;
062440b3 37703+ struct au_sbinfo *sbinfo;
acd2b654 37704+ struct file *file;
9f237c51
AM
37705+ struct au_xino *xi;
37706+ struct hlist_bl_head *hbl;
37707+ struct hlist_bl_node *pos;
37708+ struct au_xi_writing *p;
062440b3
AM
37709+
37710+ *ino = 0;
37711+ if (!au_opt_test(au_mntflags(sb), XINO))
37712+ return 0; /* no xino */
37713+
37714+ err = 0;
acd2b654 37715+ au_xi_calc(sb, h_ino, &calc);
9f237c51
AM
37716+ xi = au_sbr(sb, bindex)->br_xino;
37717+ file = au_xino_file(xi, calc.idx);
37718+ if (!file) {
37719+ hbl = &xi->xi_writing;
37720+ hlist_bl_lock(hbl);
37721+ au_hbl_for_each(pos, hbl) {
37722+ p = container_of(pos, struct au_xi_writing, node);
37723+ if (p->h_ino == h_ino) {
37724+ AuDbg("hi%llu, i%llu, found\n",
37725+ (u64)p->h_ino, (u64)p->ino);
37726+ *ino = p->ino;
37727+ break;
37728+ }
37729+ }
37730+ hlist_bl_unlock(hbl);
37731+ return 0;
37732+ } else if (vfsub_f_size_read(file) < calc.pos + sizeof(*ino))
37733+ return 0; /* no xino */
062440b3 37734+
acd2b654
AM
37735+ sbinfo = au_sbi(sb);
37736+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &calc.pos);
062440b3
AM
37737+ if (sz == sizeof(*ino))
37738+ return 0; /* success */
37739+
37740+ err = sz;
37741+ if (unlikely(sz >= 0)) {
37742+ err = -EIO;
37743+ AuIOErr("xino read error (%zd)\n", sz);
37744+ }
062440b3
AM
37745+ return err;
37746+}
37747+
5527c038 37748+static int au_xino_do_write(vfs_writef_t write, struct file *file,
acd2b654 37749+ struct au_xi_calc *calc, ino_t ino)
1facf9fc 37750+{
1facf9fc 37751+ ssize_t sz;
37752+
acd2b654 37753+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &calc->pos);
1facf9fc 37754+ if (sz == sizeof(ino))
37755+ return 0; /* success */
37756+
37757+ AuIOErr("write failed (%zd)\n", sz);
37758+ return -EIO;
37759+}
37760+
37761+/*
37762+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
37763+ * at the position of @h_ino.
37764+ * even if @ino is zero, it is written to the xinofile and means no entry.
37765+ * if the size of the xino file on a specific filesystem exceeds the watermark,
37766+ * try truncating it.
37767+ */
37768+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
37769+ ino_t ino)
37770+{
37771+ int err;
37772+ unsigned int mnt_flags;
acd2b654
AM
37773+ struct au_xi_calc calc;
37774+ struct file *file;
1facf9fc 37775+ struct au_branch *br;
acd2b654 37776+ struct au_xino *xi;
9f237c51 37777+ struct au_xi_writing *p;
1facf9fc 37778+
dece6358 37779+ SiMustAnyLock(sb);
1facf9fc 37780+
37781+ mnt_flags = au_mntflags(sb);
37782+ if (!au_opt_test(mnt_flags, XINO))
37783+ return 0;
37784+
acd2b654 37785+ au_xi_calc(sb, h_ino, &calc);
1facf9fc 37786+ br = au_sbr(sb, bindex);
acd2b654
AM
37787+ xi = br->br_xino;
37788+ file = au_xino_file(xi, calc.idx);
37789+ if (!file) {
9f237c51
AM
37790+ /* store the inum pair into the list */
37791+ p = kmalloc(sizeof(*p), GFP_NOFS | __GFP_NOFAIL);
37792+ p->h_ino = h_ino;
37793+ p->ino = ino;
37794+ au_hbl_add(&p->node, &xi->xi_writing);
37795+
acd2b654
AM
37796+ /* create and write a new xino file asynchronously */
37797+ err = au_xino_new_async(sb, br, &calc, ino);
37798+ if (!err)
37799+ return 0; /* success */
37800+ goto out;
37801+ }
37802+
37803+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, file, &calc, ino);
1facf9fc 37804+ if (!err) {
acd2b654 37805+ br = au_sbr(sb, bindex);
1facf9fc 37806+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 37807+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 37808+ xino_try_trunc(sb, br);
37809+ return 0; /* success */
37810+ }
37811+
acd2b654 37812+out:
1facf9fc 37813+ AuIOErr("write failed (%d)\n", err);
37814+ return -EIO;
37815+}
37816+
062440b3
AM
37817+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf,
37818+ size_t size, loff_t *pos);
1facf9fc 37819+
062440b3
AM
37820+/* todo: unnecessary to support mmap_sem since kernel-space? */
37821+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size,
37822+ loff_t *pos)
37823+{
37824+ ssize_t err;
37825+ mm_segment_t oldfs;
37826+ union {
37827+ void *k;
37828+ char __user *u;
37829+ } buf;
37830+ int i;
37831+ const int prevent_endless = 10;
1facf9fc 37832+
062440b3
AM
37833+ i = 0;
37834+ buf.k = kbuf;
37835+ oldfs = get_fs();
37836+ set_fs(KERNEL_DS);
37837+ do {
37838+ err = func(file, buf.u, size, pos);
37839+ if (err == -EINTR
37840+ && !au_wkq_test()
37841+ && fatal_signal_pending(current)) {
37842+ set_fs(oldfs);
37843+ err = xino_fread_wkq(func, file, kbuf, size, pos);
37844+ BUG_ON(err == -EINTR);
37845+ oldfs = get_fs();
37846+ set_fs(KERNEL_DS);
37847+ }
37848+ } while (i++ < prevent_endless
37849+ && (err == -EAGAIN || err == -EINTR));
37850+ set_fs(oldfs);
37851+
37852+#if 0 /* reserved for future use */
37853+ if (err > 0)
37854+ fsnotify_access(file->f_path.dentry);
37855+#endif
37856+
37857+ return err;
37858+}
37859+
37860+struct xino_fread_args {
37861+ ssize_t *errp;
37862+ vfs_readf_t func;
37863+ struct file *file;
37864+ void *buf;
37865+ size_t size;
37866+ loff_t *pos;
37867+};
37868+
37869+static void call_xino_fread(void *args)
37870+{
37871+ struct xino_fread_args *a = args;
37872+ *a->errp = xino_fread(a->func, a->file, a->buf, a->size, a->pos);
37873+}
37874+
37875+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf,
37876+ size_t size, loff_t *pos)
37877+{
37878+ ssize_t err;
37879+ int wkq_err;
37880+ struct xino_fread_args args = {
37881+ .errp = &err,
37882+ .func = func,
37883+ .file = file,
37884+ .buf = buf,
37885+ .size = size,
37886+ .pos = pos
37887+ };
37888+
37889+ wkq_err = au_wkq_wait(call_xino_fread, &args);
37890+ if (unlikely(wkq_err))
37891+ err = wkq_err;
37892+
37893+ return err;
37894+}
37895+
37896+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
37897+ size_t size, loff_t *pos);
37898+
37899+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf,
37900+ size_t size, loff_t *pos)
37901+{
37902+ ssize_t err;
37903+ mm_segment_t oldfs;
37904+ union {
37905+ void *k;
37906+ const char __user *u;
37907+ } buf;
37908+ int i;
37909+ const int prevent_endless = 10;
37910+
37911+ i = 0;
37912+ buf.k = kbuf;
37913+ oldfs = get_fs();
37914+ set_fs(KERNEL_DS);
37915+ do {
37916+ err = func(file, buf.u, size, pos);
37917+ if (err == -EINTR
37918+ && !au_wkq_test()
37919+ && fatal_signal_pending(current)) {
37920+ set_fs(oldfs);
37921+ err = xino_fwrite_wkq(func, file, kbuf, size, pos);
37922+ BUG_ON(err == -EINTR);
37923+ oldfs = get_fs();
37924+ set_fs(KERNEL_DS);
37925+ }
37926+ } while (i++ < prevent_endless
37927+ && (err == -EAGAIN || err == -EINTR));
37928+ set_fs(oldfs);
37929+
37930+#if 0 /* reserved for future use */
37931+ if (err > 0)
37932+ fsnotify_modify(file->f_path.dentry);
37933+#endif
37934+
37935+ return err;
37936+}
37937+
37938+struct do_xino_fwrite_args {
37939+ ssize_t *errp;
37940+ vfs_writef_t func;
37941+ struct file *file;
37942+ void *buf;
37943+ size_t size;
37944+ loff_t *pos;
37945+};
37946+
37947+static void call_do_xino_fwrite(void *args)
37948+{
37949+ struct do_xino_fwrite_args *a = args;
37950+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
37951+}
37952+
37953+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
37954+ size_t size, loff_t *pos)
37955+{
37956+ ssize_t err;
37957+ int wkq_err;
37958+ struct do_xino_fwrite_args args = {
37959+ .errp = &err,
37960+ .func = func,
37961+ .file = file,
37962+ .buf = buf,
37963+ .size = size,
37964+ .pos = pos
37965+ };
37966+
37967+ /*
37968+ * it breaks RLIMIT_FSIZE and normal user's limit,
37969+ * users should care about quota and real 'filesystem full.'
37970+ */
37971+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
37972+ if (unlikely(wkq_err))
37973+ err = wkq_err;
37974+
37975+ return err;
37976+}
37977+
37978+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
37979+ size_t size, loff_t *pos)
37980+{
37981+ ssize_t err;
37982+
37983+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
37984+ lockdep_off();
37985+ err = do_xino_fwrite(func, file, buf, size, pos);
37986+ lockdep_on();
37987+ } else {
37988+ lockdep_off();
37989+ err = xino_fwrite_wkq(func, file, buf, size, pos);
37990+ lockdep_on();
37991+ }
37992+
37993+ return err;
37994+}
37995+
37996+/* ---------------------------------------------------------------------- */
37997+
37998+/*
37999+ * inode number bitmap
38000+ */
1facf9fc 38001+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
38002+static ino_t xib_calc_ino(unsigned long pindex, int bit)
38003+{
38004+ ino_t ino;
38005+
38006+ AuDebugOn(bit < 0 || page_bits <= bit);
38007+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
38008+ return ino;
38009+}
38010+
38011+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
38012+{
38013+ AuDebugOn(ino < AUFS_FIRST_INO);
38014+ ino -= AUFS_FIRST_INO;
38015+ *pindex = ino / page_bits;
38016+ *bit = ino % page_bits;
38017+}
38018+
38019+static int xib_pindex(struct super_block *sb, unsigned long pindex)
38020+{
38021+ int err;
38022+ loff_t pos;
38023+ ssize_t sz;
38024+ struct au_sbinfo *sbinfo;
38025+ struct file *xib;
38026+ unsigned long *p;
38027+
38028+ sbinfo = au_sbi(sb);
38029+ MtxMustLock(&sbinfo->si_xib_mtx);
38030+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
38031+ || !au_opt_test(sbinfo->si_mntflags, XINO));
38032+
38033+ if (pindex == sbinfo->si_xib_last_pindex)
38034+ return 0;
38035+
38036+ xib = sbinfo->si_xib;
38037+ p = sbinfo->si_xib_buf;
38038+ pos = sbinfo->si_xib_last_pindex;
38039+ pos *= PAGE_SIZE;
38040+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
38041+ if (unlikely(sz != PAGE_SIZE))
38042+ goto out;
38043+
38044+ pos = pindex;
38045+ pos *= PAGE_SIZE;
c06a8ce3 38046+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 38047+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
38048+ else {
38049+ memset(p, 0, PAGE_SIZE);
38050+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
38051+ }
38052+ if (sz == PAGE_SIZE) {
38053+ sbinfo->si_xib_last_pindex = pindex;
38054+ return 0; /* success */
38055+ }
38056+
4f0767ce 38057+out:
b752ccd1
AM
38058+ AuIOErr1("write failed (%zd)\n", sz);
38059+ err = sz;
38060+ if (sz >= 0)
38061+ err = -EIO;
38062+ return err;
38063+}
38064+
b752ccd1
AM
38065+static void au_xib_clear_bit(struct inode *inode)
38066+{
38067+ int err, bit;
38068+ unsigned long pindex;
38069+ struct super_block *sb;
38070+ struct au_sbinfo *sbinfo;
38071+
38072+ AuDebugOn(inode->i_nlink);
38073+
38074+ sb = inode->i_sb;
38075+ xib_calc_bit(inode->i_ino, &pindex, &bit);
38076+ AuDebugOn(page_bits <= bit);
38077+ sbinfo = au_sbi(sb);
38078+ mutex_lock(&sbinfo->si_xib_mtx);
38079+ err = xib_pindex(sb, pindex);
38080+ if (!err) {
38081+ clear_bit(bit, sbinfo->si_xib_buf);
38082+ sbinfo->si_xib_next_bit = bit;
38083+ }
38084+ mutex_unlock(&sbinfo->si_xib_mtx);
38085+}
38086+
1facf9fc 38087+/* ---------------------------------------------------------------------- */
38088+
1facf9fc 38089+/*
062440b3 38090+ * truncate a xino bitmap file
1facf9fc 38091+ */
1facf9fc 38092+
38093+/* todo: slow */
38094+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
38095+{
38096+ int err, bit;
38097+ ssize_t sz;
38098+ unsigned long pindex;
38099+ loff_t pos, pend;
38100+ struct au_sbinfo *sbinfo;
5527c038 38101+ vfs_readf_t func;
1facf9fc 38102+ ino_t *ino;
38103+ unsigned long *p;
38104+
38105+ err = 0;
38106+ sbinfo = au_sbi(sb);
dece6358 38107+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 38108+ p = sbinfo->si_xib_buf;
38109+ func = sbinfo->si_xread;
c06a8ce3 38110+ pend = vfsub_f_size_read(file);
1facf9fc 38111+ pos = 0;
38112+ while (pos < pend) {
38113+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
38114+ err = sz;
38115+ if (unlikely(sz <= 0))
38116+ goto out;
38117+
38118+ err = 0;
38119+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
38120+ if (unlikely(*ino < AUFS_FIRST_INO))
38121+ continue;
38122+
38123+ xib_calc_bit(*ino, &pindex, &bit);
38124+ AuDebugOn(page_bits <= bit);
38125+ err = xib_pindex(sb, pindex);
38126+ if (!err)
38127+ set_bit(bit, p);
38128+ else
38129+ goto out;
38130+ }
38131+ }
38132+
4f0767ce 38133+out:
1facf9fc 38134+ return err;
38135+}
38136+
38137+static int xib_restore(struct super_block *sb)
38138+{
acd2b654
AM
38139+ int err, i;
38140+ unsigned int nfile;
5afbbe0d 38141+ aufs_bindex_t bindex, bbot;
1facf9fc 38142+ void *page;
062440b3 38143+ struct au_branch *br;
acd2b654
AM
38144+ struct au_xino *xi;
38145+ struct file *file;
1facf9fc 38146+
38147+ err = -ENOMEM;
38148+ page = (void *)__get_free_page(GFP_NOFS);
38149+ if (unlikely(!page))
38150+ goto out;
38151+
38152+ err = 0;
5afbbe0d
AM
38153+ bbot = au_sbbot(sb);
38154+ for (bindex = 0; !err && bindex <= bbot; bindex++)
062440b3
AM
38155+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) {
38156+ br = au_sbr(sb, bindex);
acd2b654
AM
38157+ xi = br->br_xino;
38158+ nfile = xi->xi_nfile;
38159+ for (i = 0; i < nfile; i++) {
38160+ file = au_xino_file(xi, i);
38161+ if (file)
38162+ err = do_xib_restore(sb, file, page);
38163+ }
062440b3
AM
38164+ } else
38165+ AuDbg("skip shared b%d\n", bindex);
1c60b727 38166+ free_page((unsigned long)page);
1facf9fc 38167+
4f0767ce 38168+out:
1facf9fc 38169+ return err;
38170+}
38171+
38172+int au_xib_trunc(struct super_block *sb)
38173+{
38174+ int err;
38175+ ssize_t sz;
38176+ loff_t pos;
1facf9fc 38177+ struct au_sbinfo *sbinfo;
38178+ unsigned long *p;
38179+ struct file *file;
38180+
dece6358
AM
38181+ SiMustWriteLock(sb);
38182+
1facf9fc 38183+ err = 0;
38184+ sbinfo = au_sbi(sb);
38185+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
38186+ goto out;
38187+
38188+ file = sbinfo->si_xib;
c06a8ce3 38189+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 38190+ goto out;
38191+
062440b3 38192+ file = au_xino_create2(sb, &sbinfo->si_xib->f_path, NULL);
1facf9fc 38193+ err = PTR_ERR(file);
38194+ if (IS_ERR(file))
38195+ goto out;
38196+ fput(sbinfo->si_xib);
38197+ sbinfo->si_xib = file;
38198+
38199+ p = sbinfo->si_xib_buf;
38200+ memset(p, 0, PAGE_SIZE);
38201+ pos = 0;
38202+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
38203+ if (unlikely(sz != PAGE_SIZE)) {
38204+ err = sz;
38205+ AuIOErr("err %d\n", err);
38206+ if (sz >= 0)
38207+ err = -EIO;
38208+ goto out;
38209+ }
38210+
38211+ mutex_lock(&sbinfo->si_xib_mtx);
38212+ /* mnt_want_write() is unnecessary here */
38213+ err = xib_restore(sb);
38214+ mutex_unlock(&sbinfo->si_xib_mtx);
38215+
38216+out:
38217+ return err;
38218+}
38219+
38220+/* ---------------------------------------------------------------------- */
38221+
acd2b654 38222+struct au_xino *au_xino_alloc(unsigned int nfile)
062440b3
AM
38223+{
38224+ struct au_xino *xi;
38225+
38226+ xi = kzalloc(sizeof(*xi), GFP_NOFS);
38227+ if (unlikely(!xi))
38228+ goto out;
acd2b654
AM
38229+ xi->xi_nfile = nfile;
38230+ xi->xi_file = kcalloc(nfile, sizeof(*xi->xi_file), GFP_NOFS);
38231+ if (unlikely(!xi->xi_file))
38232+ goto out_free;
062440b3
AM
38233+
38234+ xi->xi_nondir.total = 8; /* initial size */
38235+ xi->xi_nondir.array = kcalloc(xi->xi_nondir.total, sizeof(ino_t),
38236+ GFP_NOFS);
38237+ if (unlikely(!xi->xi_nondir.array))
acd2b654 38238+ goto out_file;
062440b3
AM
38239+
38240+ spin_lock_init(&xi->xi_nondir.spin);
38241+ init_waitqueue_head(&xi->xi_nondir.wqh);
acd2b654 38242+ mutex_init(&xi->xi_mtx);
9f237c51 38243+ INIT_HLIST_BL_HEAD(&xi->xi_writing);
062440b3
AM
38244+ atomic_set(&xi->xi_truncating, 0);
38245+ kref_init(&xi->xi_kref);
38246+ goto out; /* success */
38247+
acd2b654 38248+out_file:
9f237c51 38249+ au_kfree_try_rcu(xi->xi_file);
062440b3 38250+out_free:
9f237c51 38251+ au_kfree_rcu(xi);
062440b3
AM
38252+ xi = NULL;
38253+out:
38254+ return xi;
38255+}
38256+
acd2b654 38257+static int au_xino_init(struct au_branch *br, int idx, struct file *file)
062440b3
AM
38258+{
38259+ int err;
38260+ struct au_xino *xi;
38261+
38262+ err = 0;
acd2b654 38263+ xi = au_xino_alloc(idx + 1);
062440b3
AM
38264+ if (unlikely(!xi)) {
38265+ err = -ENOMEM;
38266+ goto out;
38267+ }
38268+
acd2b654
AM
38269+ if (file)
38270+ get_file(file);
38271+ xi->xi_file[idx] = file;
062440b3
AM
38272+ AuDebugOn(br->br_xino);
38273+ br->br_xino = xi;
38274+
38275+out:
38276+ return err;
38277+}
38278+
38279+static void au_xino_release(struct kref *kref)
38280+{
38281+ struct au_xino *xi;
38282+ int i;
9f237c51
AM
38283+ unsigned long ul;
38284+ struct hlist_bl_head *hbl;
38285+ struct hlist_bl_node *pos, *n;
38286+ struct au_xi_writing *p;
062440b3
AM
38287+
38288+ xi = container_of(kref, struct au_xino, xi_kref);
acd2b654
AM
38289+ for (i = 0; i < xi->xi_nfile; i++)
38290+ if (xi->xi_file[i])
38291+ fput(xi->xi_file[i]);
062440b3
AM
38292+ for (i = xi->xi_nondir.total - 1; i >= 0; i--)
38293+ AuDebugOn(xi->xi_nondir.array[i]);
acd2b654 38294+ mutex_destroy(&xi->xi_mtx);
9f237c51
AM
38295+ hbl = &xi->xi_writing;
38296+ ul = au_hbl_count(hbl);
38297+ if (unlikely(ul)) {
38298+ pr_warn("xi_writing %lu\n", ul);
38299+ hlist_bl_lock(hbl);
38300+ hlist_bl_for_each_entry_safe (p, pos, n, hbl, node) {
38301+ hlist_bl_del(&p->node);
38302+ au_kfree_rcu(p);
38303+ }
38304+ hlist_bl_unlock(hbl);
38305+ }
38306+ au_kfree_try_rcu(xi->xi_file);
38307+ au_kfree_try_rcu(xi->xi_nondir.array);
38308+ au_kfree_rcu(xi);
062440b3
AM
38309+}
38310+
38311+int au_xino_put(struct au_branch *br)
38312+{
38313+ int ret;
38314+ struct au_xino *xi;
38315+
38316+ ret = 0;
38317+ xi = br->br_xino;
38318+ if (xi) {
38319+ br->br_xino = NULL;
38320+ ret = kref_put(&xi->xi_kref, au_xino_release);
38321+ }
38322+
38323+ return ret;
38324+}
38325+
062440b3
AM
38326+/* ---------------------------------------------------------------------- */
38327+
1facf9fc 38328+/*
38329+ * xino mount option handlers
38330+ */
1facf9fc 38331+
38332+/* xino bitmap */
38333+static void xino_clear_xib(struct super_block *sb)
38334+{
38335+ struct au_sbinfo *sbinfo;
38336+
dece6358
AM
38337+ SiMustWriteLock(sb);
38338+
1facf9fc 38339+ sbinfo = au_sbi(sb);
062440b3 38340+ /* unnecessary to clear sbinfo->si_xread and ->si_xwrite */
1facf9fc 38341+ if (sbinfo->si_xib)
38342+ fput(sbinfo->si_xib);
38343+ sbinfo->si_xib = NULL;
f0c0a007 38344+ if (sbinfo->si_xib_buf)
1c60b727 38345+ free_page((unsigned long)sbinfo->si_xib_buf);
1facf9fc 38346+ sbinfo->si_xib_buf = NULL;
38347+}
38348+
062440b3 38349+static int au_xino_set_xib(struct super_block *sb, struct path *path)
1facf9fc 38350+{
38351+ int err;
38352+ loff_t pos;
38353+ struct au_sbinfo *sbinfo;
38354+ struct file *file;
acd2b654 38355+ struct super_block *xi_sb;
1facf9fc 38356+
dece6358
AM
38357+ SiMustWriteLock(sb);
38358+
1facf9fc 38359+ sbinfo = au_sbi(sb);
062440b3 38360+ file = au_xino_create2(sb, path, sbinfo->si_xib);
1facf9fc 38361+ err = PTR_ERR(file);
38362+ if (IS_ERR(file))
38363+ goto out;
38364+ if (sbinfo->si_xib)
38365+ fput(sbinfo->si_xib);
38366+ sbinfo->si_xib = file;
5527c038
JR
38367+ sbinfo->si_xread = vfs_readf(file);
38368+ sbinfo->si_xwrite = vfs_writef(file);
acd2b654
AM
38369+ xi_sb = file_inode(file)->i_sb;
38370+ sbinfo->si_ximaxent = xi_sb->s_maxbytes;
38371+ if (unlikely(sbinfo->si_ximaxent < PAGE_SIZE)) {
38372+ err = -EIO;
38373+ pr_err("s_maxbytes(%llu) on %s is too small\n",
38374+ (u64)sbinfo->si_ximaxent, au_sbtype(xi_sb));
38375+ goto out_unset;
38376+ }
38377+ sbinfo->si_ximaxent /= sizeof(ino_t);
1facf9fc 38378+
38379+ err = -ENOMEM;
38380+ if (!sbinfo->si_xib_buf)
38381+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
38382+ if (unlikely(!sbinfo->si_xib_buf))
38383+ goto out_unset;
38384+
38385+ sbinfo->si_xib_last_pindex = 0;
38386+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 38387+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 38388+ pos = 0;
38389+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
38390+ PAGE_SIZE, &pos);
38391+ if (unlikely(err != PAGE_SIZE))
38392+ goto out_free;
38393+ }
38394+ err = 0;
38395+ goto out; /* success */
38396+
4f0767ce 38397+out_free:
f0c0a007 38398+ if (sbinfo->si_xib_buf)
1c60b727 38399+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
38400+ sbinfo->si_xib_buf = NULL;
38401+ if (err >= 0)
38402+ err = -EIO;
4f0767ce 38403+out_unset:
b752ccd1
AM
38404+ fput(sbinfo->si_xib);
38405+ sbinfo->si_xib = NULL;
4f0767ce 38406+out:
062440b3 38407+ AuTraceErr(err);
b752ccd1 38408+ return err;
1facf9fc 38409+}
38410+
b752ccd1
AM
38411+/* xino for each branch */
38412+static void xino_clear_br(struct super_block *sb)
38413+{
5afbbe0d 38414+ aufs_bindex_t bindex, bbot;
b752ccd1 38415+ struct au_branch *br;
1facf9fc 38416+
5afbbe0d
AM
38417+ bbot = au_sbbot(sb);
38418+ for (bindex = 0; bindex <= bbot; bindex++) {
b752ccd1 38419+ br = au_sbr(sb, bindex);
062440b3
AM
38420+ AuDebugOn(!br);
38421+ au_xino_put(br);
38422+ }
38423+}
38424+
38425+static void au_xino_set_br_shared(struct super_block *sb, struct au_branch *br,
38426+ aufs_bindex_t bshared)
38427+{
38428+ struct au_branch *brshared;
b752ccd1 38429+
062440b3
AM
38430+ brshared = au_sbr(sb, bshared);
38431+ AuDebugOn(!brshared->br_xino);
38432+ AuDebugOn(!brshared->br_xino->xi_file);
38433+ if (br->br_xino != brshared->br_xino) {
38434+ au_xino_get(brshared);
38435+ au_xino_put(br);
38436+ br->br_xino = brshared->br_xino;
b752ccd1
AM
38437+ }
38438+}
38439+
062440b3
AM
38440+struct au_xino_do_set_br {
38441+ vfs_writef_t writef;
38442+ struct au_branch *br;
38443+ ino_t h_ino;
38444+ aufs_bindex_t bshared;
38445+};
38446+
38447+static int au_xino_do_set_br(struct super_block *sb, struct path *path,
38448+ struct au_xino_do_set_br *args)
1facf9fc 38449+{
38450+ int err;
acd2b654 38451+ struct au_xi_calc calc;
062440b3 38452+ struct file *file;
acd2b654
AM
38453+ struct au_branch *br;
38454+ struct au_xi_new xinew = {
38455+ .base = path
38456+ };
062440b3 38457+
acd2b654
AM
38458+ br = args->br;
38459+ xinew.xi = br->br_xino;
38460+ au_xi_calc(sb, args->h_ino, &calc);
38461+ xinew.copy_src = au_xino_file(xinew.xi, calc.idx);
38462+ if (args->bshared >= 0)
062440b3 38463+ /* shared xino */
acd2b654
AM
38464+ au_xino_set_br_shared(sb, br, args->bshared);
38465+ else if (!xinew.xi) {
38466+ /* new xino */
38467+ err = au_xino_init(br, calc.idx, xinew.copy_src);
38468+ if (unlikely(err))
38469+ goto out;
062440b3
AM
38470+ }
38471+
acd2b654
AM
38472+ /* force re-creating */
38473+ xinew.xi = br->br_xino;
38474+ xinew.idx = calc.idx;
38475+ mutex_lock(&xinew.xi->xi_mtx);
38476+ file = au_xi_new(sb, &xinew);
38477+ mutex_unlock(&xinew.xi->xi_mtx);
062440b3
AM
38478+ err = PTR_ERR(file);
38479+ if (IS_ERR(file))
38480+ goto out;
acd2b654
AM
38481+ AuDebugOn(!file);
38482+
38483+ err = au_xino_do_write(args->writef, file, &calc, AUFS_ROOT_INO);
38484+ if (unlikely(err))
38485+ au_xino_put(br);
062440b3 38486+
062440b3
AM
38487+out:
38488+ AuTraceErr(err);
38489+ return err;
38490+}
38491+
38492+static int au_xino_set_br(struct super_block *sb, struct path *path)
38493+{
38494+ int err;
38495+ aufs_bindex_t bindex, bbot;
38496+ struct au_xino_do_set_br args;
b752ccd1 38497+ struct inode *inode;
1facf9fc 38498+
b752ccd1
AM
38499+ SiMustWriteLock(sb);
38500+
5afbbe0d 38501+ bbot = au_sbbot(sb);
5527c038 38502+ inode = d_inode(sb->s_root);
062440b3
AM
38503+ args.writef = au_sbi(sb)->si_xwrite;
38504+ for (bindex = 0; bindex <= bbot; bindex++) {
38505+ args.h_ino = au_h_iptr(inode, bindex)->i_ino;
38506+ args.br = au_sbr(sb, bindex);
38507+ args.bshared = is_sb_shared(sb, bindex, bindex - 1);
38508+ err = au_xino_do_set_br(sb, path, &args);
b752ccd1 38509+ if (unlikely(err))
062440b3 38510+ break;
b752ccd1 38511+ }
1facf9fc 38512+
062440b3 38513+ AuTraceErr(err);
1facf9fc 38514+ return err;
38515+}
b752ccd1
AM
38516+
38517+void au_xino_clr(struct super_block *sb)
38518+{
38519+ struct au_sbinfo *sbinfo;
38520+
38521+ au_xigen_clr(sb);
38522+ xino_clear_xib(sb);
38523+ xino_clear_br(sb);
062440b3 38524+ dbgaufs_brs_del(sb, 0);
b752ccd1
AM
38525+ sbinfo = au_sbi(sb);
38526+ /* lvalue, do not call au_mntflags() */
38527+ au_opt_clr(sbinfo->si_mntflags, XINO);
38528+}
38529+
062440b3 38530+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount)
b752ccd1
AM
38531+{
38532+ int err, skip;
062440b3 38533+ struct dentry *dentry, *parent, *cur_dentry, *cur_parent;
b752ccd1
AM
38534+ struct qstr *dname, *cur_name;
38535+ struct file *cur_xino;
b752ccd1 38536+ struct au_sbinfo *sbinfo;
062440b3 38537+ struct path *path, *cur_path;
b752ccd1
AM
38538+
38539+ SiMustWriteLock(sb);
38540+
38541+ err = 0;
38542+ sbinfo = au_sbi(sb);
062440b3
AM
38543+ path = &xiopt->file->f_path;
38544+ dentry = path->dentry;
38545+ parent = dget_parent(dentry);
b752ccd1
AM
38546+ if (remount) {
38547+ skip = 0;
b752ccd1
AM
38548+ cur_xino = sbinfo->si_xib;
38549+ if (cur_xino) {
062440b3
AM
38550+ cur_path = &cur_xino->f_path;
38551+ cur_dentry = cur_path->dentry;
38552+ cur_parent = dget_parent(cur_dentry);
38553+ cur_name = &cur_dentry->d_name;
38554+ dname = &dentry->d_name;
b752ccd1 38555+ skip = (cur_parent == parent
38d290e6 38556+ && au_qstreq(dname, cur_name));
b752ccd1
AM
38557+ dput(cur_parent);
38558+ }
38559+ if (skip)
38560+ goto out;
38561+ }
38562+
38563+ au_opt_set(sbinfo->si_mntflags, XINO);
062440b3
AM
38564+ err = au_xino_set_xib(sb, path);
38565+ /* si_x{read,write} are set */
b752ccd1 38566+ if (!err)
062440b3 38567+ err = au_xigen_set(sb, path);
b752ccd1 38568+ if (!err)
062440b3
AM
38569+ err = au_xino_set_br(sb, path);
38570+ if (!err) {
38571+ dbgaufs_brs_add(sb, 0, /*topdown*/1);
b752ccd1 38572+ goto out; /* success */
062440b3 38573+ }
b752ccd1
AM
38574+
38575+ /* reset all */
062440b3
AM
38576+ AuIOErr("failed setting xino(%d).\n", err);
38577+ au_xino_clr(sb);
b752ccd1 38578+
4f0767ce 38579+out:
b752ccd1
AM
38580+ dput(parent);
38581+ return err;
38582+}
38583+
b752ccd1
AM
38584+/*
38585+ * create a xinofile at the default place/path.
38586+ */
38587+struct file *au_xino_def(struct super_block *sb)
38588+{
38589+ struct file *file;
38590+ char *page, *p;
38591+ struct au_branch *br;
38592+ struct super_block *h_sb;
38593+ struct path path;
5afbbe0d 38594+ aufs_bindex_t bbot, bindex, bwr;
b752ccd1
AM
38595+
38596+ br = NULL;
5afbbe0d 38597+ bbot = au_sbbot(sb);
b752ccd1 38598+ bwr = -1;
5afbbe0d 38599+ for (bindex = 0; bindex <= bbot; bindex++) {
b752ccd1
AM
38600+ br = au_sbr(sb, bindex);
38601+ if (au_br_writable(br->br_perm)
86dc4139 38602+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
38603+ bwr = bindex;
38604+ break;
38605+ }
38606+ }
38607+
7f207e10
AM
38608+ if (bwr >= 0) {
38609+ file = ERR_PTR(-ENOMEM);
537831f9 38610+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
38611+ if (unlikely(!page))
38612+ goto out;
86dc4139 38613+ path.mnt = au_br_mnt(br);
7f207e10
AM
38614+ path.dentry = au_h_dptr(sb->s_root, bwr);
38615+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
38616+ file = (void *)p;
38617+ if (!IS_ERR(p)) {
38618+ strcat(p, "/" AUFS_XINO_FNAME);
38619+ AuDbg("%s\n", p);
38620+ file = au_xino_create(sb, p, /*silent*/0);
7f207e10 38621+ }
1c60b727 38622+ free_page((unsigned long)page);
7f207e10
AM
38623+ } else {
38624+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
38625+ if (IS_ERR(file))
38626+ goto out;
2000de60 38627+ h_sb = file->f_path.dentry->d_sb;
7f207e10
AM
38628+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
38629+ pr_err("xino doesn't support %s(%s)\n",
38630+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
38631+ fput(file);
38632+ file = ERR_PTR(-EINVAL);
38633+ }
7f207e10 38634+ }
0c5527e5 38635+
7f207e10
AM
38636+out:
38637+ return file;
38638+}
38639+
38640+/* ---------------------------------------------------------------------- */
38641+
062440b3
AM
38642+/*
38643+ * initialize the xinofile for the specified branch @br
38644+ * at the place/path where @base_file indicates.
38645+ * test whether another branch is on the same filesystem or not,
38646+ * if found then share the xinofile with another branch.
38647+ */
38648+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
38649+ struct path *base)
7f207e10
AM
38650+{
38651+ int err;
062440b3
AM
38652+ struct au_xino_do_set_br args = {
38653+ .h_ino = h_ino,
38654+ .br = br
38655+ };
7f207e10 38656+
062440b3
AM
38657+ args.writef = au_sbi(sb)->si_xwrite;
38658+ args.bshared = sbr_find_shared(sb, /*btop*/0, au_sbbot(sb),
38659+ au_br_sb(br));
38660+ err = au_xino_do_set_br(sb, base, &args);
79b8bda9 38661+ if (unlikely(err))
062440b3 38662+ au_xino_put(br);
7f207e10 38663+
7f207e10
AM
38664+ return err;
38665+}
521ced18
JR
38666+
38667+/* ---------------------------------------------------------------------- */
38668+
062440b3
AM
38669+/*
38670+ * get an unused inode number from bitmap
38671+ */
38672+ino_t au_xino_new_ino(struct super_block *sb)
38673+{
38674+ ino_t ino;
38675+ unsigned long *p, pindex, ul, pend;
38676+ struct au_sbinfo *sbinfo;
38677+ struct file *file;
38678+ int free_bit, err;
38679+
38680+ if (!au_opt_test(au_mntflags(sb), XINO))
38681+ return iunique(sb, AUFS_FIRST_INO);
38682+
38683+ sbinfo = au_sbi(sb);
38684+ mutex_lock(&sbinfo->si_xib_mtx);
38685+ p = sbinfo->si_xib_buf;
38686+ free_bit = sbinfo->si_xib_next_bit;
38687+ if (free_bit < page_bits && !test_bit(free_bit, p))
38688+ goto out; /* success */
38689+ free_bit = find_first_zero_bit(p, page_bits);
38690+ if (free_bit < page_bits)
38691+ goto out; /* success */
38692+
38693+ pindex = sbinfo->si_xib_last_pindex;
38694+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
38695+ err = xib_pindex(sb, ul);
38696+ if (unlikely(err))
38697+ goto out_err;
38698+ free_bit = find_first_zero_bit(p, page_bits);
38699+ if (free_bit < page_bits)
38700+ goto out; /* success */
38701+ }
38702+
38703+ file = sbinfo->si_xib;
38704+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
38705+ for (ul = pindex + 1; ul <= pend; ul++) {
38706+ err = xib_pindex(sb, ul);
38707+ if (unlikely(err))
38708+ goto out_err;
38709+ free_bit = find_first_zero_bit(p, page_bits);
38710+ if (free_bit < page_bits)
38711+ goto out; /* success */
38712+ }
38713+ BUG();
38714+
38715+out:
38716+ set_bit(free_bit, p);
38717+ sbinfo->si_xib_next_bit = free_bit + 1;
38718+ pindex = sbinfo->si_xib_last_pindex;
38719+ mutex_unlock(&sbinfo->si_xib_mtx);
38720+ ino = xib_calc_ino(pindex, free_bit);
38721+ AuDbg("i%lu\n", (unsigned long)ino);
38722+ return ino;
38723+out_err:
38724+ mutex_unlock(&sbinfo->si_xib_mtx);
38725+ AuDbg("i0\n");
38726+ return 0;
38727+}
38728+
38729+/* for s_op->delete_inode() */
38730+void au_xino_delete_inode(struct inode *inode, const int unlinked)
521ced18 38731+{
062440b3
AM
38732+ int err;
38733+ unsigned int mnt_flags;
38734+ aufs_bindex_t bindex, bbot, bi;
38735+ unsigned char try_trunc;
38736+ struct au_iinfo *iinfo;
38737+ struct super_block *sb;
38738+ struct au_hinode *hi;
38739+ struct inode *h_inode;
38740+ struct au_branch *br;
38741+ vfs_writef_t xwrite;
acd2b654
AM
38742+ struct au_xi_calc calc;
38743+ struct file *file;
521ced18 38744+
062440b3 38745+ AuDebugOn(au_is_bad_inode(inode));
521ced18 38746+
062440b3
AM
38747+ sb = inode->i_sb;
38748+ mnt_flags = au_mntflags(sb);
38749+ if (!au_opt_test(mnt_flags, XINO)
38750+ || inode->i_ino == AUFS_ROOT_INO)
38751+ return;
38752+
38753+ if (unlinked) {
38754+ au_xigen_inc(inode);
38755+ au_xib_clear_bit(inode);
38756+ }
38757+
38758+ iinfo = au_ii(inode);
38759+ bindex = iinfo->ii_btop;
38760+ if (bindex < 0)
38761+ return;
38762+
38763+ xwrite = au_sbi(sb)->si_xwrite;
38764+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
38765+ hi = au_hinode(iinfo, bindex);
38766+ bbot = iinfo->ii_bbot;
38767+ for (; bindex <= bbot; bindex++, hi++) {
38768+ h_inode = hi->hi_inode;
38769+ if (!h_inode
38770+ || (!unlinked && h_inode->i_nlink))
38771+ continue;
38772+
38773+ /* inode may not be revalidated */
38774+ bi = au_br_index(sb, hi->hi_id);
38775+ if (bi < 0)
38776+ continue;
38777+
38778+ br = au_sbr(sb, bi);
acd2b654
AM
38779+ au_xi_calc(sb, h_inode->i_ino, &calc);
38780+ file = au_xino_file(br->br_xino, calc.idx);
38781+ if (IS_ERR_OR_NULL(file))
38782+ continue;
38783+
38784+ err = au_xino_do_write(xwrite, file, &calc, /*ino*/0);
062440b3
AM
38785+ if (!err && try_trunc
38786+ && au_test_fs_trunc_xino(au_br_sb(br)))
38787+ xino_try_trunc(sb, br);
38788+ }
521ced18
JR
38789+}
38790+
062440b3
AM
38791+/* ---------------------------------------------------------------------- */
38792+
38793+static int au_xinondir_find(struct au_xino *xi, ino_t h_ino)
521ced18
JR
38794+{
38795+ int found, total, i;
38796+
38797+ found = -1;
062440b3 38798+ total = xi->xi_nondir.total;
521ced18 38799+ for (i = 0; i < total; i++) {
062440b3 38800+ if (xi->xi_nondir.array[i] != h_ino)
521ced18
JR
38801+ continue;
38802+ found = i;
38803+ break;
38804+ }
38805+
38806+ return found;
38807+}
38808+
062440b3 38809+static int au_xinondir_expand(struct au_xino *xi)
521ced18
JR
38810+{
38811+ int err, sz;
38812+ ino_t *p;
38813+
38814+ BUILD_BUG_ON(KMALLOC_MAX_SIZE > INT_MAX);
38815+
38816+ err = -ENOMEM;
062440b3 38817+ sz = xi->xi_nondir.total * sizeof(ino_t);
521ced18
JR
38818+ if (unlikely(sz > KMALLOC_MAX_SIZE / 2))
38819+ goto out;
062440b3 38820+ p = au_kzrealloc(xi->xi_nondir.array, sz, sz << 1, GFP_ATOMIC,
521ced18
JR
38821+ /*may_shrink*/0);
38822+ if (p) {
062440b3
AM
38823+ xi->xi_nondir.array = p;
38824+ xi->xi_nondir.total <<= 1;
38825+ AuDbg("xi_nondir.total %d\n", xi->xi_nondir.total);
521ced18
JR
38826+ err = 0;
38827+ }
38828+
38829+out:
38830+ return err;
38831+}
38832+
062440b3
AM
38833+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
38834+ ino_t h_ino, int idx)
38835+{
38836+ struct au_xino *xi;
38837+
38838+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
38839+ xi = au_sbr(sb, bindex)->br_xino;
38840+ AuDebugOn(idx < 0 || xi->xi_nondir.total <= idx);
38841+
38842+ spin_lock(&xi->xi_nondir.spin);
38843+ AuDebugOn(xi->xi_nondir.array[idx] != h_ino);
38844+ xi->xi_nondir.array[idx] = 0;
38845+ spin_unlock(&xi->xi_nondir.spin);
38846+ wake_up_all(&xi->xi_nondir.wqh);
38847+}
38848+
521ced18
JR
38849+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
38850+ int *idx)
38851+{
38852+ int err, found, empty;
062440b3 38853+ struct au_xino *xi;
521ced18
JR
38854+
38855+ err = 0;
38856+ *idx = -1;
38857+ if (!au_opt_test(au_mntflags(sb), XINO))
38858+ goto out; /* no xino */
38859+
062440b3 38860+ xi = au_sbr(sb, bindex)->br_xino;
521ced18
JR
38861+
38862+again:
062440b3
AM
38863+ spin_lock(&xi->xi_nondir.spin);
38864+ found = au_xinondir_find(xi, h_ino);
521ced18 38865+ if (found == -1) {
062440b3 38866+ empty = au_xinondir_find(xi, /*h_ino*/0);
521ced18 38867+ if (empty == -1) {
062440b3
AM
38868+ empty = xi->xi_nondir.total;
38869+ err = au_xinondir_expand(xi);
521ced18
JR
38870+ if (unlikely(err))
38871+ goto out_unlock;
38872+ }
062440b3 38873+ xi->xi_nondir.array[empty] = h_ino;
521ced18
JR
38874+ *idx = empty;
38875+ } else {
062440b3
AM
38876+ spin_unlock(&xi->xi_nondir.spin);
38877+ wait_event(xi->xi_nondir.wqh,
38878+ xi->xi_nondir.array[found] != h_ino);
521ced18
JR
38879+ goto again;
38880+ }
38881+
38882+out_unlock:
062440b3
AM
38883+ spin_unlock(&xi->xi_nondir.spin);
38884+out:
38885+ return err;
38886+}
38887+
38888+/* ---------------------------------------------------------------------- */
38889+
38890+int au_xino_path(struct seq_file *seq, struct file *file)
38891+{
38892+ int err;
38893+
38894+ err = au_seq_path(seq, &file->f_path);
38895+ if (unlikely(err))
38896+ goto out;
38897+
38898+#define Deleted "\\040(deleted)"
38899+ seq->count -= sizeof(Deleted) - 1;
38900+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
38901+ sizeof(Deleted) - 1));
38902+#undef Deleted
38903+
521ced18
JR
38904+out:
38905+ return err;
38906+}
537831f9
AM
38907diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
38908--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
eca801bf 38909+++ linux/include/uapi/linux/aufs_type.h 2019-05-06 09:03:04.820143837 +0200
062440b3
AM
38910@@ -0,0 +1,448 @@
38911+/* SPDX-License-Identifier: GPL-2.0 */
7f207e10 38912+/*
ba1aed25 38913+ * Copyright (C) 2005-2019 Junjiro R. Okajima
7f207e10
AM
38914+ *
38915+ * This program, aufs is free software; you can redistribute it and/or modify
38916+ * it under the terms of the GNU General Public License as published by
38917+ * the Free Software Foundation; either version 2 of the License, or
38918+ * (at your option) any later version.
38919+ *
38920+ * This program is distributed in the hope that it will be useful,
38921+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
38922+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38923+ * GNU General Public License for more details.
38924+ *
38925+ * You should have received a copy of the GNU General Public License
523b37e3 38926+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
38927+ */
38928+
38929+#ifndef __AUFS_TYPE_H__
38930+#define __AUFS_TYPE_H__
38931+
f6c5ef8b
AM
38932+#define AUFS_NAME "aufs"
38933+
9dbd164d 38934+#ifdef __KERNEL__
f6c5ef8b
AM
38935+/*
38936+ * define it before including all other headers.
38937+ * sched.h may use pr_* macros before defining "current", so define the
38938+ * no-current version first, and re-define later.
38939+ */
38940+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
38941+#include <linux/sched.h>
38942+#undef pr_fmt
a2a7ad62
AM
38943+#define pr_fmt(fmt) \
38944+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
38945+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
38946+#else
38947+#include <stdint.h>
38948+#include <sys/types.h>
f6c5ef8b 38949+#endif /* __KERNEL__ */
7f207e10 38950+
f6c5ef8b
AM
38951+#include <linux/limits.h>
38952+
eca801bf 38953+#define AUFS_VERSION "4.x-rcN-20190311"
7f207e10
AM
38954+
38955+/* todo? move this to linux-2.6.19/include/magic.h */
38956+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
38957+
38958+/* ---------------------------------------------------------------------- */
38959+
38960+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 38961+typedef int8_t aufs_bindex_t;
7f207e10
AM
38962+#define AUFS_BRANCH_MAX 127
38963+#else
9dbd164d 38964+typedef int16_t aufs_bindex_t;
7f207e10
AM
38965+#ifdef CONFIG_AUFS_BRANCH_MAX_511
38966+#define AUFS_BRANCH_MAX 511
38967+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
38968+#define AUFS_BRANCH_MAX 1023
38969+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
38970+#define AUFS_BRANCH_MAX 32767
38971+#endif
38972+#endif
38973+
38974+#ifdef __KERNEL__
38975+#ifndef AUFS_BRANCH_MAX
38976+#error unknown CONFIG_AUFS_BRANCH_MAX value
38977+#endif
38978+#endif /* __KERNEL__ */
38979+
38980+/* ---------------------------------------------------------------------- */
38981+
7f207e10
AM
38982+#define AUFS_FSTYPE AUFS_NAME
38983+
38984+#define AUFS_ROOT_INO 2
38985+#define AUFS_FIRST_INO 11
38986+
38987+#define AUFS_WH_PFX ".wh."
38988+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
38989+#define AUFS_WH_TMP_LEN 4
86dc4139 38990+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
38991+#define AUFS_MAX_NAMELEN (NAME_MAX \
38992+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
38993+ - 1 /* dot */\
38994+ - AUFS_WH_TMP_LEN) /* hex */
38995+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
38996+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
38997+#define AUFS_XINO_DEF_SEC 30 /* seconds */
38998+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
38999+#define AUFS_DIRWH_DEF 3
39000+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 39001+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
39002+#define AUFS_RDBLK_DEF 512 /* bytes */
39003+#define AUFS_RDHASH_DEF 32
39004+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
39005+#define AUFS_MFS_DEF_SEC 30 /* seconds */
39006+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
076b876e 39007+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
86dc4139 39008+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
39009+
39010+/* pseudo-link maintenace under /proc */
39011+#define AUFS_PLINK_MAINT_NAME "plink_maint"
39012+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
39013+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
39014+
8b6a4947
AM
39015+/* dirren, renamed dir */
39016+#define AUFS_DR_INFO_PFX AUFS_WH_PFX ".dr."
39017+#define AUFS_DR_BRHINO_NAME AUFS_WH_PFX "hino"
39018+/* whiteouted doubly */
39019+#define AUFS_WH_DR_INFO_PFX AUFS_WH_PFX AUFS_DR_INFO_PFX
39020+#define AUFS_WH_DR_BRHINO AUFS_WH_PFX AUFS_DR_BRHINO_NAME
39021+
7f207e10
AM
39022+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
39023+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
39024+
39025+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
39026+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
39027+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
39028+
39029+/* doubly whiteouted */
39030+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
39031+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
39032+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
39033+
1e00d052 39034+/* branch permissions and attributes */
7f207e10
AM
39035+#define AUFS_BRPERM_RW "rw"
39036+#define AUFS_BRPERM_RO "ro"
39037+#define AUFS_BRPERM_RR "rr"
076b876e
AM
39038+#define AUFS_BRATTR_COO_REG "coo_reg"
39039+#define AUFS_BRATTR_COO_ALL "coo_all"
39040+#define AUFS_BRATTR_FHSM "fhsm"
39041+#define AUFS_BRATTR_UNPIN "unpin"
c1595e42
JR
39042+#define AUFS_BRATTR_ICEX "icex"
39043+#define AUFS_BRATTR_ICEX_SEC "icexsec"
39044+#define AUFS_BRATTR_ICEX_SYS "icexsys"
39045+#define AUFS_BRATTR_ICEX_TR "icextr"
39046+#define AUFS_BRATTR_ICEX_USR "icexusr"
39047+#define AUFS_BRATTR_ICEX_OTH "icexoth"
1e00d052
AM
39048+#define AUFS_BRRATTR_WH "wh"
39049+#define AUFS_BRWATTR_NLWH "nolwh"
076b876e
AM
39050+#define AUFS_BRWATTR_MOO "moo"
39051+
39052+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
39053+#define AuBrPerm_RO (1 << 1) /* readonly */
39054+#define AuBrPerm_RR (1 << 2) /* natively readonly */
39055+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
39056+
39057+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
39058+#define AuBrAttr_COO_ALL (1 << 4)
39059+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
39060+
39061+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
39062+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
c1595e42
JR
39063+ branch. meaningless since
39064+ linux-3.18-rc1 */
39065+
39066+/* ignore error in copying XATTR */
39067+#define AuBrAttr_ICEX_SEC (1 << 7)
39068+#define AuBrAttr_ICEX_SYS (1 << 8)
39069+#define AuBrAttr_ICEX_TR (1 << 9)
39070+#define AuBrAttr_ICEX_USR (1 << 10)
39071+#define AuBrAttr_ICEX_OTH (1 << 11)
39072+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \
39073+ | AuBrAttr_ICEX_SYS \
39074+ | AuBrAttr_ICEX_TR \
39075+ | AuBrAttr_ICEX_USR \
39076+ | AuBrAttr_ICEX_OTH)
39077+
39078+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */
076b876e
AM
39079+#define AuBrRAttr_Mask AuBrRAttr_WH
39080+
c1595e42
JR
39081+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */
39082+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */
076b876e
AM
39083+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
39084+
39085+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
39086+
c1595e42 39087+/* #warning test userspace */
076b876e
AM
39088+#ifdef __KERNEL__
39089+#ifndef CONFIG_AUFS_FHSM
39090+#undef AuBrAttr_FHSM
39091+#define AuBrAttr_FHSM 0
39092+#endif
c1595e42
JR
39093+#ifndef CONFIG_AUFS_XATTR
39094+#undef AuBrAttr_ICEX
39095+#define AuBrAttr_ICEX 0
39096+#undef AuBrAttr_ICEX_SEC
39097+#define AuBrAttr_ICEX_SEC 0
39098+#undef AuBrAttr_ICEX_SYS
39099+#define AuBrAttr_ICEX_SYS 0
39100+#undef AuBrAttr_ICEX_TR
39101+#define AuBrAttr_ICEX_TR 0
39102+#undef AuBrAttr_ICEX_USR
39103+#define AuBrAttr_ICEX_USR 0
39104+#undef AuBrAttr_ICEX_OTH
39105+#define AuBrAttr_ICEX_OTH 0
39106+#endif
076b876e
AM
39107+#endif
39108+
39109+/* the longest combination */
c1595e42
JR
39110+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
39111+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
39112+ "+" AUFS_BRATTR_COO_REG \
39113+ "+" AUFS_BRATTR_FHSM \
39114+ "+" AUFS_BRATTR_UNPIN \
7e9cd9fe
AM
39115+ "+" AUFS_BRATTR_ICEX_SEC \
39116+ "+" AUFS_BRATTR_ICEX_SYS \
39117+ "+" AUFS_BRATTR_ICEX_USR \
39118+ "+" AUFS_BRATTR_ICEX_OTH \
076b876e
AM
39119+ "+" AUFS_BRWATTR_NLWH)
39120+
39121+typedef struct {
39122+ char a[AuBrPermStrSz];
39123+} au_br_perm_str_t;
39124+
39125+static inline int au_br_writable(int brperm)
39126+{
39127+ return brperm & AuBrPerm_RW;
39128+}
39129+
39130+static inline int au_br_whable(int brperm)
39131+{
39132+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
39133+}
39134+
39135+static inline int au_br_wh_linkable(int brperm)
39136+{
39137+ return !(brperm & AuBrWAttr_NoLinkWH);
39138+}
39139+
39140+static inline int au_br_cmoo(int brperm)
39141+{
39142+ return brperm & AuBrAttr_CMOO_Mask;
39143+}
39144+
39145+static inline int au_br_fhsm(int brperm)
39146+{
39147+ return brperm & AuBrAttr_FHSM;
39148+}
7f207e10
AM
39149+
39150+/* ---------------------------------------------------------------------- */
39151+
39152+/* ioctl */
39153+enum {
39154+ /* readdir in userspace */
39155+ AuCtl_RDU,
39156+ AuCtl_RDU_INO,
39157+
076b876e
AM
39158+ AuCtl_WBR_FD, /* pathconf wrapper */
39159+ AuCtl_IBUSY, /* busy inode */
39160+ AuCtl_MVDOWN, /* move-down */
39161+ AuCtl_BR, /* info about branches */
39162+ AuCtl_FHSM_FD /* connection for fhsm */
7f207e10
AM
39163+};
39164+
39165+/* borrowed from linux/include/linux/kernel.h */
39166+#ifndef ALIGN
39167+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
39168+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
39169+#endif
39170+
39171+/* borrowed from linux/include/linux/compiler-gcc3.h */
39172+#ifndef __aligned
39173+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
39174+#endif
39175+
39176+#ifdef __KERNEL__
39177+#ifndef __packed
7f207e10
AM
39178+#define __packed __attribute__((packed))
39179+#endif
53392da6 39180+#endif
7f207e10
AM
39181+
39182+struct au_rdu_cookie {
9dbd164d
AM
39183+ uint64_t h_pos;
39184+ int16_t bindex;
39185+ uint8_t flags;
39186+ uint8_t pad;
39187+ uint32_t generation;
7f207e10
AM
39188+} __aligned(8);
39189+
39190+struct au_rdu_ent {
9dbd164d
AM
39191+ uint64_t ino;
39192+ int16_t bindex;
39193+ uint8_t type;
39194+ uint8_t nlen;
39195+ uint8_t wh;
7f207e10
AM
39196+ char name[0];
39197+} __aligned(8);
39198+
39199+static inline int au_rdu_len(int nlen)
39200+{
39201+ /* include the terminating NULL */
39202+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 39203+ sizeof(uint64_t));
7f207e10
AM
39204+}
39205+
39206+union au_rdu_ent_ul {
39207+ struct au_rdu_ent __user *e;
9dbd164d 39208+ uint64_t ul;
7f207e10
AM
39209+};
39210+
39211+enum {
39212+ AufsCtlRduV_SZ,
39213+ AufsCtlRduV_End
39214+};
39215+
39216+struct aufs_rdu {
39217+ /* input */
39218+ union {
9dbd164d
AM
39219+ uint64_t sz; /* AuCtl_RDU */
39220+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
39221+ };
39222+ union au_rdu_ent_ul ent;
9dbd164d 39223+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
39224+
39225+ /* input/output */
9dbd164d 39226+ uint32_t blk;
7f207e10
AM
39227+
39228+ /* output */
39229+ union au_rdu_ent_ul tail;
39230+ /* number of entries which were added in a single call */
9dbd164d
AM
39231+ uint64_t rent;
39232+ uint8_t full;
39233+ uint8_t shwh;
7f207e10
AM
39234+
39235+ struct au_rdu_cookie cookie;
39236+} __aligned(8);
39237+
1e00d052
AM
39238+/* ---------------------------------------------------------------------- */
39239+
8b6a4947
AM
39240+/* dirren. the branch is identified by the filename who contains this */
39241+struct au_drinfo {
39242+ uint64_t ino;
39243+ union {
39244+ uint8_t oldnamelen;
39245+ uint64_t _padding;
39246+ };
39247+ uint8_t oldname[0];
39248+} __aligned(8);
39249+
39250+struct au_drinfo_fdata {
39251+ uint32_t magic;
39252+ struct au_drinfo drinfo;
39253+} __aligned(8);
39254+
39255+#define AUFS_DRINFO_MAGIC_V1 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x01)
39256+/* future */
39257+#define AUFS_DRINFO_MAGIC_V2 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x02)
39258+
39259+/* ---------------------------------------------------------------------- */
39260+
1e00d052 39261+struct aufs_wbr_fd {
9dbd164d
AM
39262+ uint32_t oflags;
39263+ int16_t brid;
1e00d052
AM
39264+} __aligned(8);
39265+
39266+/* ---------------------------------------------------------------------- */
39267+
027c5e7a 39268+struct aufs_ibusy {
9dbd164d
AM
39269+ uint64_t ino, h_ino;
39270+ int16_t bindex;
027c5e7a
AM
39271+} __aligned(8);
39272+
1e00d052
AM
39273+/* ---------------------------------------------------------------------- */
39274+
392086de
AM
39275+/* error code for move-down */
39276+/* the actual message strings are implemented in aufs-util.git */
39277+enum {
39278+ EAU_MVDOWN_OPAQUE = 1,
39279+ EAU_MVDOWN_WHITEOUT,
39280+ EAU_MVDOWN_UPPER,
39281+ EAU_MVDOWN_BOTTOM,
39282+ EAU_MVDOWN_NOUPPER,
39283+ EAU_MVDOWN_NOLOWERBR,
39284+ EAU_Last
39285+};
39286+
c2b27bf2 39287+/* flags for move-down */
392086de
AM
39288+#define AUFS_MVDOWN_DMSG 1
39289+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
39290+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
39291+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
39292+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
39293+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
39294+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
39295+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
39296+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
076b876e
AM
39297+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
39298+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
39299+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
39300+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
c2b27bf2 39301+
076b876e 39302+/* index for move-down */
392086de
AM
39303+enum {
39304+ AUFS_MVDOWN_UPPER,
39305+ AUFS_MVDOWN_LOWER,
39306+ AUFS_MVDOWN_NARRAY
39307+};
39308+
076b876e
AM
39309+/*
39310+ * additional info of move-down
39311+ * number of free blocks and inodes.
39312+ * subset of struct kstatfs, but smaller and always 64bit.
39313+ */
39314+struct aufs_stfs {
39315+ uint64_t f_blocks;
39316+ uint64_t f_bavail;
39317+ uint64_t f_files;
39318+ uint64_t f_ffree;
39319+};
39320+
39321+struct aufs_stbr {
39322+ int16_t brid; /* optional input */
39323+ int16_t bindex; /* output */
39324+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
39325+} __aligned(8);
39326+
c2b27bf2 39327+struct aufs_mvdown {
076b876e
AM
39328+ uint32_t flags; /* input/output */
39329+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
39330+ int8_t au_errno; /* output */
39331+} __aligned(8);
39332+
39333+/* ---------------------------------------------------------------------- */
39334+
39335+union aufs_brinfo {
39336+ /* PATH_MAX may differ between kernel-space and user-space */
39337+ char _spacer[4096];
392086de 39338+ struct {
076b876e
AM
39339+ int16_t id;
39340+ int perm;
39341+ char path[0];
39342+ };
c2b27bf2
AM
39343+} __aligned(8);
39344+
39345+/* ---------------------------------------------------------------------- */
39346+
7f207e10
AM
39347+#define AuCtlType 'A'
39348+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
39349+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
39350+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
39351+ struct aufs_wbr_fd)
027c5e7a 39352+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
39353+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
39354+ struct aufs_mvdown)
076b876e
AM
39355+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
39356+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
7f207e10
AM
39357+
39358+#endif /* __AUFS_TYPE_H__ */
2121bcd9 39359SPDX-License-Identifier: GPL-2.0
cd7a4cd9 39360aufs4.x-rcN loopback patch
5527c038
JR
39361
39362diff --git a/drivers/block/loop.c b/drivers/block/loop.c
ba1aed25 39363index a271e17e4b10..ee17c7577224 100644
5527c038
JR
39364--- a/drivers/block/loop.c
39365+++ b/drivers/block/loop.c
9f237c51 39366@@ -625,6 +625,15 @@ static inline void loop_update_dio(struct loop_device *lo)
8b6a4947 39367 lo->use_dio);
5527c038
JR
39368 }
39369
5527c038
JR
39370+static struct file *loop_real_file(struct file *file)
39371+{
39372+ struct file *f = NULL;
39373+
39374+ if (file->f_path.dentry->d_sb->s_op->real_loop)
39375+ f = file->f_path.dentry->d_sb->s_op->real_loop(file);
39376+ return f;
8b6a4947
AM
39377+}
39378+
c2c0f25c 39379 static void loop_reread_partitions(struct loop_device *lo,
8b6a4947
AM
39380 struct block_device *bdev)
39381 {
ba1aed25 39382@@ -678,6 +687,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
39383 unsigned int arg)
39384 {
e1106418 39385 struct file *file = NULL, *old_file;
5527c038 39386+ struct file *f, *virt_file = NULL, *old_virt_file;
5527c038 39387 int error;
ba1aed25 39388 bool partscan;
5527c038 39389
ba1aed25 39390@@ -697,12 +707,19 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
cd7a4cd9
AM
39391 file = fget(arg);
39392 if (!file)
e1106418 39393 goto out_err;
5527c038
JR
39394+ f = loop_real_file(file);
39395+ if (f) {
39396+ virt_file = file;
39397+ file = f;
39398+ get_file(file);
39399+ }
39400
cd7a4cd9
AM
39401 error = loop_validate_file(file, bdev);
39402 if (error)
e1106418 39403 goto out_err;
cd7a4cd9 39404
5527c038
JR
39405 old_file = lo->lo_backing_file;
39406+ old_virt_file = lo->lo_backing_virt_file;
39407
39408 error = -EINVAL;
39409
ba1aed25 39410@@ -714,6 +731,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
8b6a4947
AM
39411 blk_mq_freeze_queue(lo->lo_queue);
39412 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
39413 lo->lo_backing_file = file;
39414+ lo->lo_backing_virt_file = virt_file;
39415 lo->old_gfp_mask = mapping_gfp_mask(file->f_mapping);
39416 mapping_set_gfp_mask(file->f_mapping,
39417 lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
ba1aed25 39418@@ -727,6 +745,8 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
e1106418
JR
39419 * dependency.
39420 */
5527c038
JR
39421 fput(old_file);
39422+ if (old_virt_file)
39423+ fput(old_virt_file);
e1106418 39424 if (partscan)
c2c0f25c 39425 loop_reread_partitions(lo, bdev);
5527c038 39426 return 0;
ba1aed25 39427@@ -735,6 +755,8 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
e1106418
JR
39428 mutex_unlock(&loop_ctl_mutex);
39429 if (file)
39430 fput(file);
5527c038
JR
39431+ if (virt_file)
39432+ fput(virt_file);
5527c038
JR
39433 return error;
39434 }
e1106418 39435
9f237c51 39436@@ -921,7 +943,7 @@ static int loop_prepare_queue(struct loop_device *lo)
5527c038
JR
39437 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
39438 struct block_device *bdev, unsigned int arg)
39439 {
062440b3 39440- struct file *file;
5527c038
JR
39441+ struct file *file, *f, *virt_file = NULL;
39442 struct inode *inode;
39443 struct address_space *mapping;
8b6a4947 39444 int lo_flags = 0;
ba1aed25 39445@@ -936,6 +958,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
39446 file = fget(arg);
39447 if (!file)
39448 goto out;
39449+ f = loop_real_file(file);
39450+ if (f) {
39451+ virt_file = file;
39452+ file = f;
39453+ get_file(file);
39454+ }
39455
ba1aed25
AM
39456 error = mutex_lock_killable(&loop_ctl_mutex);
39457 if (error)
39458@@ -972,6 +1000,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
39459 lo->lo_device = bdev;
39460 lo->lo_flags = lo_flags;
39461 lo->lo_backing_file = file;
39462+ lo->lo_backing_virt_file = virt_file;
39463 lo->transfer = NULL;
39464 lo->ioctl = NULL;
39465 lo->lo_sizelimit = 0;
ba1aed25
AM
39466@@ -1009,6 +1038,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
39467 mutex_unlock(&loop_ctl_mutex);
e1106418 39468 out_putf:
5527c038
JR
39469 fput(file);
39470+ if (virt_file)
39471+ fput(virt_file);
e1106418 39472 out:
5527c038
JR
39473 /* This is safe: open() is still holding a reference. */
39474 module_put(THIS_MODULE);
ba1aed25
AM
39475@@ -1055,6 +1086,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
39476 static int __loop_clr_fd(struct loop_device *lo, bool release)
5527c038 39477 {
e1106418 39478 struct file *filp = NULL;
5527c038
JR
39479+ struct file *virt_filp = lo->lo_backing_virt_file;
39480 gfp_t gfp = lo->old_gfp_mask;
39481 struct block_device *bdev = lo->lo_device;
ba1aed25
AM
39482 int err = 0;
39483@@ -1078,6 +1110,7 @@ static int __loop_clr_fd(struct loop_device *lo, bool release)
5527c038 39484
5527c038 39485 spin_lock_irq(&lo->lo_lock);
5527c038
JR
39486 lo->lo_backing_file = NULL;
39487+ lo->lo_backing_virt_file = NULL;
39488 spin_unlock_irq(&lo->lo_lock);
39489
39490 loop_release_xfer(lo);
ba1aed25 39491@@ -1146,6 +1179,8 @@ static int __loop_clr_fd(struct loop_device *lo, bool release)
5527c038 39492 */
e1106418
JR
39493 if (filp)
39494 fput(filp);
5527c038
JR
39495+ if (virt_filp)
39496+ fput(virt_filp);
e1106418 39497 return err;
5527c038
JR
39498 }
39499
39500diff --git a/drivers/block/loop.h b/drivers/block/loop.h
ba1aed25 39501index af75a5ee4094..1e6ee5a4f623 100644
5527c038
JR
39502--- a/drivers/block/loop.h
39503+++ b/drivers/block/loop.h
39504@@ -46,7 +46,7 @@ struct loop_device {
39505 int (*ioctl)(struct loop_device *, int cmd,
39506 unsigned long arg);
39507
39508- struct file * lo_backing_file;
39509+ struct file * lo_backing_file, *lo_backing_virt_file;
39510 struct block_device *lo_device;
5527c038 39511 void *key_data;
8b6a4947 39512
5527c038 39513diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
ba1aed25 39514index 0309f0d502ff..19feb4f3cb5f 100644
5527c038
JR
39515--- a/fs/aufs/f_op.c
39516+++ b/fs/aufs/f_op.c
acd2b654 39517@@ -359,7 +359,7 @@ static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
5527c038
JR
39518 if (IS_ERR(h_file))
39519 goto out;
39520
39521- if (au_test_loopback_kthread()) {
39522+ if (0 && au_test_loopback_kthread()) {
39523 au_warn_loopback(h_file->f_path.dentry->d_sb);
39524 if (file->f_mapping != h_file->f_mapping) {
39525 file->f_mapping = h_file->f_mapping;
39526diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
ba1aed25 39527index f05887d612fd..6f0505723cb4 100644
5527c038
JR
39528--- a/fs/aufs/loop.c
39529+++ b/fs/aufs/loop.c
2121bcd9 39530@@ -133,3 +133,19 @@ void au_loopback_fin(void)
79b8bda9 39531 symbol_put(loop_backing_file);
9f237c51 39532 au_kfree_try_rcu(au_warn_loopback_array);
5527c038
JR
39533 }
39534+
39535+/* ---------------------------------------------------------------------- */
39536+
39537+/* support the loopback block device insude aufs */
39538+
39539+struct file *aufs_real_loop(struct file *file)
39540+{
39541+ struct file *f;
39542+
39543+ BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
39544+ fi_read_lock(file);
39545+ f = au_hf_top(file);
39546+ fi_read_unlock(file);
39547+ AuDebugOn(!f);
39548+ return f;
39549+}
39550diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
eca801bf 39551index c42cbe71ed4b..255e2d3763e7 100644
5527c038
JR
39552--- a/fs/aufs/loop.h
39553+++ b/fs/aufs/loop.h
eca801bf 39554@@ -26,6 +26,8 @@ void au_warn_loopback(struct super_block *h_sb);
5527c038
JR
39555
39556 int au_loopback_init(void);
39557 void au_loopback_fin(void);
39558+
39559+struct file *aufs_real_loop(struct file *file);
39560 #else
eca801bf
AM
39561 AuStub(struct file *, loop_backing_file, return NULL)
39562
39563@@ -36,6 +38,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
5527c038
JR
39564
39565 AuStubInt0(au_loopback_init, void)
39566 AuStubVoid(au_loopback_fin, void)
39567+
39568+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
39569 #endif /* BLK_DEV_LOOP */
39570
39571 #endif /* __KERNEL__ */
39572diff --git a/fs/aufs/super.c b/fs/aufs/super.c
eca801bf 39573index 73255f63b80c..f04e211cbf89 100644
5527c038
JR
39574--- a/fs/aufs/super.c
39575+++ b/fs/aufs/super.c
eca801bf 39576@@ -846,7 +846,10 @@ static const struct super_operations aufs_sop = {
5527c038
JR
39577 .statfs = aufs_statfs,
39578 .put_super = aufs_put_super,
39579 .sync_fs = aufs_sync_fs,
39580- .remount_fs = aufs_remount_fs
39581+ .remount_fs = aufs_remount_fs,
39582+#ifdef CONFIG_AUFS_BDEV_LOOP
39583+ .real_loop = aufs_real_loop
39584+#endif
39585 };
39586
39587 /* ---------------------------------------------------------------------- */
39588diff --git a/include/linux/fs.h b/include/linux/fs.h
ba1aed25 39589index 5db265e7d35a..8895cd2343e3 100644
5527c038
JR
39590--- a/include/linux/fs.h
39591+++ b/include/linux/fs.h
ba1aed25 39592@@ -1937,6 +1937,10 @@ struct super_operations {
5527c038
JR
39593 struct shrink_control *);
39594 long (*free_cached_objects)(struct super_block *,
39595 struct shrink_control *);
39596+#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
39597+ /* and aufs */
39598+ struct file *(*real_loop)(struct file *);
39599+#endif
39600 };
39601
39602 /*
This page took 7.355141 seconds and 4 git commands to generate.