]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs4.patch
- rel 2; make xfs memory reclaim configurable; https://github.com/bobrik/linux/pull...
[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
cd7a4cd9 5index ac474a6..284cee9 100644
7f207e10
AM
6--- a/fs/Kconfig
7+++ b/fs/Kconfig
cd7a4cd9 8@@ -255,6 +255,7 @@ source "fs/pstore/Kconfig"
5527c038 9 source "fs/sysv/Kconfig"
7e9cd9fe 10 source "fs/ufs/Kconfig"
7f207e10
AM
11 source "fs/exofs/Kconfig"
12+source "fs/aufs/Kconfig"
13
14 endif # MISC_FILESYSTEMS
15
16diff --git a/fs/Makefile b/fs/Makefile
cd7a4cd9 17index 293733f..12d19d0 100644
7f207e10
AM
18--- a/fs/Makefile
19+++ b/fs/Makefile
be118d29 20@@ -128,3 +128,4 @@ obj-y += exofs/ # Multiple modules
7f207e10 21 obj-$(CONFIG_CEPH_FS) += ceph/
bf0370f2 22 obj-$(CONFIG_PSTORE) += pstore/
c06a8ce3 23 obj-$(CONFIG_EFIVAR_FS) += efivarfs/
86dc4139 24+obj-$(CONFIG_AUFS_FS) += aufs/
2121bcd9 25SPDX-License-Identifier: GPL-2.0
cd7a4cd9 26aufs4.x-rcN base patch
7f207e10 27
c1595e42 28diff --git a/MAINTAINERS b/MAINTAINERS
acd2b654 29index 6ac000c..16404bb 100644
c1595e42
JR
30--- a/MAINTAINERS
31+++ b/MAINTAINERS
acd2b654 32@@ -2605,6 +2605,19 @@ F: include/linux/audit.h
c1595e42
JR
33 F: include/uapi/linux/audit.h
34 F: kernel/audit*
35
36+AUFS (advanced multi layered unification filesystem) FILESYSTEM
37+M: "J. R. Okajima" <hooanon05g@gmail.com>
38+L: linux-unionfs@vger.kernel.org
39+L: aufs-users@lists.sourceforge.net (members only)
40+W: http://aufs.sourceforge.net
5527c038 41+T: git://github.com/sfjro/aufs4-linux.git
c1595e42
JR
42+S: Supported
43+F: Documentation/filesystems/aufs/
44+F: Documentation/ABI/testing/debugfs-aufs
45+F: Documentation/ABI/testing/sysfs-aufs
46+F: fs/aufs/
47+F: include/uapi/linux/aufs_type.h
48+
49 AUXILIARY DISPLAY DRIVERS
50 M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
cd7a4cd9 51 S: Maintained
392086de 52diff --git a/drivers/block/loop.c b/drivers/block/loop.c
acd2b654 53index ea9debf..9e534a3 100644
392086de
AM
54--- a/drivers/block/loop.c
55+++ b/drivers/block/loop.c
acd2b654 56@@ -739,6 +739,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
cd7a4cd9 57 return error;
392086de
AM
58 }
59
60+/*
61+ * for AUFS
62+ * no get/put for file.
63+ */
64+struct file *loop_backing_file(struct super_block *sb)
65+{
66+ struct file *ret;
67+ struct loop_device *l;
68+
69+ ret = NULL;
70+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
71+ l = sb->s_bdev->bd_disk->private_data;
72+ ret = l->lo_backing_file;
73+ }
74+ return ret;
75+}
febd17d6 76+EXPORT_SYMBOL_GPL(loop_backing_file);
392086de
AM
77+
78 /* loop sysfs attributes */
79
80 static ssize_t loop_attr_show(struct device *dev, char *page,
c1595e42 81diff --git a/fs/dcache.c b/fs/dcache.c
acd2b654 82index 2e7e8d8..9f57bd8 100644
c1595e42
JR
83--- a/fs/dcache.c
84+++ b/fs/dcache.c
acd2b654 85@@ -1238,7 +1238,7 @@ enum d_walk_ret {
c1595e42 86 *
cd7a4cd9 87 * The @enter() callbacks are called with d_lock held.
c1595e42
JR
88 */
89-static void d_walk(struct dentry *parent, void *data,
90+void d_walk(struct dentry *parent, void *data,
cd7a4cd9 91 enum d_walk_ret (*enter)(void *, struct dentry *))
c1595e42 92 {
cd7a4cd9 93 struct dentry *this_parent;
febd17d6 94diff --git a/fs/fcntl.c b/fs/fcntl.c
acd2b654 95index 4137d96..c91b3e3 100644
febd17d6
JR
96--- a/fs/fcntl.c
97+++ b/fs/fcntl.c
2121bcd9 98@@ -32,7 +32,7 @@
febd17d6
JR
99
100 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
101
102-static int setfl(int fd, struct file * filp, unsigned long arg)
103+int setfl(int fd, struct file * filp, unsigned long arg)
104 {
105 struct inode * inode = file_inode(filp);
106 int error = 0;
2121bcd9 107@@ -63,6 +63,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
febd17d6
JR
108
109 if (filp->f_op->check_flags)
110 error = filp->f_op->check_flags(arg);
111+ if (!error && filp->f_op->setfl)
112+ error = filp->f_op->setfl(filp, arg);
113 if (error)
114 return error;
115
5afbbe0d 116diff --git a/fs/inode.c b/fs/inode.c
acd2b654 117index 42f6d25..fa6ae6a 100644
5afbbe0d
AM
118--- a/fs/inode.c
119+++ b/fs/inode.c
acd2b654 120@@ -1657,7 +1657,7 @@ EXPORT_SYMBOL(generic_update_time);
5afbbe0d
AM
121 * This does the actual work of updating an inodes time or version. Must have
122 * had called mnt_want_write() before calling this.
123 */
cd7a4cd9
AM
124-static int update_time(struct inode *inode, struct timespec64 *time, int flags)
125+int update_time(struct inode *inode, struct timespec64 *time, int flags)
5afbbe0d 126 {
cd7a4cd9 127 int (*update_time)(struct inode *, struct timespec64 *, int);
5afbbe0d 128
8b6a4947 129diff --git a/fs/namespace.c b/fs/namespace.c
acd2b654 130index 9918655..72c93f3 100644
8b6a4947
AM
131--- a/fs/namespace.c
132+++ b/fs/namespace.c
acd2b654 133@@ -770,6 +770,12 @@ static inline int check_mnt(struct mount *mnt)
8b6a4947
AM
134 return mnt->mnt_ns == current->nsproxy->mnt_ns;
135 }
136
137+/* for aufs, CONFIG_AUFS_BR_FUSE */
138+int is_current_mnt_ns(struct vfsmount *mnt)
139+{
140+ return check_mnt(real_mount(mnt));
141+}
142+
143 /*
144 * vfsmount lock must be held for write
145 */
5527c038 146diff --git a/fs/read_write.c b/fs/read_write.c
acd2b654 147index 8a2737f..42f64cc 100644
5527c038
JR
148--- a/fs/read_write.c
149+++ b/fs/read_write.c
b00004a5 150@@ -489,6 +489,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
8b6a4947 151 return -EINVAL;
5527c038 152 }
5527c038
JR
153
154+vfs_readf_t vfs_readf(struct file *file)
155+{
156+ const struct file_operations *fop = file->f_op;
157+
158+ if (fop->read)
159+ return fop->read;
160+ if (fop->read_iter)
161+ return new_sync_read;
162+ return ERR_PTR(-ENOSYS);
163+}
164+
165+vfs_writef_t vfs_writef(struct file *file)
166+{
167+ const struct file_operations *fop = file->f_op;
168+
169+ if (fop->write)
170+ return fop->write;
171+ if (fop->write_iter)
172+ return new_sync_write;
173+ return ERR_PTR(-ENOSYS);
174+}
175+
8b6a4947 176 ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
5527c038
JR
177 {
178 mm_segment_t old_fs;
7f207e10 179diff --git a/fs/splice.c b/fs/splice.c
cd7a4cd9 180index b3daa97..1dd7f96 100644
7f207e10
AM
181--- a/fs/splice.c
182+++ b/fs/splice.c
cd7a4cd9 183@@ -838,8 +838,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
184 /*
185 * Attempt to initiate a splice from pipe to file.
186 */
187-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
188- loff_t *ppos, size_t len, unsigned int flags)
189+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
190+ loff_t *ppos, size_t len, unsigned int flags)
191 {
192 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
193 loff_t *, size_t, unsigned int);
cd7a4cd9 194@@ -855,9 +855,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
195 /*
196 * Attempt to initiate a splice from a file to a pipe.
197 */
198-static long do_splice_to(struct file *in, loff_t *ppos,
199- struct pipe_inode_info *pipe, size_t len,
200- unsigned int flags)
201+long do_splice_to(struct file *in, loff_t *ppos,
202+ struct pipe_inode_info *pipe, size_t len,
203+ unsigned int flags)
204 {
205 ssize_t (*splice_read)(struct file *, loff_t *,
206 struct pipe_inode_info *, size_t, unsigned int);
a2654f78 207diff --git a/fs/sync.c b/fs/sync.c
b00004a5 208index b54e054..2860782 100644
a2654f78
AM
209--- a/fs/sync.c
210+++ b/fs/sync.c
2121bcd9 211@@ -28,7 +28,7 @@
a2654f78
AM
212 * wait == 1 case since in that case write_inode() functions do
213 * sync_dirty_buffer() and thus effectively write one block at a time.
214 */
215-static int __sync_filesystem(struct super_block *sb, int wait)
216+int __sync_filesystem(struct super_block *sb, int wait)
217 {
218 if (wait)
219 sync_inodes_sb(sb);
5527c038 220diff --git a/include/linux/fs.h b/include/linux/fs.h
acd2b654 221index 897eae8..7fb92a9 100644
5527c038
JR
222--- a/include/linux/fs.h
223+++ b/include/linux/fs.h
acd2b654 224@@ -1286,6 +1286,7 @@ extern void fasync_free(struct fasync_struct *);
febd17d6
JR
225 /* can be called from interrupts */
226 extern void kill_fasync(struct fasync_struct **, int, int);
227
228+extern int setfl(int fd, struct file * filp, unsigned long arg);
229 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
3c1bdaff 230 extern int f_setown(struct file *filp, unsigned long arg, int force);
febd17d6 231 extern void f_delown(struct file *filp);
acd2b654 232@@ -1747,6 +1748,7 @@ struct file_operations {
febd17d6
JR
233 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
234 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
235 int (*check_flags)(int);
236+ int (*setfl)(struct file *, unsigned long);
237 int (*flock) (struct file *, int, struct file_lock *);
238 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
239 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
acd2b654 240@@ -1818,6 +1820,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
5527c038
JR
241 struct iovec *fast_pointer,
242 struct iovec **ret_pointer);
243
244+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *);
245+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t,
246+ loff_t *);
247+vfs_readf_t vfs_readf(struct file *file);
248+vfs_writef_t vfs_writef(struct file *file);
249+
250 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
5527c038 251 extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
8b6a4947 252 extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
acd2b654 253@@ -2243,6 +2251,7 @@ extern int current_umask(void);
5afbbe0d
AM
254 extern void ihold(struct inode * inode);
255 extern void iput(struct inode *);
cd7a4cd9
AM
256 extern int generic_update_time(struct inode *, struct timespec64 *, int);
257+extern int update_time(struct inode *, struct timespec64 *, int);
5afbbe0d
AM
258
259 /* /sys/fs */
260 extern struct kobject *fs_kobj;
acd2b654 261@@ -2530,6 +2539,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb)
a2654f78
AM
262 return false;
263 }
264 #endif
265+extern int __sync_filesystem(struct super_block *, int);
266 extern int sync_filesystem(struct super_block *);
267 extern const struct file_operations def_blk_fops;
268 extern const struct file_operations def_chr_fops;
8b6a4947 269diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
acd2b654 270index b0d0b51..f73ffaa 100644
8b6a4947
AM
271--- a/include/linux/lockdep.h
272+++ b/include/linux/lockdep.h
be118d29 273@@ -313,6 +313,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock,
8b6a4947
AM
274 return lock->key == key;
275 }
276
277+struct lock_class *lockdep_hlock_class(struct held_lock *hlock);
278+
279 /*
280 * Acquire a lock.
281 *
be118d29 282@@ -439,6 +441,7 @@ struct lockdep_map { };
8b6a4947
AM
283
284 #define lockdep_depth(tsk) (0)
285
286+#define lockdep_is_held(lock) (1)
287 #define lockdep_is_held_type(l, r) (1)
288
289 #define lockdep_assert_held(l) do { (void)(l); } while (0)
290diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
2121bcd9 291index 3594208..24f5fd1 100644
8b6a4947
AM
292--- a/include/linux/mnt_namespace.h
293+++ b/include/linux/mnt_namespace.h
2121bcd9 294@@ -6,11 +6,14 @@
8b6a4947
AM
295 struct mnt_namespace;
296 struct fs_struct;
297 struct user_namespace;
298+struct vfsmount;
299
300 extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *,
301 struct user_namespace *, struct fs_struct *);
302 extern void put_mnt_ns(struct mnt_namespace *ns);
303
304+extern int is_current_mnt_ns(struct vfsmount *mnt);
305+
306 extern const struct file_operations proc_mounts_operations;
307 extern const struct file_operations proc_mountinfo_operations;
308 extern const struct file_operations proc_mountstats_operations;
1e00d052 309diff --git a/include/linux/splice.h b/include/linux/splice.h
2121bcd9 310index 74b4911..19789fb 100644
1e00d052
AM
311--- a/include/linux/splice.h
312+++ b/include/linux/splice.h
2121bcd9 313@@ -87,4 +87,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
314
315 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
106341ce 316 extern const struct pipe_buf_operations default_pipe_buf_ops;
1e00d052
AM
317+
318+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
319+ loff_t *ppos, size_t len, unsigned int flags);
320+extern long do_splice_to(struct file *in, loff_t *ppos,
321+ struct pipe_inode_info *pipe, size_t len,
322+ unsigned int flags);
323 #endif
8b6a4947 324diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
acd2b654 325index dd13f86..fa6f559 100644
8b6a4947
AM
326--- a/kernel/locking/lockdep.c
327+++ b/kernel/locking/lockdep.c
be118d29 328@@ -140,7 +140,7 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
8b6a4947
AM
329 unsigned long nr_lock_classes;
330 static struct lock_class lock_classes[MAX_LOCKDEP_KEYS];
331
332-static inline struct lock_class *hlock_class(struct held_lock *hlock)
333+inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
334 {
335 if (!hlock->class_idx) {
336 /*
be118d29 337@@ -151,6 +151,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
8b6a4947
AM
338 }
339 return lock_classes + hlock->class_idx - 1;
340 }
341+#define hlock_class(hlock) lockdep_hlock_class(hlock)
342
343 #ifdef CONFIG_LOCK_STAT
344 static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats);
2121bcd9 345SPDX-License-Identifier: GPL-2.0
cd7a4cd9 346aufs4.x-rcN mmap patch
fb47a38f 347
c1595e42 348diff --git a/fs/proc/base.c b/fs/proc/base.c
acd2b654 349index 7e9f07bf..3ab5901 100644
c1595e42
JR
350--- a/fs/proc/base.c
351+++ b/fs/proc/base.c
acd2b654 352@@ -2016,7 +2016,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
c1595e42
JR
353 down_read(&mm->mmap_sem);
354 vma = find_exact_vma(mm, vm_start, vm_end);
355 if (vma && vma->vm_file) {
356- *path = vma->vm_file->f_path;
357+ *path = vma_pr_or_file(vma)->f_path;
358 path_get(path);
359 rc = 0;
360 }
fb47a38f 361diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
cd7a4cd9 362index 3b63be6..fb9913b 100644
fb47a38f
JR
363--- a/fs/proc/nommu.c
364+++ b/fs/proc/nommu.c
076b876e 365@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
fb47a38f
JR
366 file = region->vm_file;
367
368 if (file) {
369- struct inode *inode = file_inode(region->vm_file);
370+ struct inode *inode;
076b876e 371+
fb47a38f
JR
372+ file = vmr_pr_or_file(region);
373+ inode = file_inode(file);
374 dev = inode->i_sb->s_dev;
375 ino = inode->i_ino;
376 }
377diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
acd2b654 378index 5ea1d64..7865a470 100644
fb47a38f
JR
379--- a/fs/proc/task_mmu.c
380+++ b/fs/proc/task_mmu.c
acd2b654 381@@ -305,7 +305,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
fb47a38f
JR
382 const char *name = NULL;
383
384 if (file) {
385- struct inode *inode = file_inode(vma->vm_file);
386+ struct inode *inode;
076b876e 387+
fb47a38f
JR
388+ file = vma_pr_or_file(vma);
389+ inode = file_inode(file);
390 dev = inode->i_sb->s_dev;
391 ino = inode->i_ino;
392 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
acd2b654 393@@ -1727,7 +1730,7 @@ static int show_numa_map(struct seq_file *m, void *v)
076b876e
AM
394 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
395 struct vm_area_struct *vma = v;
396 struct numa_maps *md = &numa_priv->md;
397- struct file *file = vma->vm_file;
398+ struct file *file = vma_pr_or_file(vma);
076b876e 399 struct mm_struct *mm = vma->vm_mm;
7e9cd9fe
AM
400 struct mm_walk walk = {
401 .hugetlb_entry = gather_hugetlb_stats,
fb47a38f 402diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
acd2b654 403index 0b63d68..400d1c5 100644
fb47a38f
JR
404--- a/fs/proc/task_nommu.c
405+++ b/fs/proc/task_nommu.c
acd2b654 406@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
fb47a38f
JR
407 file = vma->vm_file;
408
409 if (file) {
410- struct inode *inode = file_inode(vma->vm_file);
411+ struct inode *inode;
076b876e 412+
b912730e 413+ file = vma_pr_or_file(vma);
fb47a38f
JR
414+ inode = file_inode(file);
415 dev = inode->i_sb->s_dev;
416 ino = inode->i_ino;
417 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
418diff --git a/include/linux/mm.h b/include/linux/mm.h
acd2b654 419index 0416a72..4a298a9 100644
fb47a38f
JR
420--- a/include/linux/mm.h
421+++ b/include/linux/mm.h
acd2b654 422@@ -1440,6 +1440,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
a3232e84 423 unmap_mapping_range(mapping, holebegin, holelen, 0);
fb47a38f 424 }
fb47a38f 425
076b876e
AM
426+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
427+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
f2c43d5f 428+ int);
076b876e
AM
429+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
430+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
fb47a38f 431+
f2c43d5f
AM
432+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
433+ __LINE__)
434+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
435+ __LINE__)
436+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
437+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
b912730e
AM
438+
439+#ifndef CONFIG_MMU
076b876e
AM
440+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
441+extern void vmr_do_fput(struct vm_region *, const char[], int);
442+
f2c43d5f
AM
443+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
444+ __LINE__)
445+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
b912730e 446+#endif /* !CONFIG_MMU */
fb47a38f 447+
a3232e84
JR
448 extern int access_process_vm(struct task_struct *tsk, unsigned long addr,
449 void *buf, int len, unsigned int gup_flags);
fb47a38f 450 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
fb47a38f 451diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
acd2b654 452index 5ed8f62..0122975 100644
fb47a38f
JR
453--- a/include/linux/mm_types.h
454+++ b/include/linux/mm_types.h
acd2b654 455@@ -239,6 +239,7 @@ struct vm_region {
fb47a38f
JR
456 unsigned long vm_top; /* region allocated to here */
457 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
458 struct file *vm_file; /* the backing file or NULL */
459+ struct file *vm_prfile; /* the virtual backing file or NULL */
460
461 int vm_usage; /* region usage count (access under nommu_region_sem) */
462 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
acd2b654 463@@ -313,6 +314,7 @@ struct vm_area_struct {
fb47a38f 464 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
5afbbe0d 465 units */
fb47a38f
JR
466 struct file * vm_file; /* File we map to (can be NULL). */
467+ struct file *vm_prfile; /* shadow of vm_file */
468 void * vm_private_data; /* was vm_pte (shared mem) */
469
8b6a4947 470 atomic_long_t swap_readahead_info;
fb47a38f 471diff --git a/kernel/fork.c b/kernel/fork.c
acd2b654 472index f0b5847..fa562c3 100644
fb47a38f
JR
473--- a/kernel/fork.c
474+++ b/kernel/fork.c
acd2b654 475@@ -505,7 +505,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
fb47a38f
JR
476 struct inode *inode = file_inode(file);
477 struct address_space *mapping = file->f_mapping;
478
479- get_file(file);
480+ vma_get_file(tmp);
481 if (tmp->vm_flags & VM_DENYWRITE)
482 atomic_dec(&inode->i_writecount);
2000de60 483 i_mmap_lock_write(mapping);
076b876e 484diff --git a/mm/Makefile b/mm/Makefile
acd2b654 485index 26ef77a..b2869af 100644
076b876e
AM
486--- a/mm/Makefile
487+++ b/mm/Makefile
acd2b654 488@@ -39,7 +39,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \
076b876e 489 mm_init.o mmu_context.o percpu.o slab_common.o \
b00004a5 490 compaction.o vmacache.o \
076b876e 491 interval_tree.o list_lru.o workingset.o \
7e9cd9fe
AM
492- debug.o $(mmu-y)
493+ prfile.o debug.o $(mmu-y)
076b876e
AM
494
495 obj-y += init-mm.o
496
fb47a38f 497diff --git a/mm/filemap.c b/mm/filemap.c
cd7a4cd9 498index 52517f2..250f675 100644
fb47a38f
JR
499--- a/mm/filemap.c
500+++ b/mm/filemap.c
cd7a4cd9
AM
501@@ -2700,7 +2700,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf)
502 vm_fault_t ret = VM_FAULT_LOCKED;
fb47a38f
JR
503
504 sb_start_pagefault(inode->i_sb);
521ced18
JR
505- file_update_time(vmf->vma->vm_file);
506+ vma_file_update_time(vmf->vma);
fb47a38f
JR
507 lock_page(page);
508 if (page->mapping != inode->i_mapping) {
509 unlock_page(page);
fb47a38f 510diff --git a/mm/mmap.c b/mm/mmap.c
acd2b654 511index f7cd9cb..515e88a 100644
fb47a38f
JR
512--- a/mm/mmap.c
513+++ b/mm/mmap.c
c4adf169 514@@ -180,7 +180,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
fb47a38f
JR
515 if (vma->vm_ops && vma->vm_ops->close)
516 vma->vm_ops->close(vma);
517 if (vma->vm_file)
518- fput(vma->vm_file);
519+ vma_fput(vma);
520 mpol_put(vma_policy(vma));
cd7a4cd9 521 vm_area_free(vma);
fb47a38f 522 return next;
c4adf169 523@@ -905,7 +905,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
fb47a38f
JR
524 if (remove_next) {
525 if (file) {
526 uprobe_munmap(next, next->vm_start, next->vm_end);
527- fput(file);
528+ vma_fput(vma);
529 }
530 if (next->anon_vma)
531 anon_vma_merge(vma, next);
acd2b654 532@@ -1821,8 +1821,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
35939ee7
JR
533 return addr;
534
fb47a38f 535 unmap_and_free_vma:
fb47a38f
JR
536+ vma_fput(vma);
537 vma->vm_file = NULL;
538- fput(file);
539
540 /* Undo any partial mapping done by a device driver. */
541 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
acd2b654 542@@ -2641,7 +2641,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
543 goto out_free_mpol;
544
545 if (new->vm_file)
546- get_file(new->vm_file);
547+ vma_get_file(new);
548
549 if (new->vm_ops && new->vm_ops->open)
550 new->vm_ops->open(new);
acd2b654 551@@ -2660,7 +2660,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
552 if (new->vm_ops && new->vm_ops->close)
553 new->vm_ops->close(new);
554 if (new->vm_file)
555- fput(new->vm_file);
556+ vma_fput(new);
557 unlink_anon_vmas(new);
558 out_free_mpol:
559 mpol_put(vma_policy(new));
acd2b654 560@@ -2822,7 +2822,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
7e9cd9fe
AM
561 struct vm_area_struct *vma;
562 unsigned long populate = 0;
563 unsigned long ret = -EINVAL;
564- struct file *file;
5afbbe0d 565+ struct file *file, *prfile;
7e9cd9fe 566
cd7a4cd9 567 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n",
5afbbe0d 568 current->comm, current->pid);
acd2b654 569@@ -2897,10 +2897,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
febd17d6 570 }
7e9cd9fe
AM
571 }
572
573- file = get_file(vma->vm_file);
574+ vma_get_file(vma);
5afbbe0d
AM
575+ file = vma->vm_file;
576+ prfile = vma->vm_prfile;
7e9cd9fe 577 ret = do_mmap_pgoff(vma->vm_file, start, size,
521ced18 578 prot, flags, pgoff, &populate, NULL);
5afbbe0d
AM
579+ if (!IS_ERR_VALUE(ret) && file && prfile) {
580+ struct vm_area_struct *new_vma;
581+
582+ new_vma = find_vma(mm, ret);
583+ if (!new_vma->vm_prfile)
584+ new_vma->vm_prfile = prfile;
585+ if (new_vma != vma)
586+ get_file(prfile);
587+ }
588+ /*
589+ * two fput()s instead of vma_fput(vma),
590+ * coz vma may not be available anymore.
591+ */
592 fput(file);
593+ if (prfile)
594+ fput(prfile);
7e9cd9fe
AM
595 out:
596 up_write(&mm->mmap_sem);
597 if (populate)
acd2b654 598@@ -3206,7 +3223,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
79b8bda9
AM
599 if (anon_vma_clone(new_vma, vma))
600 goto out_free_mempol;
601 if (new_vma->vm_file)
602- get_file(new_vma->vm_file);
603+ vma_get_file(new_vma);
604 if (new_vma->vm_ops && new_vma->vm_ops->open)
605 new_vma->vm_ops->open(new_vma);
606 vma_link(mm, new_vma, prev, rb_link, rb_parent);
fb47a38f 607diff --git a/mm/nommu.c b/mm/nommu.c
acd2b654 608index e4aac33..b27b200 100644
fb47a38f
JR
609--- a/mm/nommu.c
610+++ b/mm/nommu.c
acd2b654 611@@ -625,7 +625,7 @@ static void __put_nommu_region(struct vm_region *region)
fb47a38f
JR
612 up_write(&nommu_region_sem);
613
614 if (region->vm_file)
615- fput(region->vm_file);
616+ vmr_fput(region);
617
618 /* IO memory and memory shared directly out of the pagecache
619 * from ramfs/tmpfs mustn't be released here */
acd2b654 620@@ -763,7 +763,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
fb47a38f
JR
621 if (vma->vm_ops && vma->vm_ops->close)
622 vma->vm_ops->close(vma);
623 if (vma->vm_file)
624- fput(vma->vm_file);
625+ vma_fput(vma);
626 put_nommu_region(vma->vm_region);
cd7a4cd9 627 vm_area_free(vma);
fb47a38f 628 }
acd2b654 629@@ -1286,7 +1286,7 @@ unsigned long do_mmap(struct file *file,
fb47a38f
JR
630 goto error_just_free;
631 }
632 }
633- fput(region->vm_file);
634+ vmr_fput(region);
635 kmem_cache_free(vm_region_jar, region);
636 region = pregion;
637 result = start;
acd2b654 638@@ -1361,7 +1361,7 @@ unsigned long do_mmap(struct file *file,
fb47a38f
JR
639 up_write(&nommu_region_sem);
640 error:
641 if (region->vm_file)
642- fput(region->vm_file);
643+ vmr_fput(region);
644 kmem_cache_free(vm_region_jar, region);
645 if (vma->vm_file)
cd7a4cd9 646 fput(vma->vm_file);
076b876e
AM
647diff --git a/mm/prfile.c b/mm/prfile.c
648new file mode 100644
cd7a4cd9 649index 0000000..a27ac36
076b876e
AM
650--- /dev/null
651+++ b/mm/prfile.c
2121bcd9 652@@ -0,0 +1,86 @@
cd7a4cd9 653+// SPDX-License-Identifier: GPL-2.0
076b876e 654+/*
1c60b727
AM
655+ * Mainly for aufs which mmap(2) different file and wants to print different
656+ * path in /proc/PID/maps.
076b876e
AM
657+ * Call these functions via macros defined in linux/mm.h.
658+ *
659+ * See Documentation/filesystems/aufs/design/06mmap.txt
660+ *
b00004a5 661+ * Copyright (c) 2014-2018 Junjro R. Okajima
076b876e
AM
662+ * Copyright (c) 2014 Ian Campbell
663+ */
664+
665+#include <linux/mm.h>
666+#include <linux/file.h>
667+#include <linux/fs.h>
668+
669+/* #define PRFILE_TRACE */
670+static inline void prfile_trace(struct file *f, struct file *pr,
671+ const char func[], int line, const char func2[])
672+{
673+#ifdef PRFILE_TRACE
674+ if (pr)
1c60b727 675+ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f);
076b876e
AM
676+#endif
677+}
678+
076b876e
AM
679+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
680+ int line)
681+{
682+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
683+
684+ prfile_trace(f, pr, func, line, __func__);
685+ file_update_time(f);
686+ if (f && pr)
687+ file_update_time(pr);
688+}
689+
690+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
691+ int line)
692+{
693+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
694+
695+ prfile_trace(f, pr, func, line, __func__);
696+ return (f && pr) ? pr : f;
697+}
698+
699+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
700+{
701+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
702+
703+ prfile_trace(f, pr, func, line, __func__);
704+ get_file(f);
705+ if (f && pr)
706+ get_file(pr);
707+}
708+
709+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
710+{
711+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
712+
713+ prfile_trace(f, pr, func, line, __func__);
714+ fput(f);
715+ if (f && pr)
716+ fput(pr);
717+}
b912730e
AM
718+
719+#ifndef CONFIG_MMU
076b876e
AM
720+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
721+ int line)
722+{
723+ struct file *f = region->vm_file, *pr = region->vm_prfile;
724+
725+ prfile_trace(f, pr, func, line, __func__);
726+ return (f && pr) ? pr : f;
727+}
728+
729+void vmr_do_fput(struct vm_region *region, const char func[], int line)
730+{
731+ struct file *f = region->vm_file, *pr = region->vm_prfile;
732+
733+ prfile_trace(f, pr, func, line, __func__);
734+ fput(f);
735+ if (f && pr)
736+ fput(pr);
737+}
b912730e 738+#endif /* !CONFIG_MMU */
2121bcd9 739SPDX-License-Identifier: GPL-2.0
cd7a4cd9 740aufs4.x-rcN standalone patch
7f207e10 741
c1595e42 742diff --git a/fs/dcache.c b/fs/dcache.c
acd2b654 743index 9f57bd8..328a136 100644
c1595e42
JR
744--- a/fs/dcache.c
745+++ b/fs/dcache.c
acd2b654 746@@ -1343,6 +1343,7 @@ void d_walk(struct dentry *parent, void *data,
c1595e42
JR
747 seq = 1;
748 goto again;
749 }
febd17d6 750+EXPORT_SYMBOL_GPL(d_walk);
c1595e42 751
a2654f78
AM
752 struct check_mount {
753 struct vfsmount *mnt;
acd2b654 754@@ -2837,6 +2838,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2)
f2c43d5f
AM
755
756 write_sequnlock(&rename_lock);
757 }
758+EXPORT_SYMBOL_GPL(d_exchange);
759
760 /**
761 * d_ancestor - search for an ancestor
79b8bda9 762diff --git a/fs/exec.c b/fs/exec.c
acd2b654 763index 1ebf6e5..a72c294 100644
79b8bda9
AM
764--- a/fs/exec.c
765+++ b/fs/exec.c
521ced18 766@@ -109,6 +109,7 @@ bool path_noexec(const struct path *path)
79b8bda9
AM
767 return (path->mnt->mnt_flags & MNT_NOEXEC) ||
768 (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
769 }
febd17d6 770+EXPORT_SYMBOL_GPL(path_noexec);
79b8bda9
AM
771
772 #ifdef CONFIG_USELIB
773 /*
febd17d6 774diff --git a/fs/fcntl.c b/fs/fcntl.c
acd2b654 775index c91b3e3..7751309 100644
febd17d6
JR
776--- a/fs/fcntl.c
777+++ b/fs/fcntl.c
2121bcd9 778@@ -85,6 +85,7 @@ int setfl(int fd, struct file * filp, unsigned long arg)
febd17d6
JR
779 out:
780 return error;
781 }
782+EXPORT_SYMBOL_GPL(setfl);
783
784 static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
785 int force)
b912730e 786diff --git a/fs/file_table.c b/fs/file_table.c
acd2b654 787index e49af4c..569020f 100644
b912730e
AM
788--- a/fs/file_table.c
789+++ b/fs/file_table.c
acd2b654 790@@ -161,6 +161,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred)
b912730e
AM
791 }
792 return ERR_PTR(-ENFILE);
793 }
acd2b654 794+EXPORT_SYMBOL_GPL(alloc_empty_file);
b912730e 795
acd2b654
AM
796 /*
797 * Variant of alloc_empty_file() that doesn't check and modify nr_files.
798@@ -323,6 +324,7 @@ void flush_delayed_fput(void)
8cdd5066
JR
799 {
800 delayed_fput(NULL);
801 }
febd17d6 802+EXPORT_SYMBOL_GPL(flush_delayed_fput);
8cdd5066
JR
803
804 static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
805
acd2b654 806@@ -365,6 +367,7 @@ void __fput_sync(struct file *file)
8cdd5066
JR
807 }
808
809 EXPORT_SYMBOL(fput);
febd17d6 810+EXPORT_SYMBOL_GPL(__fput_sync);
8cdd5066 811
79b8bda9 812 void __init files_init(void)
8b6a4947 813 {
5afbbe0d 814diff --git a/fs/inode.c b/fs/inode.c
acd2b654 815index fa6ae6a..69d4a6c 100644
5afbbe0d
AM
816--- a/fs/inode.c
817+++ b/fs/inode.c
acd2b654 818@@ -1666,6 +1666,7 @@ int update_time(struct inode *inode, struct timespec64 *time, int flags)
5afbbe0d
AM
819
820 return update_time(inode, time, flags);
821 }
822+EXPORT_SYMBOL_GPL(update_time);
823
824 /**
825 * touch_atime - update the access time
7f207e10 826diff --git a/fs/namespace.c b/fs/namespace.c
acd2b654 827index 72c93f3..c49803c 100644
7f207e10
AM
828--- a/fs/namespace.c
829+++ b/fs/namespace.c
acd2b654 830@@ -437,6 +437,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
831 mnt_dec_writers(real_mount(mnt));
832 preempt_enable();
833 }
834+EXPORT_SYMBOL_GPL(__mnt_drop_write);
835
836 /**
837 * mnt_drop_write - give up write access to a mount
acd2b654 838@@ -775,6 +776,7 @@ int is_current_mnt_ns(struct vfsmount *mnt)
8b6a4947
AM
839 {
840 return check_mnt(real_mount(mnt));
841 }
842+EXPORT_SYMBOL_GPL(is_current_mnt_ns);
843
844 /*
845 * vfsmount lock must be held for write
acd2b654 846@@ -1832,6 +1834,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
847 }
848 return 0;
849 }
febd17d6 850+EXPORT_SYMBOL_GPL(iterate_mounts);
7f207e10 851
7eafdf33 852 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
853 {
854diff --git a/fs/notify/group.c b/fs/notify/group.c
acd2b654 855index c03b836..817f22c 100644
7f207e10
AM
856--- a/fs/notify/group.c
857+++ b/fs/notify/group.c
acd2b654 858@@ -23,6 +23,7 @@
7f207e10
AM
859 #include <linux/rculist.h>
860 #include <linux/wait.h>
acd2b654 861 #include <linux/memcontrol.h>
7f207e10
AM
862+#include <linux/module.h>
863
864 #include <linux/fsnotify_backend.h>
865 #include "fsnotify.h"
acd2b654 866@@ -112,6 +113,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
1716fcea 867 {
2121bcd9 868 refcount_inc(&group->refcnt);
1716fcea 869 }
febd17d6 870+EXPORT_SYMBOL_GPL(fsnotify_get_group);
1716fcea
AM
871
872 /*
873 * Drop a reference to a group. Free it if it's through.
acd2b654 874@@ -121,6 +123,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
2121bcd9 875 if (refcount_dec_and_test(&group->refcnt))
1716fcea 876 fsnotify_final_destroy_group(group);
7f207e10 877 }
febd17d6 878+EXPORT_SYMBOL_GPL(fsnotify_put_group);
7f207e10
AM
879
880 /*
881 * Create a new fsnotify_group and hold a reference for the group returned.
acd2b654 882@@ -150,6 +153,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
883
884 return group;
885 }
febd17d6 886+EXPORT_SYMBOL_GPL(fsnotify_alloc_group);
1716fcea
AM
887
888 int fsnotify_fasync(int fd, struct file *file, int on)
889 {
7f207e10 890diff --git a/fs/notify/mark.c b/fs/notify/mark.c
acd2b654 891index 59cdb27..ce365c7 100644
7f207e10
AM
892--- a/fs/notify/mark.c
893+++ b/fs/notify/mark.c
acd2b654 894@@ -263,6 +263,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
cd7a4cd9
AM
895 queue_delayed_work(system_unbound_wq, &reaper_work,
896 FSNOTIFY_REAPER_DELAY);
7f207e10 897 }
febd17d6 898+EXPORT_SYMBOL_GPL(fsnotify_put_mark);
7f207e10 899
cd7a4cd9
AM
900 /*
901 * Get mark reference when we found the mark via lockless traversal of object
acd2b654 902@@ -417,6 +418,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea 903 mutex_unlock(&group->mark_mutex);
79b8bda9 904 fsnotify_free_mark(mark);
7f207e10 905 }
febd17d6 906+EXPORT_SYMBOL_GPL(fsnotify_destroy_mark);
7f207e10 907
ffa93bbd
AM
908 /*
909 * Sorting function for lists of fsnotify marks.
acd2b654 910@@ -632,6 +634,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp,
cd7a4cd9 911 mutex_unlock(&group->mark_mutex);
7f207e10
AM
912 return ret;
913 }
febd17d6 914+EXPORT_SYMBOL_GPL(fsnotify_add_mark);
7f207e10 915
cd7a4cd9
AM
916 /*
917 * Given a list of marks, find the mark associated with given group. If found
acd2b654 918@@ -754,6 +757,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
ffa93bbd
AM
919 fsnotify_get_group(group);
920 mark->group = group;
7f207e10 921 }
febd17d6 922+EXPORT_SYMBOL_GPL(fsnotify_init_mark);
7f207e10 923
5afbbe0d
AM
924 /*
925 * Destroy all marks in destroy_list, waits for SRCU period to finish before
7f207e10 926diff --git a/fs/open.c b/fs/open.c
acd2b654 927index 0285ce7..cb81623 100644
7f207e10
AM
928--- a/fs/open.c
929+++ b/fs/open.c
c2c0f25c 930@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
febd17d6 931 inode_unlock(dentry->d_inode);
7f207e10
AM
932 return ret;
933 }
febd17d6 934+EXPORT_SYMBOL_GPL(do_truncate);
7f207e10 935
5afbbe0d 936 long vfs_truncate(const struct path *path, loff_t length)
7f207e10 937 {
5527c038 938diff --git a/fs/read_write.c b/fs/read_write.c
acd2b654 939index 42f64cc..d9cb969 100644
5527c038
JR
940--- a/fs/read_write.c
941+++ b/fs/read_write.c
b00004a5 942@@ -459,6 +459,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
8b6a4947
AM
943
944 return ret;
945 }
946+EXPORT_SYMBOL_GPL(vfs_read);
947
948 static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
949 {
b00004a5 950@@ -499,6 +500,7 @@ vfs_readf_t vfs_readf(struct file *file)
5527c038
JR
951 return new_sync_read;
952 return ERR_PTR(-ENOSYS);
953 }
febd17d6 954+EXPORT_SYMBOL_GPL(vfs_readf);
5527c038
JR
955
956 vfs_writef_t vfs_writef(struct file *file)
957 {
b00004a5 958@@ -510,6 +512,7 @@ vfs_writef_t vfs_writef(struct file *file)
5527c038
JR
959 return new_sync_write;
960 return ERR_PTR(-ENOSYS);
961 }
febd17d6 962+EXPORT_SYMBOL_GPL(vfs_writef);
5527c038 963
8b6a4947
AM
964 ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
965 {
b00004a5 966@@ -579,6 +582,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
8b6a4947
AM
967
968 return ret;
969 }
970+EXPORT_SYMBOL_GPL(vfs_write);
971
972 static inline loff_t file_pos_read(struct file *file)
5527c038 973 {
7f207e10 974diff --git a/fs/splice.c b/fs/splice.c
cd7a4cd9 975index 1dd7f96..a5e3bcb 100644
7f207e10
AM
976--- a/fs/splice.c
977+++ b/fs/splice.c
cd7a4cd9 978@@ -851,6 +851,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
392086de
AM
979
980 return splice_write(pipe, out, ppos, len, flags);
7f207e10 981 }
febd17d6 982+EXPORT_SYMBOL_GPL(do_splice_from);
7f207e10
AM
983
984 /*
985 * Attempt to initiate a splice from a file to a pipe.
cd7a4cd9 986@@ -880,6 +881,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
987
988 return splice_read(in, ppos, pipe, len, flags);
989 }
febd17d6 990+EXPORT_SYMBOL_GPL(do_splice_to);
7f207e10
AM
991
992 /**
993 * splice_direct_to_actor - splices data directly between two non-pipes
a2654f78 994diff --git a/fs/sync.c b/fs/sync.c
b00004a5 995index 2860782..ffd7ea4 100644
a2654f78
AM
996--- a/fs/sync.c
997+++ b/fs/sync.c
2121bcd9 998@@ -39,6 +39,7 @@ int __sync_filesystem(struct super_block *sb, int wait)
a2654f78
AM
999 sb->s_op->sync_fs(sb, wait);
1000 return __sync_blockdev(sb->s_bdev, wait);
1001 }
1002+EXPORT_SYMBOL_GPL(__sync_filesystem);
1003
1004 /*
1005 * Write out and wait upon all dirty data associated with this
c1595e42 1006diff --git a/fs/xattr.c b/fs/xattr.c
acd2b654 1007index 0d6a6a4..7ce4701 100644
c1595e42
JR
1008--- a/fs/xattr.c
1009+++ b/fs/xattr.c
acd2b654 1010@@ -295,6 +295,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
c1595e42
JR
1011 *xattr_value = value;
1012 return error;
1013 }
febd17d6 1014+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);
c1595e42 1015
febd17d6 1016 ssize_t
f2c43d5f 1017 __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
8b6a4947 1018diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
acd2b654 1019index fa6f559..7ac19ef 100644
8b6a4947
AM
1020--- a/kernel/locking/lockdep.c
1021+++ b/kernel/locking/lockdep.c
be118d29 1022@@ -151,6 +151,7 @@ inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
8b6a4947
AM
1023 }
1024 return lock_classes + hlock->class_idx - 1;
1025 }
1026+EXPORT_SYMBOL_GPL(lockdep_hlock_class);
1027 #define hlock_class(hlock) lockdep_hlock_class(hlock)
1028
1029 #ifdef CONFIG_LOCK_STAT
8cdd5066 1030diff --git a/kernel/task_work.c b/kernel/task_work.c
2121bcd9 1031index 0fef395..83fb1ec 100644
8cdd5066
JR
1032--- a/kernel/task_work.c
1033+++ b/kernel/task_work.c
2121bcd9 1034@@ -116,3 +116,4 @@ void task_work_run(void)
8cdd5066
JR
1035 } while (work);
1036 }
1037 }
febd17d6 1038+EXPORT_SYMBOL_GPL(task_work_run);
7f207e10 1039diff --git a/security/commoncap.c b/security/commoncap.c
acd2b654 1040index 2e489d6..1e146da 100644
7f207e10
AM
1041--- a/security/commoncap.c
1042+++ b/security/commoncap.c
cd7a4cd9 1043@@ -1336,12 +1336,14 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 1044 }
7f207e10
AM
1045 return ret;
1046 }
febd17d6 1047+EXPORT_SYMBOL_GPL(cap_mmap_addr);
0c3ec466
AM
1048
1049 int cap_mmap_file(struct file *file, unsigned long reqprot,
1050 unsigned long prot, unsigned long flags)
1051 {
1052 return 0;
1053 }
febd17d6 1054+EXPORT_SYMBOL_GPL(cap_mmap_file);
c2c0f25c
AM
1055
1056 #ifdef CONFIG_SECURITY
1057
7f207e10 1058diff --git a/security/device_cgroup.c b/security/device_cgroup.c
cd7a4cd9 1059index cd97929..424fd23 100644
7f207e10
AM
1060--- a/security/device_cgroup.c
1061+++ b/security/device_cgroup.c
2121bcd9 1062@@ -8,6 +8,7 @@
f6c5ef8b
AM
1063 #include <linux/device_cgroup.h>
1064 #include <linux/cgroup.h>
1065 #include <linux/ctype.h>
1066+#include <linux/export.h>
1067 #include <linux/list.h>
1068 #include <linux/uaccess.h>
1069 #include <linux/seq_file.h>
2121bcd9 1070@@ -824,3 +825,4 @@ int __devcgroup_check_permission(short type, u32 major, u32 minor,
7f207e10 1071
2121bcd9
AM
1072 return 0;
1073 }
1074+EXPORT_SYMBOL_GPL(__devcgroup_check_permission);
7f207e10 1075diff --git a/security/security.c b/security/security.c
acd2b654 1076index 736e78d..b314539 100644
7f207e10
AM
1077--- a/security/security.c
1078+++ b/security/security.c
acd2b654 1079@@ -542,6 +542,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry)
7f207e10 1080 return 0;
c2c0f25c 1081 return call_int_hook(path_rmdir, 0, dir, dentry);
7f207e10 1082 }
febd17d6 1083+EXPORT_SYMBOL_GPL(security_path_rmdir);
7f207e10 1084
5afbbe0d 1085 int security_path_unlink(const struct path *dir, struct dentry *dentry)
7f207e10 1086 {
acd2b654 1087@@ -558,6 +559,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry,
7f207e10 1088 return 0;
c2c0f25c 1089 return call_int_hook(path_symlink, 0, dir, dentry, old_name);
7f207e10 1090 }
febd17d6 1091+EXPORT_SYMBOL_GPL(security_path_symlink);
7f207e10 1092
5afbbe0d 1093 int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
7f207e10 1094 struct dentry *new_dentry)
acd2b654 1095@@ -566,6 +568,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
7f207e10 1096 return 0;
c2c0f25c 1097 return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
7f207e10 1098 }
febd17d6 1099+EXPORT_SYMBOL_GPL(security_path_link);
7f207e10 1100
5afbbe0d
AM
1101 int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
1102 const struct path *new_dir, struct dentry *new_dentry,
acd2b654 1103@@ -593,6 +596,7 @@ int security_path_truncate(const struct path *path)
7f207e10 1104 return 0;
c2c0f25c 1105 return call_int_hook(path_truncate, 0, path);
7f207e10 1106 }
febd17d6 1107+EXPORT_SYMBOL_GPL(security_path_truncate);
7f207e10 1108
5afbbe0d 1109 int security_path_chmod(const struct path *path, umode_t mode)
7eafdf33 1110 {
acd2b654 1111@@ -600,6 +604,7 @@ int security_path_chmod(const struct path *path, umode_t mode)
7f207e10 1112 return 0;
c2c0f25c 1113 return call_int_hook(path_chmod, 0, path, mode);
7f207e10 1114 }
febd17d6 1115+EXPORT_SYMBOL_GPL(security_path_chmod);
7f207e10 1116
5afbbe0d 1117 int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
7f207e10 1118 {
acd2b654 1119@@ -607,6 +612,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
7f207e10 1120 return 0;
c2c0f25c 1121 return call_int_hook(path_chown, 0, path, uid, gid);
7f207e10 1122 }
febd17d6 1123+EXPORT_SYMBOL_GPL(security_path_chown);
7f207e10 1124
5afbbe0d 1125 int security_path_chroot(const struct path *path)
7f207e10 1126 {
acd2b654 1127@@ -692,6 +698,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10 1128 return 0;
c2c0f25c 1129 return call_int_hook(inode_readlink, 0, dentry);
7f207e10 1130 }
febd17d6 1131+EXPORT_SYMBOL_GPL(security_inode_readlink);
7f207e10 1132
c2c0f25c
AM
1133 int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
1134 bool rcu)
acd2b654 1135@@ -707,6 +714,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 1136 return 0;
c2c0f25c 1137 return call_int_hook(inode_permission, 0, inode, mask);
7f207e10 1138 }
febd17d6 1139+EXPORT_SYMBOL_GPL(security_inode_permission);
7f207e10 1140
1e00d052 1141 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 1142 {
acd2b654 1143@@ -878,6 +886,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
1144
1145 return fsnotify_perm(file, mask);
1146 }
febd17d6 1147+EXPORT_SYMBOL_GPL(security_file_permission);
7f207e10
AM
1148
1149 int security_file_alloc(struct file *file)
1150 {
acd2b654 1151@@ -937,6 +946,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
1152 return ret;
1153 return ima_file_mmap(file, prot);
1154 }
febd17d6 1155+EXPORT_SYMBOL_GPL(security_mmap_file);
7f207e10 1156
0c3ec466
AM
1157 int security_mmap_addr(unsigned long addr)
1158 {
7f207e10
AM
1159diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
1160--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 1161+++ linux/Documentation/ABI/testing/debugfs-aufs 2018-08-12 23:43:05.450124426 +0200
062440b3 1162@@ -0,0 +1,55 @@
7f207e10
AM
1163+What: /debug/aufs/si_<id>/
1164+Date: March 2009
f6b6e03d 1165+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1166+Description:
1167+ Under /debug/aufs, a directory named si_<id> is created
1168+ per aufs mount, where <id> is a unique id generated
1169+ internally.
1facf9fc 1170+
86dc4139
AM
1171+What: /debug/aufs/si_<id>/plink
1172+Date: Apr 2013
f6b6e03d 1173+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
1174+Description:
1175+ It has three lines and shows the information about the
1176+ pseudo-link. The first line is a single number
1177+ representing a number of buckets. The second line is a
1178+ number of pseudo-links per buckets (separated by a
1179+ blank). The last line is a single number representing a
1180+ total number of psedo-links.
1181+ When the aufs mount option 'noplink' is specified, it
1182+ will show "1\n0\n0\n".
1183+
7f207e10
AM
1184+What: /debug/aufs/si_<id>/xib
1185+Date: March 2009
f6b6e03d 1186+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1187+Description:
1188+ It shows the consumed blocks by xib (External Inode Number
1189+ Bitmap), its block size and file size.
1190+ When the aufs mount option 'noxino' is specified, it
1191+ will be empty. About XINO files, see the aufs manual.
1192+
062440b3 1193+What: /debug/aufs/si_<id>/xi0, xi1 ... xiN and xiN-N
7f207e10 1194+Date: March 2009
f6b6e03d 1195+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1196+Description:
1197+ It shows the consumed blocks by xino (External Inode Number
1198+ Translation Table), its link count, block size and file
1199+ size.
062440b3
AM
1200+ Due to the file size limit, there may exist multiple
1201+ xino files per branch. In this case, "-N" is added to
1202+ the filename and it corresponds to the index of the
1203+ internal xino array. "-0" is omitted.
1204+ When the aufs mount option 'noxino' is specified, Those
1205+ entries won't exist. About XINO files, see the aufs
1206+ manual.
7f207e10
AM
1207+
1208+What: /debug/aufs/si_<id>/xigen
1209+Date: March 2009
f6b6e03d 1210+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1211+Description:
1212+ It shows the consumed blocks by xigen (External Inode
1213+ Generation Table), its block size and file size.
1214+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
1215+ be created.
1216+ When the aufs mount option 'noxino' is specified, it
1217+ will be empty. About XINO files, see the aufs manual.
1218diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
1219--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
b00004a5 1220+++ linux/Documentation/ABI/testing/sysfs-aufs 2017-07-29 12:14:25.893041746 +0200
392086de 1221@@ -0,0 +1,31 @@
7f207e10
AM
1222+What: /sys/fs/aufs/si_<id>/
1223+Date: March 2009
f6b6e03d 1224+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1225+Description:
1226+ Under /sys/fs/aufs, a directory named si_<id> is created
1227+ per aufs mount, where <id> is a unique id generated
1228+ internally.
1229+
1230+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
1231+Date: March 2009
f6b6e03d 1232+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1233+Description:
1234+ It shows the abolute path of a member directory (which
1235+ is called branch) in aufs, and its permission.
1236+
392086de
AM
1237+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
1238+Date: July 2013
f6b6e03d 1239+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
1240+Description:
1241+ It shows the id of a member directory (which is called
1242+ branch) in aufs.
1243+
7f207e10
AM
1244+What: /sys/fs/aufs/si_<id>/xi_path
1245+Date: March 2009
f6b6e03d 1246+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1247+Description:
1248+ It shows the abolute path of XINO (External Inode Number
1249+ Bitmap, Translation Table and Generation Table) file
1250+ even if it is the default path.
1251+ When the aufs mount option 'noxino' is specified, it
1252+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
1253diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
1254--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 1255+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2018-04-15 08:49:13.394483860 +0200
1c60b727 1256@@ -0,0 +1,171 @@
53392da6 1257+
b00004a5 1258+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
1259+#
1260+# This program is free software; you can redistribute it and/or modify
1261+# it under the terms of the GNU General Public License as published by
1262+# the Free Software Foundation; either version 2 of the License, or
1263+# (at your option) any later version.
1264+#
1265+# This program is distributed in the hope that it will be useful,
1266+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1267+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1268+# GNU General Public License for more details.
1269+#
1270+# You should have received a copy of the GNU General Public License
523b37e3 1271+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1272+
1273+Introduction
1274+----------------------------------------
1275+
3c1bdaff 1276+aufs [ei ju: ef es] | /ey-yoo-ef-es/ | [a u f s]
53392da6
AM
1277+1. abbrev. for "advanced multi-layered unification filesystem".
1278+2. abbrev. for "another unionfs".
1279+3. abbrev. for "auf das" in German which means "on the" in English.
1280+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
1281+ But "Filesystem aufs Filesystem" is hard to understand.
1c60b727 1282+4. abbrev. for "African Urban Fashion Show".
53392da6
AM
1283+
1284+AUFS is a filesystem with features:
1285+- multi layered stackable unification filesystem, the member directory
1286+ is called as a branch.
1287+- branch permission and attribute, 'readonly', 'real-readonly',
7e9cd9fe 1288+ 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their
53392da6
AM
1289+ combination.
1290+- internal "file copy-on-write".
1291+- logical deletion, whiteout.
1292+- dynamic branch manipulation, adding, deleting and changing permission.
1293+- allow bypassing aufs, user's direct branch access.
1294+- external inode number translation table and bitmap which maintains the
1295+ persistent aufs inode number.
1296+- seekable directory, including NFS readdir.
1297+- file mapping, mmap and sharing pages.
1298+- pseudo-link, hardlink over branches.
1299+- loopback mounted filesystem as a branch.
1300+- several policies to select one among multiple writable branches.
1301+- revert a single systemcall when an error occurs in aufs.
1302+- and more...
1303+
1304+
1305+Multi Layered Stackable Unification Filesystem
1306+----------------------------------------------------------------------
1307+Most people already knows what it is.
1308+It is a filesystem which unifies several directories and provides a
1309+merged single directory. When users access a file, the access will be
1310+passed/re-directed/converted (sorry, I am not sure which English word is
1311+correct) to the real file on the member filesystem. The member
1312+filesystem is called 'lower filesystem' or 'branch' and has a mode
1313+'readonly' and 'readwrite.' And the deletion for a file on the lower
1314+readonly branch is handled by creating 'whiteout' on the upper writable
1315+branch.
1316+
1317+On LKML, there have been discussions about UnionMount (Jan Blunck,
1318+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
1319+different approaches to implement the merged-view.
1320+The former tries putting it into VFS, and the latter implements as a
1321+separate filesystem.
1322+(If I misunderstand about these implementations, please let me know and
1323+I shall correct it. Because it is a long time ago when I read their
1324+source files last time).
1325+
1326+UnionMount's approach will be able to small, but may be hard to share
1327+branches between several UnionMount since the whiteout in it is
1328+implemented in the inode on branch filesystem and always
1329+shared. According to Bharata's post, readdir does not seems to be
1330+finished yet.
1331+There are several missing features known in this implementations such as
1332+- for users, the inode number may change silently. eg. copy-up.
1333+- link(2) may break by copy-up.
1334+- read(2) may get an obsoleted filedata (fstat(2) too).
1335+- fcntl(F_SETLK) may be broken by copy-up.
1336+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
1337+ open(O_RDWR).
1338+
7e9cd9fe
AM
1339+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was
1340+merged into mainline. This is another implementation of UnionMount as a
1341+separated filesystem. All the limitations and known problems which
1342+UnionMount are equally inherited to "overlay" filesystem.
1343+
1344+Unionfs has a longer history. When I started implementing a stackable
1345+filesystem (Aug 2005), it already existed. It has virtual super_block,
1346+inode, dentry and file objects and they have an array pointing lower
1347+same kind objects. After contributing many patches for Unionfs, I
1348+re-started my project AUFS (Jun 2006).
53392da6
AM
1349+
1350+In AUFS, the structure of filesystem resembles to Unionfs, but I
1351+implemented my own ideas, approaches and enhancements and it became
1352+totally different one.
1353+
1354+Comparing DM snapshot and fs based implementation
1355+- the number of bytes to be copied between devices is much smaller.
1356+- the type of filesystem must be one and only.
1357+- the fs must be writable, no readonly fs, even for the lower original
1358+ device. so the compression fs will not be usable. but if we use
1359+ loopback mount, we may address this issue.
1360+ for instance,
1361+ mount /cdrom/squashfs.img /sq
1362+ losetup /sq/ext2.img
1363+ losetup /somewhere/cow
1364+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
1365+- it will be difficult (or needs more operations) to extract the
1366+ difference between the original device and COW.
1367+- DM snapshot-merge may help a lot when users try merging. in the
1368+ fs-layer union, users will use rsync(1).
1369+
7e9cd9fe
AM
1370+You may want to read my old paper "Filesystems in LiveCD"
1371+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf).
53392da6 1372+
7e9cd9fe
AM
1373+
1374+Several characters/aspects/persona of aufs
53392da6
AM
1375+----------------------------------------------------------------------
1376+
7e9cd9fe 1377+Aufs has several characters, aspects or persona.
53392da6
AM
1378+1. a filesystem, callee of VFS helper
1379+2. sub-VFS, caller of VFS helper for branches
1380+3. a virtual filesystem which maintains persistent inode number
1381+4. reader/writer of files on branches such like an application
1382+
1383+1. Callee of VFS Helper
1384+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1385+unlink(2) from an application reaches sys_unlink() kernel function and
1386+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1387+calls filesystem specific unlink operation. Actually aufs implements the
1388+unlink operation but it behaves like a redirector.
1389+
1390+2. Caller of VFS Helper for Branches
1391+aufs_unlink() passes the unlink request to the branch filesystem as if
1392+it were called from VFS. So the called unlink operation of the branch
1393+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1394+every necessary pre/post operation for the branch filesystem.
1395+- acquire the lock for the parent dir on a branch
1396+- lookup in a branch
1397+- revalidate dentry on a branch
1398+- mnt_want_write() for a branch
1399+- vfs_unlink() for a branch
1400+- mnt_drop_write() for a branch
1401+- release the lock on a branch
1402+
1403+3. Persistent Inode Number
1404+One of the most important issue for a filesystem is to maintain inode
1405+numbers. This is particularly important to support exporting a
1406+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1407+backend block device for its own. But some storage is necessary to
7e9cd9fe
AM
1408+keep and maintain the inode numbers. It may be a large space and may not
1409+suit to keep in memory. Aufs rents some space from its first writable
1410+branch filesystem (by default) and creates file(s) on it. These files
1411+are created by aufs internally and removed soon (currently) keeping
1412+opened.
53392da6
AM
1413+Note: Because these files are removed, they are totally gone after
1414+ unmounting aufs. It means the inode numbers are not persistent
1415+ across unmount or reboot. I have a plan to make them really
1416+ persistent which will be important for aufs on NFS server.
1417+
1418+4. Read/Write Files Internally (copy-on-write)
1419+Because a branch can be readonly, when you write a file on it, aufs will
1420+"copy-up" it to the upper writable branch internally. And then write the
1421+originally requested thing to the file. Generally kernel doesn't
1422+open/read/write file actively. In aufs, even a single write may cause a
1423+internal "file copy". This behaviour is very similar to cp(1) command.
1424+
1425+Some people may think it is better to pass such work to user space
1426+helper, instead of doing in kernel space. Actually I am still thinking
1427+about it. But currently I have implemented it in kernel space.
1428diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1429--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 1430+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2018-04-15 08:49:13.394483860 +0200
7e9cd9fe 1431@@ -0,0 +1,258 @@
53392da6 1432+
b00004a5 1433+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
1434+#
1435+# This program is free software; you can redistribute it and/or modify
1436+# it under the terms of the GNU General Public License as published by
1437+# the Free Software Foundation; either version 2 of the License, or
1438+# (at your option) any later version.
1439+#
1440+# This program is distributed in the hope that it will be useful,
1441+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1442+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1443+# GNU General Public License for more details.
1444+#
1445+# You should have received a copy of the GNU General Public License
523b37e3 1446+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1447+
1448+Basic Aufs Internal Structure
1449+
1450+Superblock/Inode/Dentry/File Objects
1451+----------------------------------------------------------------------
1452+As like an ordinary filesystem, aufs has its own
1453+superblock/inode/dentry/file objects. All these objects have a
1454+dynamically allocated array and store the same kind of pointers to the
1455+lower filesystem, branch.
1456+For example, when you build a union with one readwrite branch and one
1457+readonly, mounted /au, /rw and /ro respectively.
1458+- /au = /rw + /ro
1459+- /ro/fileA exists but /rw/fileA
1460+
1461+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1462+pointers are stored in a aufs dentry. The array in aufs dentry will be,
7e9cd9fe 1463+- [0] = NULL (because /rw/fileA doesn't exist)
53392da6
AM
1464+- [1] = /ro/fileA
1465+
1466+This style of an array is essentially same to the aufs
1467+superblock/inode/dentry/file objects.
1468+
1469+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1470+branches dynamically, these objects has its own generation. When
1471+branches are changed, the generation in aufs superblock is
1472+incremented. And a generation in other object are compared when it is
1473+accessed. When a generation in other objects are obsoleted, aufs
1474+refreshes the internal array.
53392da6
AM
1475+
1476+
1477+Superblock
1478+----------------------------------------------------------------------
1479+Additionally aufs superblock has some data for policies to select one
1480+among multiple writable branches, XIB files, pseudo-links and kobject.
1481+See below in detail.
7e9cd9fe
AM
1482+About the policies which supports copy-down a directory, see
1483+wbr_policy.txt too.
53392da6
AM
1484+
1485+
1486+Branch and XINO(External Inode Number Translation Table)
1487+----------------------------------------------------------------------
1488+Every branch has its own xino (external inode number translation table)
1489+file. The xino file is created and unlinked by aufs internally. When two
1490+members of a union exist on the same filesystem, they share the single
1491+xino file.
1492+The struct of a xino file is simple, just a sequence of aufs inode
1493+numbers which is indexed by the lower inode number.
1494+In the above sample, assume the inode number of /ro/fileA is i111 and
1495+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1496+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1497+
1498+When the inode numbers are not contiguous, the xino file will be sparse
1499+which has a hole in it and doesn't consume as much disk space as it
1500+might appear. If your branch filesystem consumes disk space for such
1501+holes, then you should specify 'xino=' option at mounting aufs.
1502+
7e9cd9fe
AM
1503+Aufs has a mount option to free the disk blocks for such holes in XINO
1504+files on tmpfs or ramdisk. But it is not so effective actually. If you
1505+meet a problem of disk shortage due to XINO files, then you should try
1506+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git.
1507+The patch localizes the assignment inumbers per tmpfs-mount and avoid
1508+the holes in XINO files.
1509+
53392da6 1510+Also a writable branch has three kinds of "whiteout bases". All these
7e9cd9fe 1511+are existed when the branch is joined to aufs, and their names are
53392da6
AM
1512+whiteout-ed doubly, so that users will never see their names in aufs
1513+hierarchy.
7e9cd9fe 1514+1. a regular file which will be hardlinked to all whiteouts.
53392da6 1515+2. a directory to store a pseudo-link.
7e9cd9fe 1516+3. a directory to store an "orphan"-ed file temporary.
53392da6
AM
1517+
1518+1. Whiteout Base
1519+ When you remove a file on a readonly branch, aufs handles it as a
1520+ logical deletion and creates a whiteout on the upper writable branch
1521+ as a hardlink of this file in order not to consume inode on the
1522+ writable branch.
1523+2. Pseudo-link Dir
1524+ See below, Pseudo-link.
1525+3. Step-Parent Dir
1526+ When "fileC" exists on the lower readonly branch only and it is
1527+ opened and removed with its parent dir, and then user writes
1528+ something into it, then aufs copies-up fileC to this
1529+ directory. Because there is no other dir to store fileC. After
1530+ creating a file under this dir, the file is unlinked.
1531+
1532+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1533+dynamically, a branch has its own id. When the branch order changes,
1534+aufs finds the new index by searching the branch id.
53392da6
AM
1535+
1536+
1537+Pseudo-link
1538+----------------------------------------------------------------------
1539+Assume "fileA" exists on the lower readonly branch only and it is
1540+hardlinked to "fileB" on the branch. When you write something to fileA,
1541+aufs copies-up it to the upper writable branch. Additionally aufs
1542+creates a hardlink under the Pseudo-link Directory of the writable
1543+branch. The inode of a pseudo-link is kept in aufs super_block as a
1544+simple list. If fileB is read after unlinking fileA, aufs returns
1545+filedata from the pseudo-link instead of the lower readonly
1546+branch. Because the pseudo-link is based upon the inode, to keep the
7e9cd9fe 1547+inode number by xino (see above) is essentially necessary.
53392da6
AM
1548+
1549+All the hardlinks under the Pseudo-link Directory of the writable branch
1550+should be restored in a proper location later. Aufs provides a utility
1551+to do this. The userspace helpers executed at remounting and unmounting
1552+aufs by default.
1553+During this utility is running, it puts aufs into the pseudo-link
1554+maintenance mode. In this mode, only the process which began the
1555+maintenance mode (and its child processes) is allowed to operate in
1556+aufs. Some other processes which are not related to the pseudo-link will
1557+be allowed to run too, but the rest have to return an error or wait
1558+until the maintenance mode ends. If a process already acquires an inode
1559+mutex (in VFS), it has to return an error.
1560+
1561+
1562+XIB(external inode number bitmap)
1563+----------------------------------------------------------------------
1564+Addition to the xino file per a branch, aufs has an external inode number
7e9cd9fe
AM
1565+bitmap in a superblock object. It is also an internal file such like a
1566+xino file.
53392da6
AM
1567+It is a simple bitmap to mark whether the aufs inode number is in-use or
1568+not.
1569+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1570+
7e9cd9fe 1571+As well as XINO files, aufs has a feature to truncate/refresh XIB to
53392da6
AM
1572+reduce the number of consumed disk blocks for these files.
1573+
1574+
1575+Virtual or Vertical Dir, and Readdir in Userspace
1576+----------------------------------------------------------------------
1577+In order to support multiple layers (branches), aufs readdir operation
1578+constructs a virtual dir block on memory. For readdir, aufs calls
1579+vfs_readdir() internally for each dir on branches, merges their entries
1580+with eliminating the whiteout-ed ones, and sets it to file (dir)
1581+object. So the file object has its entry list until it is closed. The
1582+entry list will be updated when the file position is zero and becomes
7e9cd9fe 1583+obsoleted. This decision is made in aufs automatically.
53392da6
AM
1584+
1585+The dynamically allocated memory block for the name of entries has a
1586+unit of 512 bytes (by default) and stores the names contiguously (no
1587+padding). Another block for each entry is handled by kmem_cache too.
1588+During building dir blocks, aufs creates hash list and judging whether
1589+the entry is whiteouted by its upper branch or already listed.
1590+The merged result is cached in the corresponding inode object and
1591+maintained by a customizable life-time option.
1592+
1593+Some people may call it can be a security hole or invite DoS attack
1594+since the opened and once readdir-ed dir (file object) holds its entry
1595+list and becomes a pressure for system memory. But I'd say it is similar
1596+to files under /proc or /sys. The virtual files in them also holds a
1597+memory page (generally) while they are opened. When an idea to reduce
1598+memory for them is introduced, it will be applied to aufs too.
1599+For those who really hate this situation, I've developed readdir(3)
1600+library which operates this merging in userspace. You just need to set
1601+LD_PRELOAD environment variable, and aufs will not consume no memory in
1602+kernel space for readdir(3).
1603+
1604+
1605+Workqueue
1606+----------------------------------------------------------------------
1607+Aufs sometimes requires privilege access to a branch. For instance,
1608+in copy-up/down operation. When a user process is going to make changes
1609+to a file which exists in the lower readonly branch only, and the mode
1610+of one of ancestor directories may not be writable by a user
1611+process. Here aufs copy-up the file with its ancestors and they may
1612+require privilege to set its owner/group/mode/etc.
1613+This is a typical case of a application character of aufs (see
1614+Introduction).
1615+
1616+Aufs uses workqueue synchronously for this case. It creates its own
1617+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1618+passes the request to call mkdir or write (for example), and wait for
1619+its completion. This approach solves a problem of a signal handler
1620+simply.
1621+If aufs didn't adopt the workqueue and changed the privilege of the
7e9cd9fe
AM
1622+process, then the process may receive the unexpected SIGXFSZ or other
1623+signals.
53392da6
AM
1624+
1625+Also aufs uses the system global workqueue ("events" kernel thread) too
1626+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1627+whiteout base and etc. This is unrelated to a privilege.
1628+Most of aufs operation tries acquiring a rw_semaphore for aufs
1629+superblock at the beginning, at the same time waits for the completion
1630+of all queued asynchronous tasks.
1631+
1632+
1633+Whiteout
1634+----------------------------------------------------------------------
1635+The whiteout in aufs is very similar to Unionfs's. That is represented
1636+by its filename. UnionMount takes an approach of a file mode, but I am
1637+afraid several utilities (find(1) or something) will have to support it.
1638+
1639+Basically the whiteout represents "logical deletion" which stops aufs to
1640+lookup further, but also it represents "dir is opaque" which also stop
7e9cd9fe 1641+further lookup.
53392da6
AM
1642+
1643+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1644+In order to make several functions in a single systemcall to be
1645+revertible, aufs adopts an approach to rename a directory to a temporary
1646+unique whiteouted name.
1647+For example, in rename(2) dir where the target dir already existed, aufs
1648+renames the target dir to a temporary unique whiteouted name before the
7e9cd9fe 1649+actual rename on a branch, and then handles other actions (make it opaque,
53392da6
AM
1650+update the attributes, etc). If an error happens in these actions, aufs
1651+simply renames the whiteouted name back and returns an error. If all are
1652+succeeded, aufs registers a function to remove the whiteouted unique
1653+temporary name completely and asynchronously to the system global
1654+workqueue.
1655+
1656+
1657+Copy-up
1658+----------------------------------------------------------------------
1659+It is a well-known feature or concept.
1660+When user modifies a file on a readonly branch, aufs operate "copy-up"
1661+internally and makes change to the new file on the upper writable branch.
1662+When the trigger systemcall does not update the timestamps of the parent
1663+dir, aufs reverts it after copy-up.
c2b27bf2
AM
1664+
1665+
1666+Move-down (aufs3.9 and later)
1667+----------------------------------------------------------------------
1668+"Copy-up" is one of the essential feature in aufs. It copies a file from
1669+the lower readonly branch to the upper writable branch when a user
1670+changes something about the file.
1671+"Move-down" is an opposite action of copy-up. Basically this action is
1672+ran manually instead of automatically and internally.
076b876e
AM
1673+For desgin and implementation, aufs has to consider these issues.
1674+- whiteout for the file may exist on the lower branch.
1675+- ancestor directories may not exist on the lower branch.
1676+- diropq for the ancestor directories may exist on the upper branch.
1677+- free space on the lower branch will reduce.
1678+- another access to the file may happen during moving-down, including
7e9cd9fe 1679+ UDBA (see "Revalidate Dentry and UDBA").
076b876e
AM
1680+- the file should not be hard-linked nor pseudo-linked. they should be
1681+ handled by auplink utility later.
c2b27bf2
AM
1682+
1683+Sometimes users want to move-down a file from the upper writable branch
1684+to the lower readonly or writable branch. For instance,
1685+- the free space of the upper writable branch is going to run out.
1686+- create a new intermediate branch between the upper and lower branch.
1687+- etc.
1688+
1689+For this purpose, use "aumvdown" command in aufs-util.git.
b912730e
AM
1690diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt linux/Documentation/filesystems/aufs/design/03atomic_open.txt
1691--- /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 1692+++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2018-04-15 08:49:13.394483860 +0200
b912730e
AM
1693@@ -0,0 +1,85 @@
1694+
b00004a5 1695+# Copyright (C) 2015-2018 Junjiro R. Okajima
b912730e
AM
1696+#
1697+# This program is free software; you can redistribute it and/or modify
1698+# it under the terms of the GNU General Public License as published by
1699+# the Free Software Foundation; either version 2 of the License, or
1700+# (at your option) any later version.
1701+#
1702+# This program is distributed in the hope that it will be useful,
1703+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1704+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1705+# GNU General Public License for more details.
1706+#
1707+# You should have received a copy of the GNU General Public License
1708+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1709+
1710+Support for a branch who has its ->atomic_open()
1711+----------------------------------------------------------------------
1712+The filesystems who implement its ->atomic_open() are not majority. For
1713+example NFSv4 does, and aufs should call NFSv4 ->atomic_open,
1714+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than
1715+->atomic_open(), NFSv4 returns an error for this open(2). While I am not
1716+sure whether all filesystems who have ->atomic_open() behave like this,
1717+but NFSv4 surely returns the error.
1718+
1719+In order to support ->atomic_open() for aufs, there are a few
1720+approaches.
1721+
1722+A. Introduce aufs_atomic_open()
1723+ - calls one of VFS:do_last(), lookup_open() or atomic_open() for
1724+ branch fs.
1725+B. Introduce aufs_atomic_open() calling create, open and chmod. this is
1726+ an aufs user Pip Cet's approach
1727+ - calls aufs_create(), VFS finish_open() and notify_change().
1728+ - pass fake-mode to finish_open(), and then correct the mode by
1729+ notify_change().
1730+C. Extend aufs_open() to call branch fs's ->atomic_open()
1731+ - no aufs_atomic_open().
1732+ - aufs_lookup() registers the TID to an aufs internal object.
1733+ - aufs_create() does nothing when the matching TID is registered, but
1734+ registers the mode.
1735+ - aufs_open() calls branch fs's ->atomic_open() when the matching
1736+ TID is registered.
1737+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's
1738+ credential
1739+ - no aufs_atomic_open().
1740+ - aufs_create() registers the TID to an internal object. this info
1741+ represents "this process created this file just now."
1742+ - when aufs gets EACCES from branch fs's ->open(), then confirm the
1743+ registered TID and re-try open() with superuser's credential.
1744+
1745+Pros and cons for each approach.
1746+
1747+A.
1748+ - straightforward but highly depends upon VFS internal.
1749+ - the atomic behavaiour is kept.
1750+ - some of parameters such as nameidata are hard to reproduce for
1751+ branch fs.
1752+ - large overhead.
1753+B.
1754+ - easy to implement.
1755+ - the atomic behavaiour is lost.
1756+C.
1757+ - the atomic behavaiour is kept.
1758+ - dirty and tricky.
1759+ - VFS checks whether the file is created correctly after calling
1760+ ->create(), which means this approach doesn't work.
1761+D.
1762+ - easy to implement.
1763+ - the atomic behavaiour is lost.
1764+ - to open a file with superuser's credential and give it to a user
1765+ process is a bad idea, since the file object keeps the credential
1766+ in it. It may affect LSM or something. This approach doesn't work
1767+ either.
1768+
1769+The approach A is ideal, but it hard to implement. So here is a
1770+variation of A, which is to be implemented.
1771+
1772+A-1. Introduce aufs_atomic_open()
1773+ - calls branch fs ->atomic_open() if exists. otherwise calls
1774+ vfs_create() and finish_open().
1775+ - the demerit is that the several checks after branch fs
1776+ ->atomic_open() are lost. in the ordinary case, the checks are
1777+ done by VFS:do_last(), lookup_open() and atomic_open(). some can
1778+ be implemented in aufs, but not all I am afraid.
53392da6
AM
1779diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1780--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 1781+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2018-04-15 08:49:13.394483860 +0200
7e9cd9fe 1782@@ -0,0 +1,113 @@
53392da6 1783+
b00004a5 1784+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
1785+#
1786+# This program is free software; you can redistribute it and/or modify
1787+# it under the terms of the GNU General Public License as published by
1788+# the Free Software Foundation; either version 2 of the License, or
1789+# (at your option) any later version.
1790+#
1791+# This program is distributed in the hope that it will be useful,
1792+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1793+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1794+# GNU General Public License for more details.
1795+#
1796+# You should have received a copy of the GNU General Public License
523b37e3 1797+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1798+
1799+Lookup in a Branch
1800+----------------------------------------------------------------------
1801+Since aufs has a character of sub-VFS (see Introduction), it operates
7e9cd9fe
AM
1802+lookup for branches as VFS does. It may be a heavy work. But almost all
1803+lookup operation in aufs is the simplest case, ie. lookup only an entry
1804+directly connected to its parent. Digging down the directory hierarchy
1805+is unnecessary. VFS has a function lookup_one_len() for that use, and
1806+aufs calls it.
1807+
1808+When a branch is a remote filesystem, aufs basically relies upon its
53392da6
AM
1809+->d_revalidate(), also aufs forces the hardest revalidate tests for
1810+them.
1811+For d_revalidate, aufs implements three levels of revalidate tests. See
1812+"Revalidate Dentry and UDBA" in detail.
1813+
1814+
076b876e
AM
1815+Test Only the Highest One for the Directory Permission (dirperm1 option)
1816+----------------------------------------------------------------------
1817+Let's try case study.
1818+- aufs has two branches, upper readwrite and lower readonly.
1819+ /au = /rw + /ro
1820+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1821+- user invoked "chmod a+rx /au/dirA"
1822+- the internal copy-up is activated and "/rw/dirA" is created and its
7e9cd9fe 1823+ permission bits are set to world readable.
076b876e
AM
1824+- then "/au/dirA" becomes world readable?
1825+
1826+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1827+or it may be a natively readonly filesystem. If aufs respects the lower
1828+branch, it should not respond readdir request from other users. But user
1829+allowed it by chmod. Should really aufs rejects showing the entries
1830+under /ro/dirA?
1831+
7e9cd9fe
AM
1832+To be honest, I don't have a good solution for this case. So aufs
1833+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to
1834+users.
076b876e
AM
1835+When dirperm1 is specified, aufs checks only the highest one for the
1836+directory permission, and shows the entries. Otherwise, as usual, checks
1837+every dir existing on all branches and rejects the request.
1838+
1839+As a side effect, dirperm1 option improves the performance of aufs
1840+because the number of permission check is reduced when the number of
1841+branch is many.
1842+
1843+
53392da6
AM
1844+Revalidate Dentry and UDBA (User's Direct Branch Access)
1845+----------------------------------------------------------------------
1846+Generally VFS helpers re-validate a dentry as a part of lookup.
1847+0. digging down the directory hierarchy.
1848+1. lock the parent dir by its i_mutex.
1849+2. lookup the final (child) entry.
1850+3. revalidate it.
1851+4. call the actual operation (create, unlink, etc.)
1852+5. unlock the parent dir
1853+
1854+If the filesystem implements its ->d_revalidate() (step 3), then it is
1855+called. Actually aufs implements it and checks the dentry on a branch is
1856+still valid.
1857+But it is not enough. Because aufs has to release the lock for the
1858+parent dir on a branch at the end of ->lookup() (step 2) and
1859+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1860+held by VFS.
1861+If the file on a branch is changed directly, eg. bypassing aufs, after
1862+aufs released the lock, then the subsequent operation may cause
1863+something unpleasant result.
1864+
1865+This situation is a result of VFS architecture, ->lookup() and
1866+->d_revalidate() is separated. But I never say it is wrong. It is a good
1867+design from VFS's point of view. It is just not suitable for sub-VFS
1868+character in aufs.
1869+
1870+Aufs supports such case by three level of revalidation which is
1871+selectable by user.
1872+1. Simple Revalidate
1873+ Addition to the native flow in VFS's, confirm the child-parent
1874+ relationship on the branch just after locking the parent dir on the
1875+ branch in the "actual operation" (step 4). When this validation
1876+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1877+ checks the validation of the dentry on branches.
1878+2. Monitor Changes Internally by Inotify/Fsnotify
1879+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1880+ the dentry on the branch, and returns EBUSY if it finds different
1881+ dentry.
1882+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1883+ during it is in cache. When the event is notified, aufs registers a
1884+ function to kernel 'events' thread by schedule_work(). And the
1885+ function sets some special status to the cached aufs dentry and inode
1886+ private data. If they are not cached, then aufs has nothing to
1887+ do. When the same file is accessed through aufs (step 0-3) later,
1888+ aufs will detect the status and refresh all necessary data.
1889+ In this mode, aufs has to ignore the event which is fired by aufs
1890+ itself.
1891+3. No Extra Validation
1892+ This is the simplest test and doesn't add any additional revalidation
7e9cd9fe 1893+ test, and skip the revalidation in step 4. It is useful and improves
53392da6
AM
1894+ aufs performance when system surely hide the aufs branches from user,
1895+ by over-mounting something (or another method).
1896diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1897--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 1898+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2018-04-15 08:49:13.394483860 +0200
7e9cd9fe 1899@@ -0,0 +1,74 @@
53392da6 1900+
b00004a5 1901+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
1902+#
1903+# This program is free software; you can redistribute it and/or modify
1904+# it under the terms of the GNU General Public License as published by
1905+# the Free Software Foundation; either version 2 of the License, or
1906+# (at your option) any later version.
1907+#
1908+# This program is distributed in the hope that it will be useful,
1909+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1910+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1911+# GNU General Public License for more details.
1912+#
1913+# You should have received a copy of the GNU General Public License
523b37e3 1914+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1915+
1916+Branch Manipulation
1917+
1918+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1919+and changing its permission/attribute, there are a lot of works to do.
1920+
1921+
1922+Add a Branch
1923+----------------------------------------------------------------------
1924+o Confirm the adding dir exists outside of aufs, including loopback
7e9cd9fe 1925+ mount, and its various attributes.
53392da6
AM
1926+o Initialize the xino file and whiteout bases if necessary.
1927+ See struct.txt.
1928+
1929+o Check the owner/group/mode of the directory
1930+ When the owner/group/mode of the adding directory differs from the
1931+ existing branch, aufs issues a warning because it may impose a
1932+ security risk.
1933+ For example, when a upper writable branch has a world writable empty
1934+ top directory, a malicious user can create any files on the writable
1935+ branch directly, like copy-up and modify manually. If something like
1936+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1937+ writable branch, and the writable branch is world-writable, then a
1938+ malicious guy may create /etc/passwd on the writable branch directly
1939+ and the infected file will be valid in aufs.
7e9cd9fe 1940+ I am afraid it can be a security issue, but aufs can do nothing except
53392da6
AM
1941+ producing a warning.
1942+
1943+
1944+Delete a Branch
1945+----------------------------------------------------------------------
1946+o Confirm the deleting branch is not busy
1947+ To be general, there is one merit to adopt "remount" interface to
1948+ manipulate branches. It is to discard caches. At deleting a branch,
1949+ aufs checks the still cached (and connected) dentries and inodes. If
1950+ there are any, then they are all in-use. An inode without its
1951+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1952+
1953+ For the cached one, aufs checks whether the same named entry exists on
1954+ other branches.
1955+ If the cached one is a directory, because aufs provides a merged view
1956+ to users, as long as one dir is left on any branch aufs can show the
1957+ dir to users. In this case, the branch can be removed from aufs.
1958+ Otherwise aufs rejects deleting the branch.
1959+
1960+ If any file on the deleting branch is opened by aufs, then aufs
1961+ rejects deleting.
1962+
1963+
1964+Modify the Permission of a Branch
1965+----------------------------------------------------------------------
1966+o Re-initialize or remove the xino file and whiteout bases if necessary.
1967+ See struct.txt.
1968+
1969+o rw --> ro: Confirm the modifying branch is not busy
1970+ Aufs rejects the request if any of these conditions are true.
1971+ - a file on the branch is mmap-ed.
1972+ - a regular file on the branch is opened for write and there is no
1973+ same named entry on the upper branch.
1974diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1975--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 1976+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2018-04-15 08:49:13.394483860 +0200
523b37e3 1977@@ -0,0 +1,64 @@
53392da6 1978+
b00004a5 1979+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
1980+#
1981+# This program is free software; you can redistribute it and/or modify
1982+# it under the terms of the GNU General Public License as published by
1983+# the Free Software Foundation; either version 2 of the License, or
1984+# (at your option) any later version.
1985+#
1986+# This program is distributed in the hope that it will be useful,
1987+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1988+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1989+# GNU General Public License for more details.
1990+#
1991+# You should have received a copy of the GNU General Public License
523b37e3 1992+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1993+
1994+Policies to Select One among Multiple Writable Branches
1995+----------------------------------------------------------------------
1996+When the number of writable branch is more than one, aufs has to decide
1997+the target branch for file creation or copy-up. By default, the highest
1998+writable branch which has the parent (or ancestor) dir of the target
1999+file is chosen (top-down-parent policy).
2000+By user's request, aufs implements some other policies to select the
7e9cd9fe
AM
2001+writable branch, for file creation several policies, round-robin,
2002+most-free-space, and other policies. For copy-up, top-down-parent,
2003+bottom-up-parent, bottom-up and others.
53392da6
AM
2004+
2005+As expected, the round-robin policy selects the branch in circular. When
2006+you have two writable branches and creates 10 new files, 5 files will be
2007+created for each branch. mkdir(2) systemcall is an exception. When you
2008+create 10 new directories, all will be created on the same branch.
2009+And the most-free-space policy selects the one which has most free
2010+space among the writable branches. The amount of free space will be
2011+checked by aufs internally, and users can specify its time interval.
2012+
2013+The policies for copy-up is more simple,
2014+top-down-parent is equivalent to the same named on in create policy,
2015+bottom-up-parent selects the writable branch where the parent dir
2016+exists and the nearest upper one from the copyup-source,
2017+bottom-up selects the nearest upper writable branch from the
2018+copyup-source, regardless the existence of the parent dir.
2019+
2020+There are some rules or exceptions to apply these policies.
2021+- If there is a readonly branch above the policy-selected branch and
2022+ the parent dir is marked as opaque (a variation of whiteout), or the
2023+ target (creating) file is whiteout-ed on the upper readonly branch,
2024+ then the result of the policy is ignored and the target file will be
2025+ created on the nearest upper writable branch than the readonly branch.
2026+- If there is a writable branch above the policy-selected branch and
2027+ the parent dir is marked as opaque or the target file is whiteouted
2028+ on the branch, then the result of the policy is ignored and the target
2029+ file will be created on the highest one among the upper writable
2030+ branches who has diropq or whiteout. In case of whiteout, aufs removes
2031+ it as usual.
2032+- link(2) and rename(2) systemcalls are exceptions in every policy.
2033+ They try selecting the branch where the source exists as possible
2034+ since copyup a large file will take long time. If it can't be,
2035+ ie. the branch where the source exists is readonly, then they will
2036+ follow the copyup policy.
2037+- There is an exception for rename(2) when the target exists.
2038+ If the rename target exists, aufs compares the index of the branches
2039+ where the source and the target exists and selects the higher
2040+ one. If the selected branch is readonly, then aufs follows the
2041+ copyup policy.
8b6a4947
AM
2042diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot linux/Documentation/filesystems/aufs/design/06dirren.dot
2043--- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.dot 1970-01-01 01:00:00.000000000 +0100
b00004a5 2044+++ linux/Documentation/filesystems/aufs/design/06dirren.dot 2018-04-15 08:49:13.394483860 +0200
8b6a4947
AM
2045@@ -0,0 +1,31 @@
2046+
2047+// to view this graph, run dot(1) command in GRAPHVIZ.
2048+
2049+digraph G {
2050+node [shape=box];
2051+whinfo [label="detailed info file\n(lower_brid_root-hinum, h_inum, namelen, old name)"];
2052+
2053+node [shape=oval];
2054+
2055+aufs_rename -> whinfo [label="store/remove"];
2056+
2057+node [shape=oval];
2058+inode_list [label="h_inum list in branch\ncache"];
2059+
2060+node [shape=box];
2061+whinode [label="h_inum list file"];
2062+
2063+node [shape=oval];
2064+brmgmt [label="br_add/del/mod/umount"];
2065+
2066+brmgmt -> inode_list [label="create/remove"];
2067+brmgmt -> whinode [label="load/store"];
2068+
2069+inode_list -> whinode [style=dashed,dir=both];
2070+
2071+aufs_rename -> inode_list [label="add/del"];
2072+
2073+aufs_lookup -> inode_list [label="search"];
2074+
2075+aufs_lookup -> whinfo [label="load/remove"];
2076+}
2077diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt linux/Documentation/filesystems/aufs/design/06dirren.txt
2078--- /usr/share/empty/Documentation/filesystems/aufs/design/06dirren.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 2079+++ linux/Documentation/filesystems/aufs/design/06dirren.txt 2018-04-15 08:49:13.394483860 +0200
8b6a4947
AM
2080@@ -0,0 +1,102 @@
2081+
b00004a5 2082+# Copyright (C) 2017-2018 Junjiro R. Okajima
8b6a4947
AM
2083+#
2084+# This program is free software; you can redistribute it and/or modify
2085+# it under the terms of the GNU General Public License as published by
2086+# the Free Software Foundation; either version 2 of the License, or
2087+# (at your option) any later version.
2088+#
2089+# This program is distributed in the hope that it will be useful,
2090+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2091+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2092+# GNU General Public License for more details.
2093+#
2094+# You should have received a copy of the GNU General Public License
2095+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2096+
2097+Special handling for renaming a directory (DIRREN)
2098+----------------------------------------------------------------------
2099+First, let's assume we have a simple usecase.
2100+
2101+- /u = /rw + /ro
2102+- /rw/dirA exists
2103+- /ro/dirA and /ro/dirA/file exist too
2104+- there is no dirB on both branches
2105+- a user issues rename("dirA", "dirB")
2106+
2107+Now, what should aufs behave against this rename(2)?
2108+There are a few possible cases.
2109+
2110+A. returns EROFS.
2111+ since dirA exists on a readonly branch which cannot be renamed.
2112+B. returns EXDEV.
2113+ it is possible to copy-up dirA (only the dir itself), but the child
2114+ entries ("file" in this case) should not be. it must be a bad
2115+ approach to copy-up recursively.
2116+C. returns a success.
2117+ even the branch /ro is readonly, aufs tries renaming it. Obviously it
2118+ is a violation of aufs' policy.
2119+D. construct an extra information which indicates that /ro/dirA should
2120+ be handled as the name of dirB.
2121+ overlayfs has a similar feature called REDIRECT.
2122+
2123+Until now, aufs implements the case B only which returns EXDEV, and
2124+expects the userspace application behaves like mv(1) which tries
2125+issueing rename(2) recursively.
2126+
2127+A new aufs feature called DIRREN is introduced which implements the case
2128+D. There are several "extra information" added.
2129+
2130+1. detailed info per renamed directory
2131+ path: /rw/dirB/$AUFS_WH_DR_INFO_PFX.<lower branch-id>
2132+2. the inode-number list of directories on a branch
2133+ path: /rw/dirB/$AUFS_WH_DR_BRHINO
2134+
2135+The filename of "detailed info per directory" represents the lower
2136+branch, and its format is
2137+- a type of the branch id
2138+ one of these.
2139+ + uuid (not implemented yet)
2140+ + fsid
2141+ + dev
2142+- the inode-number of the branch root dir
2143+
2144+And it contains these info in a single regular file.
2145+- magic number
2146+- branch's inode-number of the logically renamed dir
2147+- the name of the before-renamed dir
2148+
2149+The "detailed info per directory" file is created in aufs rename(2), and
2150+loaded in any lookup.
2151+The info is considered in lookup for the matching case only. Here
2152+"matching" means that the root of branch (in the info filename) is same
2153+to the current looking-up branch. After looking-up the before-renamed
2154+name, the inode-number is compared. And the matched dentry is used.
2155+
2156+The "inode-number list of directories" is a regular file which contains
2157+simply the inode-numbers on the branch. The file is created or updated
2158+in removing the branch, and loaded in adding the branch. Its lifetime is
2159+equal to the branch.
2160+The list is refered in lookup, and when the current target inode is
2161+found in the list, the aufs tries loading the "detailed info per
2162+directory" and get the changed and valid name of the dir.
2163+
2164+Theoretically these "extra informaiton" may be able to be put into XATTR
2165+in the dir inode. But aufs doesn't choose this way because
2166+1. XATTR may not be supported by the branch (or its configuration)
2167+2. XATTR may have its size limit.
2168+3. XATTR may be less easy to convert than a regular file, when the
2169+ format of the info is changed in the future.
2170+At the same time, I agree that the regular file approach is much slower
2171+than XATTR approach. So, in the future, aufs may take the XATTR or other
2172+better approach.
2173+
2174+This DIRREN feature is enabled by aufs configuration, and is activated
2175+by a new mount option.
2176+
2177+For the more complicated case, there is a work with UDBA option, which
2178+is to dected the direct access to the branches (by-passing aufs) and to
2179+maintain the cashes in aufs. Since a single cached aufs dentry may
2180+contains two names, before- and after-rename, the name comparision in
2181+UDBA handler may not work correctly. In this case, the behaviour will be
2182+equivalen to udba=reval case.
076b876e
AM
2183diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
2184--- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 2185+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2018-04-15 08:49:13.394483860 +0200
076b876e
AM
2186@@ -0,0 +1,120 @@
2187+
b00004a5 2188+# Copyright (C) 2011-2018 Junjiro R. Okajima
076b876e
AM
2189+#
2190+# This program is free software; you can redistribute it and/or modify
2191+# it under the terms of the GNU General Public License as published by
2192+# the Free Software Foundation; either version 2 of the License, or
2193+# (at your option) any later version.
2194+#
2195+# This program is distributed in the hope that it will be useful,
2196+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2197+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2198+# GNU General Public License for more details.
2199+#
2200+# You should have received a copy of the GNU General Public License
2201+# along with this program; if not, write to the Free Software
2202+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2203+
2204+
2205+File-based Hierarchical Storage Management (FHSM)
2206+----------------------------------------------------------------------
2207+Hierarchical Storage Management (or HSM) is a well-known feature in the
2208+storage world. Aufs provides this feature as file-based with multiple
7e9cd9fe 2209+writable branches, based upon the principle of "Colder, the Lower".
076b876e 2210+Here the word "colder" means that the less used files, and "lower" means
7e9cd9fe 2211+that the position in the order of the stacked branches vertically.
076b876e
AM
2212+These multiple writable branches are prioritized, ie. the topmost one
2213+should be the fastest drive and be used heavily.
2214+
2215+o Characters in aufs FHSM story
2216+- aufs itself and a new branch attribute.
2217+- a new ioctl interface to move-down and to establish a connection with
2218+ the daemon ("move-down" is a converse of "copy-up").
2219+- userspace tool and daemon.
2220+
2221+The userspace daemon establishes a connection with aufs and waits for
2222+the notification. The notified information is very similar to struct
2223+statfs containing the number of consumed blocks and inodes.
2224+When the consumed blocks/inodes of a branch exceeds the user-specified
2225+upper watermark, the daemon activates its move-down process until the
2226+consumed blocks/inodes reaches the user-specified lower watermark.
2227+
2228+The actual move-down is done by aufs based upon the request from
2229+user-space since we need to maintain the inode number and the internal
2230+pointer arrays in aufs.
2231+
2232+Currently aufs FHSM handles the regular files only. Additionally they
2233+must not be hard-linked nor pseudo-linked.
2234+
2235+
2236+o Cowork of aufs and the user-space daemon
2237+ During the userspace daemon established the connection, aufs sends a
2238+ small notification to it whenever aufs writes something into the
2239+ writable branch. But it may cost high since aufs issues statfs(2)
2240+ internally. So user can specify a new option to cache the
2241+ info. Actually the notification is controlled by these factors.
2242+ + the specified cache time.
2243+ + classified as "force" by aufs internally.
2244+ Until the specified time expires, aufs doesn't send the info
2245+ except the forced cases. When aufs decide forcing, the info is always
2246+ notified to userspace.
2247+ For example, the number of free inodes is generally large enough and
2248+ the shortage of it happens rarely. So aufs doesn't force the
2249+ notification when creating a new file, directory and others. This is
2250+ the typical case which aufs doesn't force.
2251+ When aufs writes the actual filedata and the files consumes any of new
2252+ blocks, the aufs forces notifying.
2253+
2254+
2255+o Interfaces in aufs
2256+- New branch attribute.
2257+ + fhsm
2258+ Specifies that the branch is managed by FHSM feature. In other word,
2259+ participant in the FHSM.
2260+ When nofhsm is set to the branch, it will not be the source/target
2261+ branch of the move-down operation. This attribute is set
2262+ independently from coo and moo attributes, and if you want full
2263+ FHSM, you should specify them as well.
2264+- New mount option.
2265+ + fhsm_sec
2266+ Specifies a second to suppress many less important info to be
2267+ notified.
2268+- New ioctl.
2269+ + AUFS_CTL_FHSM_FD
2270+ create a new file descriptor which userspace can read the notification
2271+ (a subset of struct statfs) from aufs.
2272+- Module parameter 'brs'
2273+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not
2274+ be set.
2275+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
2276+ When there are two or more branches with fhsm attributes,
2277+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
2278+ terminates it. As a result of remounting and branch-manipulation, the
2279+ number of branches with fhsm attribute can be one. In this case,
2280+ /sbin/mount.aufs will terminate the user-space daemon.
2281+
2282+
2283+Finally the operation is done as these steps in kernel-space.
2284+- make sure that,
2285+ + no one else is using the file.
2286+ + the file is not hard-linked.
2287+ + the file is not pseudo-linked.
2288+ + the file is a regular file.
2289+ + the parent dir is not opaqued.
2290+- find the target writable branch.
2291+- make sure the file is not whiteout-ed by the upper (than the target)
2292+ branch.
2293+- make the parent dir on the target branch.
2294+- mutex lock the inode on the branch.
2295+- unlink the whiteout on the target branch (if exists).
2296+- lookup and create the whiteout-ed temporary name on the target branch.
2297+- copy the file as the whiteout-ed temporary name on the target branch.
2298+- rename the whiteout-ed temporary name to the original name.
2299+- unlink the file on the source branch.
2300+- maintain the internal pointer array and the external inode number
2301+ table (XINO).
2302+- maintain the timestamps and other attributes of the parent dir and the
2303+ file.
2304+
2305+And of course, in every step, an error may happen. So the operation
2306+should restore the original file state after an error happens.
53392da6
AM
2307diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
2308--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 2309+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2018-04-15 08:49:13.394483860 +0200
b912730e 2310@@ -0,0 +1,72 @@
53392da6 2311+
b00004a5 2312+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
2313+#
2314+# This program is free software; you can redistribute it and/or modify
2315+# it under the terms of the GNU General Public License as published by
2316+# the Free Software Foundation; either version 2 of the License, or
2317+# (at your option) any later version.
2318+#
2319+# This program is distributed in the hope that it will be useful,
2320+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2321+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2322+# GNU General Public License for more details.
2323+#
2324+# You should have received a copy of the GNU General Public License
523b37e3 2325+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2326+
2327+mmap(2) -- File Memory Mapping
2328+----------------------------------------------------------------------
2329+In aufs, the file-mapped pages are handled by a branch fs directly, no
2330+interaction with aufs. It means aufs_mmap() calls the branch fs's
2331+->mmap().
2332+This approach is simple and good, but there is one problem.
7e9cd9fe 2333+Under /proc, several entries show the mmapped files by its path (with
53392da6
AM
2334+device and inode number), and the printed path will be the path on the
2335+branch fs's instead of virtual aufs's.
2336+This is not a problem in most cases, but some utilities lsof(1) (and its
2337+user) may expect the path on aufs.
2338+
2339+To address this issue, aufs adds a new member called vm_prfile in struct
2340+vm_area_struct (and struct vm_region). The original vm_file points to
2341+the file on the branch fs in order to handle everything correctly as
2342+usual. The new vm_prfile points to a virtual file in aufs, and the
2343+show-functions in procfs refers to vm_prfile if it is set.
2344+Also we need to maintain several other places where touching vm_file
2345+such like
2346+- fork()/clone() copies vma and the reference count of vm_file is
2347+ incremented.
2348+- merging vma maintains the ref count too.
2349+
7e9cd9fe 2350+This is not a good approach. It just fakes the printed path. But it
53392da6
AM
2351+leaves all behaviour around f_mapping unchanged. This is surely an
2352+advantage.
2353+Actually aufs had adopted another complicated approach which calls
2354+generic_file_mmap() and handles struct vm_operations_struct. In this
2355+approach, aufs met a hard problem and I could not solve it without
2356+switching the approach.
b912730e
AM
2357+
2358+There may be one more another approach which is
2359+- bind-mount the branch-root onto the aufs-root internally
2360+- grab the new vfsmount (ie. struct mount)
2361+- lazy-umount the branch-root internally
2362+- in open(2) the aufs-file, open the branch-file with the hidden
2363+ vfsmount (instead of the original branch's vfsmount)
2364+- ideally this "bind-mount and lazy-umount" should be done atomically,
2365+ but it may be possible from userspace by the mount helper.
2366+
2367+Adding the internal hidden vfsmount and using it in opening a file, the
2368+file path under /proc will be printed correctly. This approach looks
2369+smarter, but is not possible I am afraid.
2370+- aufs-root may be bind-mount later. when it happens, another hidden
2371+ vfsmount will be required.
2372+- it is hard to get the chance to bind-mount and lazy-umount
2373+ + in kernel-space, FS can have vfsmount in open(2) via
2374+ file->f_path, and aufs can know its vfsmount. But several locks are
2375+ already acquired, and if aufs tries to bind-mount and lazy-umount
2376+ here, then it may cause a deadlock.
2377+ + in user-space, bind-mount doesn't invoke the mount helper.
2378+- since /proc shows dev and ino, aufs has to give vma these info. it
2379+ means a new member vm_prinode will be necessary. this is essentially
2380+ equivalent to vm_prfile described above.
2381+
2382+I have to give up this "looks-smater" approach.
c1595e42
JR
2383diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
2384--- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 2385+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2018-04-15 08:49:13.394483860 +0200
c1595e42
JR
2386@@ -0,0 +1,96 @@
2387+
b00004a5 2388+# Copyright (C) 2014-2018 Junjiro R. Okajima
c1595e42
JR
2389+#
2390+# This program is free software; you can redistribute it and/or modify
2391+# it under the terms of the GNU General Public License as published by
2392+# the Free Software Foundation; either version 2 of the License, or
2393+# (at your option) any later version.
2394+#
2395+# This program is distributed in the hope that it will be useful,
2396+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2397+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2398+# GNU General Public License for more details.
2399+#
2400+# You should have received a copy of the GNU General Public License
2401+# along with this program; if not, write to the Free Software
2402+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2403+
2404+
2405+Listing XATTR/EA and getting the value
2406+----------------------------------------------------------------------
2407+For the inode standard attributes (owner, group, timestamps, etc.), aufs
2408+shows the values from the topmost existing file. This behaviour is good
7e9cd9fe 2409+for the non-dir entries since the bahaviour exactly matches the shown
c1595e42
JR
2410+information. But for the directories, aufs considers all the same named
2411+entries on the lower branches. Which means, if one of the lower entry
2412+rejects readdir call, then aufs returns an error even if the topmost
2413+entry allows it. This behaviour is necessary to respect the branch fs's
2414+security, but can make users confused since the user-visible standard
2415+attributes don't match the behaviour.
2416+To address this issue, aufs has a mount option called dirperm1 which
2417+checks the permission for the topmost entry only, and ignores the lower
2418+entry's permission.
2419+
2420+A similar issue can happen around XATTR.
2421+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
7e9cd9fe
AM
2422+always set. Otherwise these very unpleasant situation would happen.
2423+- listxattr(2) may return the duplicated entries.
c1595e42
JR
2424+- users may not be able to remove or reset the XATTR forever,
2425+
2426+
2427+XATTR/EA support in the internal (copy,move)-(up,down)
2428+----------------------------------------------------------------------
7e9cd9fe 2429+Generally the extended attributes of inode are categorized as these.
c1595e42
JR
2430+- "security" for LSM and capability.
2431+- "system" for posix ACL, 'acl' mount option is required for the branch
2432+ fs generally.
2433+- "trusted" for userspace, CAP_SYS_ADMIN is required.
2434+- "user" for userspace, 'user_xattr' mount option is required for the
2435+ branch fs generally.
2436+
2437+Moreover there are some other categories. Aufs handles these rather
2438+unpopular categories as the ordinary ones, ie. there is no special
2439+condition nor exception.
2440+
2441+In copy-up, the support for XATTR on the dst branch may differ from the
2442+src branch. In this case, the copy-up operation will get an error and
7e9cd9fe
AM
2443+the original user operation which triggered the copy-up will fail. It
2444+can happen that even all copy-up will fail.
c1595e42
JR
2445+When both of src and dst branches support XATTR and if an error occurs
2446+during copying XATTR, then the copy-up should fail obviously. That is a
2447+good reason and aufs should return an error to userspace. But when only
7e9cd9fe 2448+the src branch support that XATTR, aufs should not return an error.
c1595e42
JR
2449+For example, the src branch supports ACL but the dst branch doesn't
2450+because the dst branch may natively un-support it or temporary
2451+un-support it due to "noacl" mount option. Of course, the dst branch fs
2452+may NOT return an error even if the XATTR is not supported. It is
2453+totally up to the branch fs.
2454+
2455+Anyway when the aufs internal copy-up gets an error from the dst branch
2456+fs, then aufs tries removing the just copied entry and returns the error
2457+to the userspace. The worst case of this situation will be all copy-up
2458+will fail.
2459+
2460+For the copy-up operation, there two basic approaches.
2461+- copy the specified XATTR only (by category above), and return the
7e9cd9fe 2462+ error unconditionally if it happens.
c1595e42
JR
2463+- copy all XATTR, and ignore the error on the specified category only.
2464+
2465+In order to support XATTR and to implement the correct behaviour, aufs
7e9cd9fe
AM
2466+chooses the latter approach and introduces some new branch attributes,
2467+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
c1595e42 2468+They correspond to the XATTR namespaces (see above). Additionally, to be
7e9cd9fe
AM
2469+convenient, "icex" is also provided which means all "icex*" attributes
2470+are set (here the word "icex" stands for "ignore copy-error on XATTR").
c1595e42
JR
2471+
2472+The meaning of these attributes is to ignore the error from setting
2473+XATTR on that branch.
2474+Note that aufs tries copying all XATTR unconditionally, and ignores the
2475+error from the dst branch according to the specified attributes.
2476+
2477+Some XATTR may have its default value. The default value may come from
2478+the parent dir or the environment. If the default value is set at the
2479+file creating-time, it will be overwritten by copy-up.
2480+Some contradiction may happen I am afraid.
2481+Do we need another attribute to stop copying XATTR? I am unsure. For
2482+now, aufs implements the branch attributes to ignore the error.
53392da6
AM
2483diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
2484--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 2485+++ linux/Documentation/filesystems/aufs/design/07export.txt 2018-04-15 08:49:13.394483860 +0200
523b37e3 2486@@ -0,0 +1,58 @@
53392da6 2487+
b00004a5 2488+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
2489+#
2490+# This program is free software; you can redistribute it and/or modify
2491+# it under the terms of the GNU General Public License as published by
2492+# the Free Software Foundation; either version 2 of the License, or
2493+# (at your option) any later version.
2494+#
2495+# This program is distributed in the hope that it will be useful,
2496+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2497+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2498+# GNU General Public License for more details.
2499+#
2500+# You should have received a copy of the GNU General Public License
523b37e3 2501+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2502+
2503+Export Aufs via NFS
2504+----------------------------------------------------------------------
2505+Here is an approach.
2506+- like xino/xib, add a new file 'xigen' which stores aufs inode
2507+ generation.
2508+- iget_locked(): initialize aufs inode generation for a new inode, and
2509+ store it in xigen file.
2510+- destroy_inode(): increment aufs inode generation and store it in xigen
2511+ file. it is necessary even if it is not unlinked, because any data of
2512+ inode may be changed by UDBA.
2513+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
2514+ build file handle by
2515+ + branch id (4 bytes)
2516+ + superblock generation (4 bytes)
2517+ + inode number (4 or 8 bytes)
2518+ + parent dir inode number (4 or 8 bytes)
2519+ + inode generation (4 bytes))
2520+ + return value of exportfs_encode_fh() for the parent on a branch (4
2521+ bytes)
2522+ + file handle for a branch (by exportfs_encode_fh())
2523+- fh_to_dentry():
2524+ + find the index of a branch from its id in handle, and check it is
2525+ still exist in aufs.
2526+ + 1st level: get the inode number from handle and search it in cache.
7e9cd9fe
AM
2527+ + 2nd level: if not found in cache, get the parent inode number from
2528+ the handle and search it in cache. and then open the found parent
2529+ dir, find the matching inode number by vfs_readdir() and get its
2530+ name, and call lookup_one_len() for the target dentry.
53392da6
AM
2531+ + 3rd level: if the parent dir is not cached, call
2532+ exportfs_decode_fh() for a branch and get the parent on a branch,
2533+ build a pathname of it, convert it a pathname in aufs, call
2534+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
2535+ the 2nd level.
2536+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
2537+ for every branch, but not itself. to get this, (currently) aufs
2538+ searches in current->nsproxy->mnt_ns list. it may not be a good
2539+ idea, but I didn't get other approach.
2540+ + test the generation of the gotten inode.
2541+- every inode operation: they may get EBUSY due to UDBA. in this case,
2542+ convert it into ESTALE for NFSD.
2543+- readdir(): call lockdep_on/off() because filldir in NFSD calls
2544+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
2545diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
2546--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 2547+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2018-04-15 08:49:13.394483860 +0200
523b37e3 2548@@ -0,0 +1,52 @@
53392da6 2549+
b00004a5 2550+# Copyright (C) 2005-2018 Junjiro R. Okajima
53392da6
AM
2551+#
2552+# This program is free software; you can redistribute it and/or modify
2553+# it under the terms of the GNU General Public License as published by
2554+# the Free Software Foundation; either version 2 of the License, or
2555+# (at your option) any later version.
2556+#
2557+# This program is distributed in the hope that it will be useful,
2558+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2559+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2560+# GNU General Public License for more details.
2561+#
2562+# You should have received a copy of the GNU General Public License
523b37e3 2563+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2564+
2565+Show Whiteout Mode (shwh)
2566+----------------------------------------------------------------------
2567+Generally aufs hides the name of whiteouts. But in some cases, to show
2568+them is very useful for users. For instance, creating a new middle layer
2569+(branch) by merging existing layers.
2570+
2571+(borrowing aufs1 HOW-TO from a user, Michael Towers)
2572+When you have three branches,
2573+- Bottom: 'system', squashfs (underlying base system), read-only
2574+- Middle: 'mods', squashfs, read-only
2575+- Top: 'overlay', ram (tmpfs), read-write
2576+
2577+The top layer is loaded at boot time and saved at shutdown, to preserve
2578+the changes made to the system during the session.
2579+When larger changes have been made, or smaller changes have accumulated,
2580+the size of the saved top layer data grows. At this point, it would be
2581+nice to be able to merge the two overlay branches ('mods' and 'overlay')
2582+and rewrite the 'mods' squashfs, clearing the top layer and thus
2583+restoring save and load speed.
2584+
2585+This merging is simplified by the use of another aufs mount, of just the
2586+two overlay branches using the 'shwh' option.
2587+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
2588+ aufs /livesys/merge_union
2589+
2590+A merged view of these two branches is then available at
2591+/livesys/merge_union, and the new feature is that the whiteouts are
2592+visible!
2593+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
2594+writing to all branches. Also the default mode for all branches is 'ro'.
2595+It is now possible to save the combined contents of the two overlay
2596+branches to a new squashfs, e.g.:
2597+# mksquashfs /livesys/merge_union /path/to/newmods.squash
2598+
2599+This new squashfs archive can be stored on the boot device and the
2600+initramfs will use it to replace the old one at the next boot.
2601diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
2602--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
b00004a5 2603+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2018-04-15 08:49:13.394483860 +0200
7e9cd9fe 2604@@ -0,0 +1,47 @@
53392da6 2605+
b00004a5 2606+# Copyright (C) 2010-2018 Junjiro R. Okajima
53392da6
AM
2607+#
2608+# This program is free software; you can redistribute it and/or modify
2609+# it under the terms of the GNU General Public License as published by
2610+# the Free Software Foundation; either version 2 of the License, or
2611+# (at your option) any later version.
2612+#
2613+# This program is distributed in the hope that it will be useful,
2614+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2615+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2616+# GNU General Public License for more details.
2617+#
2618+# You should have received a copy of the GNU General Public License
523b37e3 2619+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2620+
2621+Dynamically customizable FS operations
2622+----------------------------------------------------------------------
2623+Generally FS operations (struct inode_operations, struct
2624+address_space_operations, struct file_operations, etc.) are defined as
2625+"static const", but it never means that FS have only one set of
2626+operation. Some FS have multiple sets of them. For instance, ext2 has
2627+three sets, one for XIP, for NOBH, and for normal.
2628+Since aufs overrides and redirects these operations, sometimes aufs has
7e9cd9fe 2629+to change its behaviour according to the branch FS type. More importantly
53392da6
AM
2630+VFS acts differently if a function (member in the struct) is set or
2631+not. It means aufs should have several sets of operations and select one
2632+among them according to the branch FS definition.
2633+
7e9cd9fe 2634+In order to solve this problem and not to affect the behaviour of VFS,
53392da6 2635+aufs defines these operations dynamically. For instance, aufs defines
7e9cd9fe
AM
2636+dummy direct_IO function for struct address_space_operations, but it may
2637+not be set to the address_space_operations actually. When the branch FS
2638+doesn't have it, aufs doesn't set it to its address_space_operations
2639+while the function definition itself is still alive. So the behaviour
2640+itself will not change, and it will return an error when direct_IO is
2641+not set.
53392da6
AM
2642+
2643+The lifetime of these dynamically generated operation object is
2644+maintained by aufs branch object. When the branch is removed from aufs,
2645+the reference counter of the object is decremented. When it reaches
2646+zero, the dynamically generated operation object will be freed.
2647+
7e9cd9fe
AM
2648+This approach is designed to support AIO (io_submit), Direct I/O and
2649+XIP (DAX) mainly.
2650+Currently this approach is applied to address_space_operations for
2651+regular files only.
53392da6
AM
2652diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
2653--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
2654+++ linux/Documentation/filesystems/aufs/README 2018-10-23 12:33:35.579375203 +0200
2655@@ -0,0 +1,394 @@
53392da6 2656+
5527c038 2657+Aufs4 -- advanced multi layered unification filesystem version 4.x
53392da6
AM
2658+http://aufs.sf.net
2659+Junjiro R. Okajima
2660+
2661+
2662+0. Introduction
2663+----------------------------------------
2664+In the early days, aufs was entirely re-designed and re-implemented
7e9cd9fe 2665+Unionfs Version 1.x series. Adding many original ideas, approaches,
53392da6
AM
2666+improvements and implementations, it becomes totally different from
2667+Unionfs while keeping the basic features.
2668+Recently, Unionfs Version 2.x series begin taking some of the same
2669+approaches to aufs1's.
2670+Unionfs is being developed by Professor Erez Zadok at Stony Brook
2671+University and his team.
2672+
5527c038 2673+Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3.
53392da6
AM
2674+If you want older kernel version support, try aufs2-2.6.git or
2675+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
2676+
2677+Note: it becomes clear that "Aufs was rejected. Let's give it up."
38d290e6
JR
2678+ According to Christoph Hellwig, linux rejects all union-type
2679+ filesystems but UnionMount.
53392da6
AM
2680+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
2681+
38d290e6
JR
2682+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
2683+ UnionMount, and he pointed out an issue around a directory mutex
2684+ lock and aufs addressed it. But it is still unsure whether aufs will
2685+ be merged (or any other union solution).
076b876e 2686+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
38d290e6 2687+
53392da6
AM
2688+
2689+1. Features
2690+----------------------------------------
2691+- unite several directories into a single virtual filesystem. The member
2692+ directory is called as a branch.
2693+- you can specify the permission flags to the branch, which are 'readonly',
2694+ 'readwrite' and 'whiteout-able.'
2695+- by upper writable branch, internal copyup and whiteout, files/dirs on
2696+ readonly branch are modifiable logically.
2697+- dynamic branch manipulation, add, del.
2698+- etc...
2699+
7e9cd9fe
AM
2700+Also there are many enhancements in aufs, such as:
2701+- test only the highest one for the directory permission (dirperm1)
2702+- copyup on open (coo=)
2703+- 'move' policy for copy-up between two writable branches, after
2704+ checking free space.
2705+- xattr, acl
53392da6
AM
2706+- readdir(3) in userspace.
2707+- keep inode number by external inode number table
2708+- keep the timestamps of file/dir in internal copyup operation
2709+- seekable directory, supporting NFS readdir.
2710+- whiteout is hardlinked in order to reduce the consumption of inodes
2711+ on branch
2712+- do not copyup, nor create a whiteout when it is unnecessary
2713+- revert a single systemcall when an error occurs in aufs
2714+- remount interface instead of ioctl
2715+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
2716+- loopback mounted filesystem as a branch
2717+- kernel thread for removing the dir who has a plenty of whiteouts
2718+- support copyup sparse file (a file which has a 'hole' in it)
2719+- default permission flags for branches
2720+- selectable permission flags for ro branch, whether whiteout can
2721+ exist or not
2722+- export via NFS.
2723+- support <sysfs>/fs/aufs and <debugfs>/aufs.
2724+- support multiple writable branches, some policies to select one
2725+ among multiple writable branches.
2726+- a new semantics for link(2) and rename(2) to support multiple
2727+ writable branches.
2728+- no glibc changes are required.
2729+- pseudo hardlink (hardlink over branches)
2730+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
2731+ including NFS or remote filesystem branch.
2732+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
2733+- and more...
2734+
5527c038 2735+Currently these features are dropped temporary from aufs4.
53392da6 2736+See design/08plan.txt in detail.
53392da6
AM
2737+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
2738+ (robr)
2739+- statistics of aufs thread (/sys/fs/aufs/stat)
53392da6
AM
2740+
2741+Features or just an idea in the future (see also design/*.txt),
2742+- reorder the branch index without del/re-add.
2743+- permanent xino files for NFSD
2744+- an option for refreshing the opened files after add/del branches
53392da6
AM
2745+- light version, without branch manipulation. (unnecessary?)
2746+- copyup in userspace
2747+- inotify in userspace
2748+- readv/writev
53392da6
AM
2749+
2750+
2751+2. Download
2752+----------------------------------------
5527c038
JR
2753+There are three GIT trees for aufs4, aufs4-linux.git,
2754+aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in
1e00d052 2755+"aufs-util.git."
5527c038
JR
2756+While the aufs-util is always necessary, you need either of aufs4-linux
2757+or aufs4-standalone.
1e00d052 2758+
5527c038 2759+The aufs4-linux tree includes the whole linux mainline GIT tree,
1e00d052
AM
2760+git://git.kernel.org/.../torvalds/linux.git.
2761+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
5527c038 2762+build aufs4 as an external kernel module.
2000de60 2763+Several extra patches are not included in this tree. Only
be52b249 2764+aufs4-standalone tree contains them. They are described in the later
2000de60 2765+section "Configuration and Compilation."
1e00d052 2766+
5527c038 2767+On the other hand, the aufs4-standalone tree has only aufs source files
53392da6 2768+and necessary patches, and you can select CONFIG_AUFS_FS=m.
2000de60 2769+But you need to apply all aufs patches manually.
53392da6 2770+
5527c038
JR
2771+You will find GIT branches whose name is in form of "aufs4.x" where "x"
2772+represents the linux kernel version, "linux-4.x". For instance,
2773+"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use
2774+"aufs4.x-rcN" branch.
1e00d052 2775+
5527c038 2776+o aufs4-linux tree
1e00d052 2777+$ git clone --reference /your/linux/git/tree \
5527c038 2778+ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git
1e00d052 2779+- if you don't have linux GIT tree, then remove "--reference ..."
5527c038
JR
2780+$ cd aufs4-linux.git
2781+$ git checkout origin/aufs4.0
53392da6 2782+
2000de60
JR
2783+Or You may want to directly git-pull aufs into your linux GIT tree, and
2784+leave the patch-work to GIT.
2785+$ cd /your/linux/git/tree
5527c038
JR
2786+$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git
2787+$ git fetch aufs4
2788+$ git checkout -b my4.0 v4.0
2789+$ (add your local change...)
2790+$ git pull aufs4 aufs4.0
2791+- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch.
2000de60 2792+- you may need to solve some conflicts between your_changes and
5527c038
JR
2793+ aufs4.0. in this case, git-rerere is recommended so that you can
2794+ solve the similar conflicts automatically when you upgrade to 4.1 or
2000de60
JR
2795+ later in the future.
2796+
5527c038
JR
2797+o aufs4-standalone tree
2798+$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git
2799+$ cd aufs4-standalone.git
2800+$ git checkout origin/aufs4.0
53392da6
AM
2801+
2802+o aufs-util tree
5527c038
JR
2803+$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git
2804+- note that the public aufs-util.git is on SourceForge instead of
2805+ GitHUB.
53392da6 2806+$ cd aufs-util.git
5527c038 2807+$ git checkout origin/aufs4.0
53392da6 2808+
5527c038
JR
2809+Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY.
2810+The minor version number, 'x' in '4.x', of aufs may not always
9dbd164d
AM
2811+follow the minor version number of the kernel.
2812+Because changes in the kernel that cause the use of a new
2813+minor version number do not always require changes to aufs-util.
2814+
2815+Since aufs-util has its own minor version number, you may not be
2816+able to find a GIT branch in aufs-util for your kernel's
2817+exact minor version number.
2818+In this case, you should git-checkout the branch for the
53392da6 2819+nearest lower number.
9dbd164d
AM
2820+
2821+For (an unreleased) example:
5527c038
JR
2822+If you are using "linux-4.10" and the "aufs4.10" branch
2823+does not exist in aufs-util repository, then "aufs4.9", "aufs4.8"
9dbd164d
AM
2824+or something numerically smaller is the branch for your kernel.
2825+
53392da6
AM
2826+Also you can view all branches by
2827+ $ git branch -a
2828+
2829+
2830+3. Configuration and Compilation
2831+----------------------------------------
2832+Make sure you have git-checkout'ed the correct branch.
2833+
5527c038 2834+For aufs4-linux tree,
c06a8ce3 2835+- enable CONFIG_AUFS_FS.
1e00d052
AM
2836+- set other aufs configurations if necessary.
2837+
5527c038 2838+For aufs4-standalone tree,
53392da6
AM
2839+There are several ways to build.
2840+
2841+1.
5527c038
JR
2842+- apply ./aufs4-kbuild.patch to your kernel source files.
2843+- apply ./aufs4-base.patch too.
2844+- apply ./aufs4-mmap.patch too.
2845+- apply ./aufs4-standalone.patch too, if you have a plan to set
2846+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch.
537831f9
AM
2847+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2848+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 2849+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
2850+ =m or =y.
2851+- and build your kernel as usual.
2852+- install the built kernel.
c06a8ce3
AM
2853+ Note: Since linux-3.9, every filesystem module requires an alias
2854+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2855+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
2856+- install the header files too by "make headers_install" to the
2857+ directory where you specify. By default, it is $PWD/usr.
b4510431 2858+ "make help" shows a brief note for headers_install.
53392da6
AM
2859+- and reboot your system.
2860+
2861+2.
2862+- module only (CONFIG_AUFS_FS=m).
5527c038
JR
2863+- apply ./aufs4-base.patch to your kernel source files.
2864+- apply ./aufs4-mmap.patch too.
2865+- apply ./aufs4-standalone.patch too.
53392da6
AM
2866+- build your kernel, don't forget "make headers_install", and reboot.
2867+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 2868+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
2869+ every aufs configurations.
2870+- build the module by simple "make".
c06a8ce3
AM
2871+ Note: Since linux-3.9, every filesystem module requires an alias
2872+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2873+ modules.aliases file.
53392da6
AM
2874+- you can specify ${KDIR} make variable which points to your kernel
2875+ source tree.
2876+- install the files
2877+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
2878+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2879+ + run "make install_headers" (instead of headers_install) to install
2880+ the modified aufs header file (you can specify DESTDIR which is
2881+ available in aufs standalone version's Makefile only), or copy
2882+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2883+ you like manually. By default, the target directory is $PWD/usr.
5527c038 2884+- no need to apply aufs4-kbuild.patch, nor copying source files to your
53392da6
AM
2885+ kernel source tree.
2886+
b4510431 2887+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
2888+ as well as "make headers_install" in the kernel source tree.
2889+ headers_install is subject to be forgotten, but it is essentially
2890+ necessary, not only for building aufs-util.
2891+ You may not meet problems without headers_install in some older
2892+ version though.
2893+
2894+And then,
2895+- read README in aufs-util, build and install it
9dbd164d
AM
2896+- note that your distribution may contain an obsoleted version of
2897+ aufs_type.h in /usr/include/linux or something. When you build aufs
2898+ utilities, make sure that your compiler refers the correct aufs header
2899+ file which is built by "make headers_install."
53392da6
AM
2900+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2901+ then run "make install_ulib" too. And refer to the aufs manual in
2902+ detail.
2903+
5527c038 2904+There several other patches in aufs4-standalone.git. They are all
38d290e6 2905+optional. When you meet some problems, they will help you.
5527c038 2906+- aufs4-loopback.patch
38d290e6
JR
2907+ Supports a nested loopback mount in a branch-fs. This patch is
2908+ unnecessary until aufs produces a message like "you may want to try
2909+ another patch for loopback file".
2910+- vfs-ino.patch
2911+ Modifies a system global kernel internal function get_next_ino() in
2912+ order to stop assigning 0 for an inode-number. Not directly related to
2913+ aufs, but recommended generally.
2914+- tmpfs-idr.patch
2915+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
2916+ the size of aufs XINO files for tmpfs branch. Also it prevents the
2917+ duplication of inode number, which is important for backup tools and
2918+ other utilities. When you find aufs XINO files for tmpfs branch
2919+ growing too much, try this patch.
be52b249
AM
2920+- lockdep-debug.patch
2921+ Because aufs is not only an ordinary filesystem (callee of VFS), but
2922+ also a caller of VFS functions for branch filesystems, subclassing of
2923+ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging
2924+ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will
2925+ need to apply this debug patch to expand several constant values.
2926+ If don't know what LOCKDEP, then you don't have apply this patch.
38d290e6 2927+
53392da6
AM
2928+
2929+4. Usage
2930+----------------------------------------
2931+At first, make sure aufs-util are installed, and please read the aufs
2932+manual, aufs.5 in aufs-util.git tree.
2933+$ man -l aufs.5
2934+
2935+And then,
2936+$ mkdir /tmp/rw /tmp/aufs
2937+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2938+
2939+Here is another example. The result is equivalent.
2940+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2941+ Or
2942+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2943+# mount -o remount,append:${HOME} /tmp/aufs
2944+
2945+Then, you can see whole tree of your home dir through /tmp/aufs. If
2946+you modify a file under /tmp/aufs, the one on your home directory is
2947+not affected, instead the same named file will be newly created under
2948+/tmp/rw. And all of your modification to a file will be applied to
2949+the one under /tmp/rw. This is called the file based Copy on Write
2950+(COW) method.
2951+Aufs mount options are described in aufs.5.
2952+If you run chroot or something and make your aufs as a root directory,
2953+then you need to customize the shutdown script. See the aufs manual in
2954+detail.
2955+
2956+Additionally, there are some sample usages of aufs which are a
2957+diskless system with network booting, and LiveCD over NFS.
2958+See sample dir in CVS tree on SourceForge.
2959+
2960+
2961+5. Contact
2962+----------------------------------------
2963+When you have any problems or strange behaviour in aufs, please let me
2964+know with:
2965+- /proc/mounts (instead of the output of mount(8))
2966+- /sys/module/aufs/*
2967+- /sys/fs/aufs/* (if you have them)
2968+- /debug/aufs/* (if you have them)
2969+- linux kernel version
2970+ if your kernel is not plain, for example modified by distributor,
2971+ the url where i can download its source is necessary too.
2972+- aufs version which was printed at loading the module or booting the
2973+ system, instead of the date you downloaded.
2974+- configuration (define/undefine CONFIG_AUFS_xxx)
2975+- kernel configuration or /proc/config.gz (if you have it)
2976+- behaviour which you think to be incorrect
2977+- actual operation, reproducible one is better
2978+- mailto: aufs-users at lists.sourceforge.net
2979+
2980+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2981+and Feature Requests) on SourceForge. Please join and write to
2982+aufs-users ML.
2983+
2984+
2985+6. Acknowledgements
2986+----------------------------------------
2987+Thanks to everyone who have tried and are using aufs, whoever
2988+have reported a bug or any feedback.
2989+
2990+Especially donators:
2991+Tomas Matejicek(slax.org) made a donation (much more than once).
2992+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2993+ scripts) is making "doubling" donations.
2994+ Unfortunately I cannot list all of the donators, but I really
b4510431 2995+ appreciate.
53392da6
AM
2996+ It ends Aug 2010, but the ordinary donation URL is still available.
2997+ <http://sourceforge.net/donate/index.php?group_id=167503>
2998+Dai Itasaka made a donation (2007/8).
2999+Chuck Smith made a donation (2008/4, 10 and 12).
3000+Henk Schoneveld made a donation (2008/9).
3001+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
3002+Francois Dupoux made a donation (2008/11).
3003+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
3004+ aufs2 GIT tree (2009/2).
3005+William Grant made a donation (2009/3).
3006+Patrick Lane made a donation (2009/4).
3007+The Mail Archive (mail-archive.com) made donations (2009/5).
3008+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
3009+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
3010+Pavel Pronskiy made a donation (2011/2).
3011+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
3012+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
3013+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
3014+11).
1e00d052 3015+Sam Liddicott made a donation (2011/9).
86dc4139
AM
3016+Era Scarecrow made a donation (2013/4).
3017+Bor Ratajc made a donation (2013/4).
3018+Alessandro Gorreta made a donation (2013/4).
3019+POIRETTE Marc made a donation (2013/4).
3020+Alessandro Gorreta made a donation (2013/4).
3021+lauri kasvandik made a donation (2013/5).
392086de 3022+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
3023+The Parted Magic Project made a donation (2013/9 and 11).
3024+Pavel Barta made a donation (2013/10).
38d290e6 3025+Nikolay Pertsev made a donation (2014/5).
c2c0f25c 3026+James B made a donation (2014/7 and 2015/7).
076b876e 3027+Stefano Di Biase made a donation (2014/8).
2000de60 3028+Daniel Epellei made a donation (2015/1).
c4adf169 3029+OmegaPhil made a donation (2016/1, 2018/4).
5afbbe0d 3030+Tomasz Szewczyk made a donation (2016/4).
f2c43d5f 3031+James Burry made a donation (2016/12).
acd2b654 3032+Carsten Rose made a donation (2018/9).
53392da6
AM
3033+
3034+Thank you very much.
3035+Donations are always, including future donations, very important and
3036+helpful for me to keep on developing aufs.
3037+
3038+
3039+7.
3040+----------------------------------------
3041+If you are an experienced user, no explanation is needed. Aufs is
3042+just a linux filesystem.
3043+
3044+
3045+Enjoy!
3046+
3047+# Local variables: ;
3048+# mode: text;
3049+# End: ;
7f207e10
AM
3050diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
3051--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
3052+++ linux/fs/aufs/aufs.h 2018-10-23 12:33:35.592708932 +0200
3053@@ -0,0 +1,62 @@
062440b3 3054+/* SPDX-License-Identifier: GPL-2.0 */
7f207e10 3055+/*
b00004a5 3056+ * Copyright (C) 2005-2018 Junjiro R. Okajima
7f207e10
AM
3057+ *
3058+ * This program, aufs is free software; you can redistribute it and/or modify
3059+ * it under the terms of the GNU General Public License as published by
3060+ * the Free Software Foundation; either version 2 of the License, or
3061+ * (at your option) any later version.
3062+ *
3063+ * This program is distributed in the hope that it will be useful,
3064+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3065+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3066+ * GNU General Public License for more details.
3067+ *
3068+ * You should have received a copy of the GNU General Public License
523b37e3 3069+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
3070+ */
3071+
3072+/*
3073+ * all header files
3074+ */
3075+
3076+#ifndef __AUFS_H__
3077+#define __AUFS_H__
3078+
3079+#ifdef __KERNEL__
3080+
3081+#define AuStub(type, name, body, ...) \
3082+ static inline type name(__VA_ARGS__) { body; }
3083+
3084+#define AuStubVoid(name, ...) \
3085+ AuStub(void, name, , __VA_ARGS__)
3086+#define AuStubInt0(name, ...) \
3087+ AuStub(int, name, return 0, __VA_ARGS__)
3088+
3089+#include "debug.h"
3090+
3091+#include "branch.h"
3092+#include "cpup.h"
3093+#include "dcsub.h"
3094+#include "dbgaufs.h"
3095+#include "dentry.h"
3096+#include "dir.h"
8b6a4947 3097+#include "dirren.h"
7f207e10
AM
3098+#include "dynop.h"
3099+#include "file.h"
3100+#include "fstype.h"
8b6a4947 3101+#include "hbl.h"
7f207e10 3102+#include "inode.h"
acd2b654 3103+#include "lcnt.h"
7f207e10
AM
3104+#include "loop.h"
3105+#include "module.h"
7f207e10
AM
3106+#include "opts.h"
3107+#include "rwsem.h"
7f207e10
AM
3108+#include "super.h"
3109+#include "sysaufs.h"
3110+#include "vfsub.h"
3111+#include "whout.h"
3112+#include "wkq.h"
3113+
3114+#endif /* __KERNEL__ */
3115+#endif /* __AUFS_H__ */
3116diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
3117--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 3118+++ linux/fs/aufs/branch.c 2018-10-23 12:33:35.592708932 +0200
062440b3 3119@@ -0,0 +1,1422 @@
cd7a4cd9 3120+// SPDX-License-Identifier: GPL-2.0
7f207e10 3121+/*
b00004a5 3122+ * Copyright (C) 2005-2018 Junjiro R. Okajima
7f207e10
AM
3123+ *
3124+ * This program, aufs is free software; you can redistribute it and/or modify
3125+ * it under the terms of the GNU General Public License as published by
3126+ * the Free Software Foundation; either version 2 of the License, or
3127+ * (at your option) any later version.
3128+ *
3129+ * This program is distributed in the hope that it will be useful,
3130+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3131+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3132+ * GNU General Public License for more details.
3133+ *
3134+ * You should have received a copy of the GNU General Public License
523b37e3 3135+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
3136+ */
3137+
3138+/*
3139+ * branch management
3140+ */
3141+
027c5e7a 3142+#include <linux/compat.h>
7f207e10
AM
3143+#include <linux/statfs.h>
3144+#include "aufs.h"
3145+
3146+/*
3147+ * free a single branch
1facf9fc 3148+ */
3149+static void au_br_do_free(struct au_branch *br)
3150+{
3151+ int i;
3152+ struct au_wbr *wbr;
4a4d8108 3153+ struct au_dykey **key;
1facf9fc 3154+
027c5e7a 3155+ au_hnotify_fin_br(br);
8b6a4947
AM
3156+ /* always, regardless the mount option */
3157+ au_dr_hino_free(&br->br_dirren);
062440b3 3158+ au_xino_put(br);
1facf9fc 3159+
acd2b654
AM
3160+ AuLCntZero(au_lcnt_read(&br->br_nfiles, /*do_rev*/0));
3161+ au_lcnt_fin(&br->br_nfiles, /*do_sync*/0);
3162+ AuLCntZero(au_lcnt_read(&br->br_count, /*do_rev*/0));
3163+ au_lcnt_fin(&br->br_count, /*do_sync*/0);
1facf9fc 3164+
3165+ wbr = br->br_wbr;
3166+ if (wbr) {
3167+ for (i = 0; i < AuBrWh_Last; i++)
3168+ dput(wbr->wbr_wh[i]);
3169+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 3170+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 3171+ }
3172+
076b876e
AM
3173+ if (br->br_fhsm) {
3174+ au_br_fhsm_fin(br->br_fhsm);
1c60b727 3175+ kfree(br->br_fhsm);
076b876e
AM
3176+ }
3177+
4a4d8108
AM
3178+ key = br->br_dykey;
3179+ for (i = 0; i < AuBrDynOp; i++, key++)
3180+ if (*key)
3181+ au_dy_put(*key);
3182+ else
3183+ break;
3184+
537831f9 3185+ /* recursive lock, s_umount of branch's */
acd2b654 3186+ /* synchronize_rcu(); */ /* why? */
537831f9 3187+ lockdep_off();
86dc4139 3188+ path_put(&br->br_path);
537831f9 3189+ lockdep_on();
1c60b727 3190+ kfree(wbr);
acd2b654
AM
3191+ au_lcnt_wait_for_fin(&br->br_nfiles);
3192+ au_lcnt_wait_for_fin(&br->br_count);
3193+ /* I don't know why, but percpu_refcount requires this */
3194+ /* synchronize_rcu(); */
1c60b727 3195+ kfree(br);
1facf9fc 3196+}
3197+
3198+/*
3199+ * frees all branches
3200+ */
3201+void au_br_free(struct au_sbinfo *sbinfo)
3202+{
3203+ aufs_bindex_t bmax;
3204+ struct au_branch **br;
3205+
dece6358
AM
3206+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3207+
5afbbe0d 3208+ bmax = sbinfo->si_bbot + 1;
1facf9fc 3209+ br = sbinfo->si_branch;
3210+ while (bmax--)
3211+ au_br_do_free(*br++);
3212+}
3213+
3214+/*
3215+ * find the index of a branch which is specified by @br_id.
3216+ */
3217+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
3218+{
5afbbe0d 3219+ aufs_bindex_t bindex, bbot;
1facf9fc 3220+
5afbbe0d
AM
3221+ bbot = au_sbbot(sb);
3222+ for (bindex = 0; bindex <= bbot; bindex++)
1facf9fc 3223+ if (au_sbr_id(sb, bindex) == br_id)
3224+ return bindex;
3225+ return -1;
3226+}
3227+
3228+/* ---------------------------------------------------------------------- */
3229+
3230+/*
3231+ * add a branch
3232+ */
3233+
b752ccd1
AM
3234+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
3235+ struct dentry *h_root)
1facf9fc 3236+{
b752ccd1
AM
3237+ if (unlikely(h_adding == h_root
3238+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 3239+ return 1;
b752ccd1
AM
3240+ if (h_adding->d_sb != h_root->d_sb)
3241+ return 0;
3242+ return au_test_subdir(h_adding, h_root)
3243+ || au_test_subdir(h_root, h_adding);
1facf9fc 3244+}
3245+
3246+/*
3247+ * returns a newly allocated branch. @new_nbranch is a number of branches
3248+ * after adding a branch.
3249+ */
3250+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
3251+ int perm)
3252+{
3253+ struct au_branch *add_branch;
3254+ struct dentry *root;
5527c038 3255+ struct inode *inode;
4a4d8108 3256+ int err;
1facf9fc 3257+
4a4d8108 3258+ err = -ENOMEM;
be52b249 3259+ add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS);
1facf9fc 3260+ if (unlikely(!add_branch))
3261+ goto out;
acd2b654 3262+ add_branch->br_xino = au_xino_alloc(/*nfile*/1);
062440b3 3263+ if (unlikely(!add_branch->br_xino))
521ced18 3264+ goto out_br;
027c5e7a
AM
3265+ err = au_hnotify_init_br(add_branch, perm);
3266+ if (unlikely(err))
062440b3 3267+ goto out_xino;
027c5e7a 3268+
1facf9fc 3269+ if (au_br_writable(perm)) {
3270+ /* may be freed separately at changing the branch permission */
be52b249 3271+ add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr),
1facf9fc 3272+ GFP_NOFS);
3273+ if (unlikely(!add_branch->br_wbr))
027c5e7a 3274+ goto out_hnotify;
1facf9fc 3275+ }
3276+
076b876e
AM
3277+ if (au_br_fhsm(perm)) {
3278+ err = au_fhsm_br_alloc(add_branch);
3279+ if (unlikely(err))
3280+ goto out_wbr;
3281+ }
3282+
521ced18 3283+ root = sb->s_root;
e2f27e51 3284+ err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0);
4a4d8108 3285+ if (!err)
e2f27e51 3286+ err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0);
5527c038
JR
3287+ if (!err) {
3288+ inode = d_inode(root);
1c60b727
AM
3289+ err = au_hinode_realloc(au_ii(inode), new_nbranch,
3290+ /*may_shrink*/0);
5527c038 3291+ }
4a4d8108
AM
3292+ if (!err)
3293+ return add_branch; /* success */
1facf9fc 3294+
076b876e 3295+out_wbr:
1c60b727 3296+ kfree(add_branch->br_wbr);
027c5e7a
AM
3297+out_hnotify:
3298+ au_hnotify_fin_br(add_branch);
062440b3
AM
3299+out_xino:
3300+ au_xino_put(add_branch);
4f0767ce 3301+out_br:
1c60b727 3302+ kfree(add_branch);
4f0767ce 3303+out:
4a4d8108 3304+ return ERR_PTR(err);
1facf9fc 3305+}
3306+
3307+/*
3308+ * test if the branch permission is legal or not.
3309+ */
3310+static int test_br(struct inode *inode, int brperm, char *path)
3311+{
3312+ int err;
3313+
4a4d8108
AM
3314+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
3315+ if (!err)
3316+ goto out;
1facf9fc 3317+
4a4d8108
AM
3318+ err = -EINVAL;
3319+ pr_err("write permission for readonly mount or inode, %s\n", path);
3320+
4f0767ce 3321+out:
1facf9fc 3322+ return err;
3323+}
3324+
3325+/*
3326+ * returns:
3327+ * 0: success, the caller will add it
3328+ * plus: success, it is already unified, the caller should ignore it
3329+ * minus: error
3330+ */
3331+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
3332+{
3333+ int err;
5afbbe0d 3334+ aufs_bindex_t bbot, bindex;
5527c038 3335+ struct dentry *root, *h_dentry;
1facf9fc 3336+ struct inode *inode, *h_inode;
3337+
3338+ root = sb->s_root;
5afbbe0d
AM
3339+ bbot = au_sbbot(sb);
3340+ if (unlikely(bbot >= 0
1facf9fc 3341+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
3342+ err = 1;
3343+ if (!remount) {
3344+ err = -EINVAL;
4a4d8108 3345+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 3346+ }
3347+ goto out;
3348+ }
3349+
3350+ err = -ENOSPC; /* -E2BIG; */
3351+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
5afbbe0d 3352+ || AUFS_BRANCH_MAX - 1 <= bbot)) {
4a4d8108 3353+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 3354+ goto out;
3355+ }
3356+
3357+ err = -EDOM;
5afbbe0d 3358+ if (unlikely(add->bindex < 0 || bbot + 1 < add->bindex)) {
4a4d8108 3359+ pr_err("bad index %d\n", add->bindex);
1facf9fc 3360+ goto out;
3361+ }
3362+
5527c038 3363+ inode = d_inode(add->path.dentry);
1facf9fc 3364+ err = -ENOENT;
3365+ if (unlikely(!inode->i_nlink)) {
4a4d8108 3366+ pr_err("no existence %s\n", add->pathname);
1facf9fc 3367+ goto out;
3368+ }
3369+
3370+ err = -EINVAL;
3371+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 3372+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 3373+ goto out;
3374+ }
3375+
3376+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
3377+ pr_err("unsupported filesystem, %s (%s)\n",
3378+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 3379+ goto out;
3380+ }
3381+
c1595e42
JR
3382+ if (unlikely(inode->i_sb->s_stack_depth)) {
3383+ pr_err("already stacked, %s (%s)\n",
3384+ add->pathname, au_sbtype(inode->i_sb));
3385+ goto out;
3386+ }
3387+
5527c038 3388+ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname);
1facf9fc 3389+ if (unlikely(err))
3390+ goto out;
3391+
5afbbe0d 3392+ if (bbot < 0)
1facf9fc 3393+ return 0; /* success */
3394+
3395+ err = -EINVAL;
5afbbe0d 3396+ for (bindex = 0; bindex <= bbot; bindex++)
1facf9fc 3397+ if (unlikely(test_overlap(sb, add->path.dentry,
3398+ au_h_dptr(root, bindex)))) {
4a4d8108 3399+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 3400+ goto out;
3401+ }
3402+
3403+ err = 0;
3404+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
5527c038
JR
3405+ h_dentry = au_h_dptr(root, 0);
3406+ h_inode = d_inode(h_dentry);
1facf9fc 3407+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
3408+ || !uid_eq(h_inode->i_uid, inode->i_uid)
3409+ || !gid_eq(h_inode->i_gid, inode->i_gid))
3410+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
3411+ add->pathname,
3412+ i_uid_read(inode), i_gid_read(inode),
3413+ (inode->i_mode & S_IALLUGO),
3414+ i_uid_read(h_inode), i_gid_read(h_inode),
3415+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 3416+ }
3417+
4f0767ce 3418+out:
1facf9fc 3419+ return err;
3420+}
3421+
3422+/*
3423+ * initialize or clean the whiteouts for an adding branch
3424+ */
3425+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 3426+ int new_perm)
1facf9fc 3427+{
3428+ int err, old_perm;
3429+ aufs_bindex_t bindex;
febd17d6 3430+ struct inode *h_inode;
1facf9fc 3431+ struct au_wbr *wbr;
3432+ struct au_hinode *hdir;
5527c038 3433+ struct dentry *h_dentry;
1facf9fc 3434+
86dc4139
AM
3435+ err = vfsub_mnt_want_write(au_br_mnt(br));
3436+ if (unlikely(err))
3437+ goto out;
3438+
1facf9fc 3439+ wbr = br->br_wbr;
3440+ old_perm = br->br_perm;
3441+ br->br_perm = new_perm;
3442+ hdir = NULL;
febd17d6 3443+ h_inode = NULL;
1facf9fc 3444+ bindex = au_br_index(sb, br->br_id);
3445+ if (0 <= bindex) {
5527c038 3446+ hdir = au_hi(d_inode(sb->s_root), bindex);
5afbbe0d 3447+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 3448+ } else {
5527c038 3449+ h_dentry = au_br_dentry(br);
febd17d6
JR
3450+ h_inode = d_inode(h_dentry);
3451+ inode_lock_nested(h_inode, AuLsc_I_PARENT);
1facf9fc 3452+ }
3453+ if (!wbr)
86dc4139 3454+ err = au_wh_init(br, sb);
1facf9fc 3455+ else {
3456+ wbr_wh_write_lock(wbr);
86dc4139 3457+ err = au_wh_init(br, sb);
1facf9fc 3458+ wbr_wh_write_unlock(wbr);
3459+ }
3460+ if (hdir)
5afbbe0d 3461+ au_hn_inode_unlock(hdir);
1facf9fc 3462+ else
febd17d6 3463+ inode_unlock(h_inode);
86dc4139 3464+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 3465+ br->br_perm = old_perm;
3466+
3467+ if (!err && wbr && !au_br_writable(new_perm)) {
1c60b727 3468+ kfree(wbr);
1facf9fc 3469+ br->br_wbr = NULL;
3470+ }
3471+
86dc4139 3472+out:
1facf9fc 3473+ return err;
3474+}
3475+
3476+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 3477+ int perm)
1facf9fc 3478+{
3479+ int err;
4a4d8108 3480+ struct kstatfs kst;
1facf9fc 3481+ struct au_wbr *wbr;
3482+
3483+ wbr = br->br_wbr;
dece6358 3484+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 3485+ atomic_set(&wbr->wbr_wh_running, 0);
1facf9fc 3486+
4a4d8108
AM
3487+ /*
3488+ * a limit for rmdir/rename a dir
523b37e3 3489+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 3490+ */
86dc4139 3491+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
3492+ if (unlikely(err))
3493+ goto out;
3494+ err = -EINVAL;
3495+ if (kst.f_namelen >= NAME_MAX)
86dc4139 3496+ err = au_br_init_wh(sb, br, perm);
4a4d8108 3497+ else
523b37e3
AM
3498+ pr_err("%pd(%s), unsupported namelen %ld\n",
3499+ au_br_dentry(br),
86dc4139 3500+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 3501+
4f0767ce 3502+out:
1facf9fc 3503+ return err;
3504+}
3505+
c1595e42 3506+/* initialize a new branch */
1facf9fc 3507+static int au_br_init(struct au_branch *br, struct super_block *sb,
3508+ struct au_opt_add *add)
3509+{
3510+ int err;
062440b3
AM
3511+ struct au_branch *brbase;
3512+ struct file *xf;
5527c038 3513+ struct inode *h_inode;
1facf9fc 3514+
3515+ err = 0;
1facf9fc 3516+ br->br_perm = add->perm;
86dc4139 3517+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108 3518+ spin_lock_init(&br->br_dykey_lock);
acd2b654
AM
3519+ au_lcnt_init(&br->br_nfiles, /*release*/NULL);
3520+ au_lcnt_init(&br->br_count, /*release*/NULL);
1facf9fc 3521+ br->br_id = au_new_br_id(sb);
7f207e10 3522+ AuDebugOn(br->br_id < 0);
1facf9fc 3523+
8b6a4947
AM
3524+ /* always, regardless the given option */
3525+ err = au_dr_br_init(sb, br, &add->path);
3526+ if (unlikely(err))
3527+ goto out_err;
3528+
1facf9fc 3529+ if (au_br_writable(add->perm)) {
86dc4139 3530+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 3531+ if (unlikely(err))
b752ccd1 3532+ goto out_err;
1facf9fc 3533+ }
3534+
3535+ if (au_opt_test(au_mntflags(sb), XINO)) {
062440b3 3536+ brbase = au_sbr(sb, 0);
acd2b654 3537+ xf = au_xino_file(brbase->br_xino, /*idx*/-1);
062440b3 3538+ AuDebugOn(!xf);
5527c038 3539+ h_inode = d_inode(add->path.dentry);
062440b3 3540+ err = au_xino_init_br(sb, br, h_inode->i_ino, &xf->f_path);
1facf9fc 3541+ if (unlikely(err)) {
acd2b654 3542+ AuDebugOn(au_xino_file(br->br_xino, /*idx*/-1));
b752ccd1 3543+ goto out_err;
1facf9fc 3544+ }
3545+ }
3546+
3547+ sysaufs_br_init(br);
86dc4139 3548+ path_get(&br->br_path);
b752ccd1 3549+ goto out; /* success */
1facf9fc 3550+
4f0767ce 3551+out_err:
86dc4139 3552+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 3553+out:
1facf9fc 3554+ return err;
3555+}
3556+
3557+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
5afbbe0d 3558+ struct au_branch *br, aufs_bindex_t bbot,
1facf9fc 3559+ aufs_bindex_t amount)
3560+{
3561+ struct au_branch **brp;
3562+
dece6358
AM
3563+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3564+
1facf9fc 3565+ brp = sbinfo->si_branch + bindex;
3566+ memmove(brp + 1, brp, sizeof(*brp) * amount);
3567+ *brp = br;
5afbbe0d
AM
3568+ sbinfo->si_bbot++;
3569+ if (unlikely(bbot < 0))
3570+ sbinfo->si_bbot = 0;
1facf9fc 3571+}
3572+
3573+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
5afbbe0d 3574+ aufs_bindex_t bbot, aufs_bindex_t amount)
1facf9fc 3575+{
3576+ struct au_hdentry *hdp;
3577+
1308ab2a 3578+ AuRwMustWriteLock(&dinfo->di_rwsem);
3579+
5afbbe0d 3580+ hdp = au_hdentry(dinfo, bindex);
1facf9fc 3581+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
3582+ au_h_dentry_init(hdp);
5afbbe0d
AM
3583+ dinfo->di_bbot++;
3584+ if (unlikely(bbot < 0))
3585+ dinfo->di_btop = 0;
1facf9fc 3586+}
3587+
3588+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
5afbbe0d 3589+ aufs_bindex_t bbot, aufs_bindex_t amount)
1facf9fc 3590+{
3591+ struct au_hinode *hip;
3592+
1308ab2a 3593+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3594+
5afbbe0d 3595+ hip = au_hinode(iinfo, bindex);
1facf9fc 3596+ memmove(hip + 1, hip, sizeof(*hip) * amount);
5afbbe0d
AM
3597+ au_hinode_init(hip);
3598+ iinfo->ii_bbot++;
3599+ if (unlikely(bbot < 0))
3600+ iinfo->ii_btop = 0;
1facf9fc 3601+}
3602+
86dc4139
AM
3603+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
3604+ aufs_bindex_t bindex)
1facf9fc 3605+{
86dc4139 3606+ struct dentry *root, *h_dentry;
5527c038 3607+ struct inode *root_inode, *h_inode;
5afbbe0d 3608+ aufs_bindex_t bbot, amount;
1facf9fc 3609+
3610+ root = sb->s_root;
5527c038 3611+ root_inode = d_inode(root);
5afbbe0d
AM
3612+ bbot = au_sbbot(sb);
3613+ amount = bbot + 1 - bindex;
86dc4139 3614+ h_dentry = au_br_dentry(br);
53392da6 3615+ au_sbilist_lock();
5afbbe0d
AM
3616+ au_br_do_add_brp(au_sbi(sb), bindex, br, bbot, amount);
3617+ au_br_do_add_hdp(au_di(root), bindex, bbot, amount);
3618+ au_br_do_add_hip(au_ii(root_inode), bindex, bbot, amount);
1facf9fc 3619+ au_set_h_dptr(root, bindex, dget(h_dentry));
5527c038
JR
3620+ h_inode = d_inode(h_dentry);
3621+ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
53392da6 3622+ au_sbilist_unlock();
1facf9fc 3623+}
3624+
3625+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
3626+{
3627+ int err;
5afbbe0d 3628+ aufs_bindex_t bbot, add_bindex;
1facf9fc 3629+ struct dentry *root, *h_dentry;
3630+ struct inode *root_inode;
3631+ struct au_branch *add_branch;
3632+
3633+ root = sb->s_root;
5527c038 3634+ root_inode = d_inode(root);
1facf9fc 3635+ IMustLock(root_inode);
5afbbe0d 3636+ IiMustWriteLock(root_inode);
1facf9fc 3637+ err = test_add(sb, add, remount);
3638+ if (unlikely(err < 0))
3639+ goto out;
3640+ if (err) {
3641+ err = 0;
3642+ goto out; /* success */
3643+ }
3644+
5afbbe0d
AM
3645+ bbot = au_sbbot(sb);
3646+ add_branch = au_br_alloc(sb, bbot + 2, add->perm);
1facf9fc 3647+ err = PTR_ERR(add_branch);
3648+ if (IS_ERR(add_branch))
3649+ goto out;
3650+
3651+ err = au_br_init(add_branch, sb, add);
3652+ if (unlikely(err)) {
3653+ au_br_do_free(add_branch);
3654+ goto out;
3655+ }
3656+
3657+ add_bindex = add->bindex;
062440b3
AM
3658+ sysaufs_brs_del(sb, add_bindex); /* remove successors */
3659+ au_br_do_add(sb, add_branch, add_bindex);
3660+ sysaufs_brs_add(sb, add_bindex); /* append successors */
3661+ dbgaufs_brs_add(sb, add_bindex, /*topdown*/0); /* rename successors */
1facf9fc 3662+
86dc4139 3663+ h_dentry = add->path.dentry;
1308ab2a 3664+ if (!add_bindex) {
1facf9fc 3665+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 3666+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
3667+ } else
5527c038 3668+ au_add_nlink(root_inode, d_inode(h_dentry));
1facf9fc 3669+
4f0767ce 3670+out:
1facf9fc 3671+ return err;
3672+}
3673+
3674+/* ---------------------------------------------------------------------- */
3675+
79b8bda9 3676+static unsigned long long au_farray_cb(struct super_block *sb, void *a,
076b876e
AM
3677+ unsigned long long max __maybe_unused,
3678+ void *arg)
3679+{
3680+ unsigned long long n;
3681+ struct file **p, *f;
8b6a4947
AM
3682+ struct hlist_bl_head *files;
3683+ struct hlist_bl_node *pos;
076b876e 3684+ struct au_finfo *finfo;
076b876e
AM
3685+
3686+ n = 0;
3687+ p = a;
3688+ files = &au_sbi(sb)->si_files;
8b6a4947
AM
3689+ hlist_bl_lock(files);
3690+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) {
076b876e
AM
3691+ f = finfo->fi_file;
3692+ if (file_count(f)
3693+ && !special_file(file_inode(f)->i_mode)) {
3694+ get_file(f);
3695+ *p++ = f;
3696+ n++;
3697+ AuDebugOn(n > max);
3698+ }
3699+ }
8b6a4947 3700+ hlist_bl_unlock(files);
076b876e
AM
3701+
3702+ return n;
3703+}
3704+
3705+static struct file **au_farray_alloc(struct super_block *sb,
3706+ unsigned long long *max)
3707+{
acd2b654
AM
3708+ struct au_sbinfo *sbi;
3709+
3710+ sbi = au_sbi(sb);
3711+ *max = au_lcnt_read(&sbi->si_nfiles, /*do_rev*/1);
79b8bda9 3712+ return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL);
076b876e
AM
3713+}
3714+
3715+static void au_farray_free(struct file **a, unsigned long long max)
3716+{
3717+ unsigned long long ull;
3718+
3719+ for (ull = 0; ull < max; ull++)
3720+ if (a[ull])
3721+ fput(a[ull]);
be52b249 3722+ kvfree(a);
076b876e
AM
3723+}
3724+
3725+/* ---------------------------------------------------------------------- */
3726+
1facf9fc 3727+/*
3728+ * delete a branch
3729+ */
3730+
3731+/* to show the line number, do not make it inlined function */
4a4d8108 3732+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 3733+ if (do_info) \
4a4d8108 3734+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 3735+} while (0)
3736+
5afbbe0d
AM
3737+static int au_test_ibusy(struct inode *inode, aufs_bindex_t btop,
3738+ aufs_bindex_t bbot)
027c5e7a 3739+{
5afbbe0d 3740+ return (inode && !S_ISDIR(inode->i_mode)) || btop == bbot;
027c5e7a
AM
3741+}
3742+
5afbbe0d
AM
3743+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t btop,
3744+ aufs_bindex_t bbot)
027c5e7a 3745+{
5afbbe0d 3746+ return au_test_ibusy(d_inode(dentry), btop, bbot);
027c5e7a
AM
3747+}
3748+
1facf9fc 3749+/*
3750+ * test if the branch is deletable or not.
3751+ */
3752+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 3753+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3754+{
3755+ int err, i, j, ndentry;
5afbbe0d 3756+ aufs_bindex_t btop, bbot;
1facf9fc 3757+ struct au_dcsub_pages dpages;
3758+ struct au_dpage *dpage;
3759+ struct dentry *d;
1facf9fc 3760+
3761+ err = au_dpages_init(&dpages, GFP_NOFS);
3762+ if (unlikely(err))
3763+ goto out;
3764+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
3765+ if (unlikely(err))
3766+ goto out_dpages;
3767+
1facf9fc 3768+ for (i = 0; !err && i < dpages.ndpage; i++) {
3769+ dpage = dpages.dpages + i;
3770+ ndentry = dpage->ndentry;
3771+ for (j = 0; !err && j < ndentry; j++) {
3772+ d = dpage->dentries[j];
c1595e42 3773+ AuDebugOn(au_dcount(d) <= 0);
027c5e7a 3774+ if (!au_digen_test(d, sigen)) {
1facf9fc 3775+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
3776+ if (unlikely(au_dbrange_test(d))) {
3777+ di_read_unlock(d, AuLock_IR);
3778+ continue;
3779+ }
3780+ } else {
1facf9fc 3781+ di_write_lock_child(d);
027c5e7a
AM
3782+ if (unlikely(au_dbrange_test(d))) {
3783+ di_write_unlock(d);
3784+ continue;
3785+ }
1facf9fc 3786+ err = au_reval_dpath(d, sigen);
3787+ if (!err)
3788+ di_downgrade_lock(d, AuLock_IR);
3789+ else {
3790+ di_write_unlock(d);
3791+ break;
3792+ }
3793+ }
3794+
027c5e7a 3795+ /* AuDbgDentry(d); */
5afbbe0d
AM
3796+ btop = au_dbtop(d);
3797+ bbot = au_dbbot(d);
3798+ if (btop <= bindex
3799+ && bindex <= bbot
1facf9fc 3800+ && au_h_dptr(d, bindex)
5afbbe0d 3801+ && au_test_dbusy(d, btop, bbot)) {
1facf9fc 3802+ err = -EBUSY;
523b37e3 3803+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 3804+ AuDbgDentry(d);
1facf9fc 3805+ }
3806+ di_read_unlock(d, AuLock_IR);
3807+ }
3808+ }
3809+
4f0767ce 3810+out_dpages:
1facf9fc 3811+ au_dpages_free(&dpages);
4f0767ce 3812+out:
1facf9fc 3813+ return err;
3814+}
3815+
3816+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 3817+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3818+{
3819+ int err;
7f207e10
AM
3820+ unsigned long long max, ull;
3821+ struct inode *i, **array;
5afbbe0d 3822+ aufs_bindex_t btop, bbot;
1facf9fc 3823+
7f207e10
AM
3824+ array = au_iarray_alloc(sb, &max);
3825+ err = PTR_ERR(array);
3826+ if (IS_ERR(array))
3827+ goto out;
3828+
1facf9fc 3829+ err = 0;
7f207e10
AM
3830+ AuDbg("b%d\n", bindex);
3831+ for (ull = 0; !err && ull < max; ull++) {
3832+ i = array[ull];
076b876e
AM
3833+ if (unlikely(!i))
3834+ break;
7f207e10 3835+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 3836+ continue;
3837+
7f207e10 3838+ /* AuDbgInode(i); */
537831f9 3839+ if (au_iigen(i, NULL) == sigen)
1facf9fc 3840+ ii_read_lock_child(i);
3841+ else {
3842+ ii_write_lock_child(i);
027c5e7a
AM
3843+ err = au_refresh_hinode_self(i);
3844+ au_iigen_dec(i);
1facf9fc 3845+ if (!err)
3846+ ii_downgrade_lock(i);
3847+ else {
3848+ ii_write_unlock(i);
3849+ break;
3850+ }
3851+ }
3852+
5afbbe0d
AM
3853+ btop = au_ibtop(i);
3854+ bbot = au_ibbot(i);
3855+ if (btop <= bindex
3856+ && bindex <= bbot
1facf9fc 3857+ && au_h_iptr(i, bindex)
5afbbe0d 3858+ && au_test_ibusy(i, btop, bbot)) {
1facf9fc 3859+ err = -EBUSY;
3860+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 3861+ AuDbgInode(i);
1facf9fc 3862+ }
3863+ ii_read_unlock(i);
3864+ }
7f207e10 3865+ au_iarray_free(array, max);
1facf9fc 3866+
7f207e10 3867+out:
1facf9fc 3868+ return err;
3869+}
3870+
b752ccd1
AM
3871+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
3872+ const unsigned int verbose)
1facf9fc 3873+{
3874+ int err;
3875+ unsigned int sigen;
3876+
3877+ sigen = au_sigen(root->d_sb);
3878+ DiMustNoWaiters(root);
5527c038 3879+ IiMustNoWaiters(d_inode(root));
1facf9fc 3880+ di_write_unlock(root);
b752ccd1 3881+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 3882+ if (!err)
b752ccd1 3883+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 3884+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3885+
3886+ return err;
3887+}
3888+
076b876e
AM
3889+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
3890+ struct file **to_free, int *idx)
3891+{
3892+ int err;
c1595e42 3893+ unsigned char matched, root;
5afbbe0d 3894+ aufs_bindex_t bindex, bbot;
076b876e
AM
3895+ struct au_fidir *fidir;
3896+ struct au_hfile *hfile;
3897+
3898+ err = 0;
2000de60 3899+ root = IS_ROOT(file->f_path.dentry);
c1595e42
JR
3900+ if (root) {
3901+ get_file(file);
3902+ to_free[*idx] = file;
3903+ (*idx)++;
3904+ goto out;
3905+ }
3906+
076b876e 3907+ matched = 0;
076b876e
AM
3908+ fidir = au_fi(file)->fi_hdir;
3909+ AuDebugOn(!fidir);
5afbbe0d
AM
3910+ bbot = au_fbbot_dir(file);
3911+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) {
076b876e
AM
3912+ hfile = fidir->fd_hfile + bindex;
3913+ if (!hfile->hf_file)
3914+ continue;
3915+
c1595e42 3916+ if (hfile->hf_br->br_id == br_id) {
076b876e 3917+ matched = 1;
076b876e 3918+ break;
c1595e42 3919+ }
076b876e 3920+ }
c1595e42 3921+ if (matched)
076b876e
AM
3922+ err = -EBUSY;
3923+
3924+out:
3925+ return err;
3926+}
3927+
3928+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
3929+ struct file **to_free, int opened)
3930+{
3931+ int err, idx;
3932+ unsigned long long ull, max;
5afbbe0d 3933+ aufs_bindex_t btop;
076b876e 3934+ struct file *file, **array;
076b876e
AM
3935+ struct dentry *root;
3936+ struct au_hfile *hfile;
3937+
3938+ array = au_farray_alloc(sb, &max);
3939+ err = PTR_ERR(array);
3940+ if (IS_ERR(array))
3941+ goto out;
3942+
3943+ err = 0;
3944+ idx = 0;
3945+ root = sb->s_root;
3946+ di_write_unlock(root);
3947+ for (ull = 0; ull < max; ull++) {
3948+ file = array[ull];
3949+ if (unlikely(!file))
3950+ break;
3951+
3952+ /* AuDbg("%pD\n", file); */
3953+ fi_read_lock(file);
5afbbe0d 3954+ btop = au_fbtop(file);
2000de60 3955+ if (!d_is_dir(file->f_path.dentry)) {
076b876e
AM
3956+ hfile = &au_fi(file)->fi_htop;
3957+ if (hfile->hf_br->br_id == br_id)
3958+ err = -EBUSY;
3959+ } else
3960+ err = test_dir_busy(file, br_id, to_free, &idx);
3961+ fi_read_unlock(file);
3962+ if (unlikely(err))
3963+ break;
3964+ }
3965+ di_write_lock_child(root);
3966+ au_farray_free(array, max);
3967+ AuDebugOn(idx > opened);
3968+
3969+out:
3970+ return err;
3971+}
3972+
3973+static void br_del_file(struct file **to_free, unsigned long long opened,
062440b3 3974+ aufs_bindex_t br_id)
076b876e
AM
3975+{
3976+ unsigned long long ull;
5afbbe0d 3977+ aufs_bindex_t bindex, btop, bbot, bfound;
076b876e
AM
3978+ struct file *file;
3979+ struct au_fidir *fidir;
3980+ struct au_hfile *hfile;
3981+
3982+ for (ull = 0; ull < opened; ull++) {
3983+ file = to_free[ull];
3984+ if (unlikely(!file))
3985+ break;
3986+
3987+ /* AuDbg("%pD\n", file); */
2000de60 3988+ AuDebugOn(!d_is_dir(file->f_path.dentry));
076b876e
AM
3989+ bfound = -1;
3990+ fidir = au_fi(file)->fi_hdir;
3991+ AuDebugOn(!fidir);
3992+ fi_write_lock(file);
5afbbe0d
AM
3993+ btop = au_fbtop(file);
3994+ bbot = au_fbbot_dir(file);
3995+ for (bindex = btop; bindex <= bbot; bindex++) {
076b876e
AM
3996+ hfile = fidir->fd_hfile + bindex;
3997+ if (!hfile->hf_file)
3998+ continue;
3999+
4000+ if (hfile->hf_br->br_id == br_id) {
4001+ bfound = bindex;
4002+ break;
4003+ }
4004+ }
4005+ AuDebugOn(bfound < 0);
4006+ au_set_h_fptr(file, bfound, NULL);
5afbbe0d
AM
4007+ if (bfound == btop) {
4008+ for (btop++; btop <= bbot; btop++)
4009+ if (au_hf_dir(file, btop)) {
4010+ au_set_fbtop(file, btop);
076b876e
AM
4011+ break;
4012+ }
4013+ }
4014+ fi_write_unlock(file);
4015+ }
4016+}
4017+
1facf9fc 4018+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
4019+ const aufs_bindex_t bindex,
5afbbe0d 4020+ const aufs_bindex_t bbot)
1facf9fc 4021+{
4022+ struct au_branch **brp, **p;
4023+
dece6358
AM
4024+ AuRwMustWriteLock(&sbinfo->si_rwsem);
4025+
1facf9fc 4026+ brp = sbinfo->si_branch + bindex;
5afbbe0d
AM
4027+ if (bindex < bbot)
4028+ memmove(brp, brp + 1, sizeof(*brp) * (bbot - bindex));
4029+ sbinfo->si_branch[0 + bbot] = NULL;
4030+ sbinfo->si_bbot--;
1facf9fc 4031+
e2f27e51
AM
4032+ p = au_krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST,
4033+ /*may_shrink*/1);
1facf9fc 4034+ if (p)
4035+ sbinfo->si_branch = p;
4a4d8108 4036+ /* harmless error */
1facf9fc 4037+}
4038+
4039+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
5afbbe0d 4040+ const aufs_bindex_t bbot)
1facf9fc 4041+{
4042+ struct au_hdentry *hdp, *p;
4043+
1308ab2a 4044+ AuRwMustWriteLock(&dinfo->di_rwsem);
4045+
5afbbe0d
AM
4046+ hdp = au_hdentry(dinfo, bindex);
4047+ if (bindex < bbot)
4048+ memmove(hdp, hdp + 1, sizeof(*hdp) * (bbot - bindex));
4049+ /* au_h_dentry_init(au_hdentry(dinfo, bbot); */
4050+ dinfo->di_bbot--;
1facf9fc 4051+
e2f27e51
AM
4052+ p = au_krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST,
4053+ /*may_shrink*/1);
1facf9fc 4054+ if (p)
4055+ dinfo->di_hdentry = p;
4a4d8108 4056+ /* harmless error */
1facf9fc 4057+}
4058+
4059+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
5afbbe0d 4060+ const aufs_bindex_t bbot)
1facf9fc 4061+{
4062+ struct au_hinode *hip, *p;
4063+
1308ab2a 4064+ AuRwMustWriteLock(&iinfo->ii_rwsem);
4065+
5afbbe0d
AM
4066+ hip = au_hinode(iinfo, bindex);
4067+ if (bindex < bbot)
4068+ memmove(hip, hip + 1, sizeof(*hip) * (bbot - bindex));
4069+ /* au_hinode_init(au_hinode(iinfo, bbot)); */
4070+ iinfo->ii_bbot--;
1facf9fc 4071+
e2f27e51
AM
4072+ p = au_krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST,
4073+ /*may_shrink*/1);
1facf9fc 4074+ if (p)
4075+ iinfo->ii_hinode = p;
4a4d8108 4076+ /* harmless error */
1facf9fc 4077+}
4078+
4079+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
4080+ struct au_branch *br)
4081+{
5afbbe0d 4082+ aufs_bindex_t bbot;
1facf9fc 4083+ struct au_sbinfo *sbinfo;
53392da6
AM
4084+ struct dentry *root, *h_root;
4085+ struct inode *inode, *h_inode;
4086+ struct au_hinode *hinode;
1facf9fc 4087+
dece6358
AM
4088+ SiMustWriteLock(sb);
4089+
1facf9fc 4090+ root = sb->s_root;
5527c038 4091+ inode = d_inode(root);
1facf9fc 4092+ sbinfo = au_sbi(sb);
5afbbe0d 4093+ bbot = sbinfo->si_bbot;
1facf9fc 4094+
53392da6
AM
4095+ h_root = au_h_dptr(root, bindex);
4096+ hinode = au_hi(inode, bindex);
4097+ h_inode = au_igrab(hinode->hi_inode);
4098+ au_hiput(hinode);
1facf9fc 4099+
53392da6 4100+ au_sbilist_lock();
5afbbe0d
AM
4101+ au_br_do_del_brp(sbinfo, bindex, bbot);
4102+ au_br_do_del_hdp(au_di(root), bindex, bbot);
4103+ au_br_do_del_hip(au_ii(inode), bindex, bbot);
53392da6
AM
4104+ au_sbilist_unlock();
4105+
8b6a4947
AM
4106+ /* ignore an error */
4107+ au_dr_br_fin(sb, br); /* always, regardless the mount option */
4108+
53392da6
AM
4109+ dput(h_root);
4110+ iput(h_inode);
4111+ au_br_do_free(br);
1facf9fc 4112+}
4113+
79b8bda9
AM
4114+static unsigned long long empty_cb(struct super_block *sb, void *array,
4115+ unsigned long long max, void *arg)
076b876e
AM
4116+{
4117+ return max;
4118+}
4119+
1facf9fc 4120+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
4121+{
4122+ int err, rerr, i;
076b876e 4123+ unsigned long long opened;
1facf9fc 4124+ unsigned int mnt_flags;
5afbbe0d 4125+ aufs_bindex_t bindex, bbot, br_id;
1facf9fc 4126+ unsigned char do_wh, verbose;
4127+ struct au_branch *br;
4128+ struct au_wbr *wbr;
076b876e
AM
4129+ struct dentry *root;
4130+ struct file **to_free;
1facf9fc 4131+
4132+ err = 0;
076b876e
AM
4133+ opened = 0;
4134+ to_free = NULL;
4135+ root = sb->s_root;
4136+ bindex = au_find_dbindex(root, del->h_path.dentry);
1facf9fc 4137+ if (bindex < 0) {
4138+ if (remount)
4139+ goto out; /* success */
4140+ err = -ENOENT;
4a4d8108 4141+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 4142+ goto out;
4143+ }
4144+ AuDbg("bindex b%d\n", bindex);
4145+
4146+ err = -EBUSY;
4147+ mnt_flags = au_mntflags(sb);
4148+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
5afbbe0d
AM
4149+ bbot = au_sbbot(sb);
4150+ if (unlikely(!bbot)) {
1facf9fc 4151+ AuVerbose(verbose, "no more branches left\n");
4152+ goto out;
4153+ }
acd2b654 4154+
1facf9fc 4155+ br = au_sbr(sb, bindex);
86dc4139 4156+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
acd2b654
AM
4157+ if (unlikely(au_lcnt_read(&br->br_count, /*do_rev*/1))) {
4158+ AuVerbose(verbose, "br %pd2 is busy now\n", del->h_path.dentry);
4159+ goto out;
4160+ }
076b876e
AM
4161+
4162+ br_id = br->br_id;
acd2b654 4163+ opened = au_lcnt_read(&br->br_nfiles, /*do_rev*/1);
076b876e 4164+ if (unlikely(opened)) {
79b8bda9 4165+ to_free = au_array_alloc(&opened, empty_cb, sb, NULL);
076b876e
AM
4166+ err = PTR_ERR(to_free);
4167+ if (IS_ERR(to_free))
4168+ goto out;
4169+
4170+ err = test_file_busy(sb, br_id, to_free, opened);
4171+ if (unlikely(err)) {
4172+ AuVerbose(verbose, "%llu file(s) opened\n", opened);
4173+ goto out;
4174+ }
1facf9fc 4175+ }
4176+
4177+ wbr = br->br_wbr;
4178+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
4179+ if (do_wh) {
1308ab2a 4180+ /* instead of WbrWhMustWriteLock(wbr) */
4181+ SiMustWriteLock(sb);
1facf9fc 4182+ for (i = 0; i < AuBrWh_Last; i++) {
4183+ dput(wbr->wbr_wh[i]);
4184+ wbr->wbr_wh[i] = NULL;
4185+ }
4186+ }
4187+
076b876e 4188+ err = test_children_busy(root, bindex, verbose);
1facf9fc 4189+ if (unlikely(err)) {
4190+ if (do_wh)
4191+ goto out_wh;
4192+ goto out;
4193+ }
4194+
4195+ err = 0;
076b876e
AM
4196+ if (to_free) {
4197+ /*
4198+ * now we confirmed the branch is deletable.
4199+ * let's free the remaining opened dirs on the branch.
4200+ */
4201+ di_write_unlock(root);
4202+ br_del_file(to_free, opened, br_id);
4203+ di_write_lock_child(root);
4204+ }
4205+
062440b3
AM
4206+ sysaufs_brs_del(sb, bindex); /* remove successors */
4207+ dbgaufs_xino_del(br); /* remove one */
4208+ au_br_do_del(sb, bindex, br);
4209+ sysaufs_brs_add(sb, bindex); /* append successors */
4210+ dbgaufs_brs_add(sb, bindex, /*topdown*/1); /* rename successors */
1facf9fc 4211+
1308ab2a 4212+ if (!bindex) {
5527c038 4213+ au_cpup_attr_all(d_inode(root), /*force*/1);
1308ab2a 4214+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
4215+ } else
5527c038 4216+ au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry));
1facf9fc 4217+ if (au_opt_test(mnt_flags, PLINK))
4218+ au_plink_half_refresh(sb, br_id);
4219+
1facf9fc 4220+ goto out; /* success */
4221+
4f0767ce 4222+out_wh:
1facf9fc 4223+ /* revert */
86dc4139 4224+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 4225+ if (rerr)
0c3ec466
AM
4226+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
4227+ del->pathname, rerr);
4f0767ce 4228+out:
076b876e
AM
4229+ if (to_free)
4230+ au_farray_free(to_free, opened);
1facf9fc 4231+ return err;
4232+}
4233+
4234+/* ---------------------------------------------------------------------- */
4235+
027c5e7a
AM
4236+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
4237+{
4238+ int err;
5afbbe0d 4239+ aufs_bindex_t btop, bbot;
027c5e7a
AM
4240+ struct aufs_ibusy ibusy;
4241+ struct inode *inode, *h_inode;
4242+
4243+ err = -EPERM;
4244+ if (unlikely(!capable(CAP_SYS_ADMIN)))
4245+ goto out;
4246+
4247+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
4248+ if (!err)
4249+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
4250+ if (unlikely(err)) {
4251+ err = -EFAULT;
4252+ AuTraceErr(err);
4253+ goto out;
4254+ }
4255+
4256+ err = -EINVAL;
4257+ si_read_lock(sb, AuLock_FLUSH);
5afbbe0d 4258+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbbot(sb)))
027c5e7a
AM
4259+ goto out_unlock;
4260+
4261+ err = 0;
4262+ ibusy.h_ino = 0; /* invalid */
4263+ inode = ilookup(sb, ibusy.ino);
4264+ if (!inode
4265+ || inode->i_ino == AUFS_ROOT_INO
5afbbe0d 4266+ || au_is_bad_inode(inode))
027c5e7a
AM
4267+ goto out_unlock;
4268+
4269+ ii_read_lock_child(inode);
5afbbe0d
AM
4270+ btop = au_ibtop(inode);
4271+ bbot = au_ibbot(inode);
4272+ if (btop <= ibusy.bindex && ibusy.bindex <= bbot) {
027c5e7a 4273+ h_inode = au_h_iptr(inode, ibusy.bindex);
5afbbe0d 4274+ if (h_inode && au_test_ibusy(inode, btop, bbot))
027c5e7a
AM
4275+ ibusy.h_ino = h_inode->i_ino;
4276+ }
4277+ ii_read_unlock(inode);
4278+ iput(inode);
4279+
4280+out_unlock:
4281+ si_read_unlock(sb);
4282+ if (!err) {
4283+ err = __put_user(ibusy.h_ino, &arg->h_ino);
4284+ if (unlikely(err)) {
4285+ err = -EFAULT;
4286+ AuTraceErr(err);
4287+ }
4288+ }
4289+out:
4290+ return err;
4291+}
4292+
4293+long au_ibusy_ioctl(struct file *file, unsigned long arg)
4294+{
2000de60 4295+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg);
027c5e7a
AM
4296+}
4297+
4298+#ifdef CONFIG_COMPAT
4299+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
4300+{
2000de60 4301+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg));
027c5e7a
AM
4302+}
4303+#endif
4304+
4305+/* ---------------------------------------------------------------------- */
4306+
1facf9fc 4307+/*
4308+ * change a branch permission
4309+ */
4310+
dece6358
AM
4311+static void au_warn_ima(void)
4312+{
4313+#ifdef CONFIG_IMA
1308ab2a 4314+ /* since it doesn't support mark_files_ro() */
027c5e7a 4315+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
4316+#endif
4317+}
4318+
1facf9fc 4319+static int do_need_sigen_inc(int a, int b)
4320+{
4321+ return au_br_whable(a) && !au_br_whable(b);
4322+}
4323+
4324+static int need_sigen_inc(int old, int new)
4325+{
4326+ return do_need_sigen_inc(old, new)
4327+ || do_need_sigen_inc(new, old);
4328+}
4329+
4330+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
4331+{
7f207e10 4332+ int err, do_warn;
027c5e7a 4333+ unsigned int mnt_flags;
7f207e10 4334+ unsigned long long ull, max;
e49829fe 4335+ aufs_bindex_t br_id;
38d290e6 4336+ unsigned char verbose, writer;
7f207e10 4337+ struct file *file, *hf, **array;
e49829fe 4338+ struct au_hfile *hfile;
1facf9fc 4339+
027c5e7a
AM
4340+ mnt_flags = au_mntflags(sb);
4341+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
4342+
7f207e10
AM
4343+ array = au_farray_alloc(sb, &max);
4344+ err = PTR_ERR(array);
4345+ if (IS_ERR(array))
1facf9fc 4346+ goto out;
4347+
7f207e10 4348+ do_warn = 0;
e49829fe 4349+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
4350+ for (ull = 0; ull < max; ull++) {
4351+ file = array[ull];
076b876e
AM
4352+ if (unlikely(!file))
4353+ break;
1facf9fc 4354+
523b37e3 4355+ /* AuDbg("%pD\n", file); */
1facf9fc 4356+ fi_read_lock(file);
4357+ if (unlikely(au_test_mmapped(file))) {
4358+ err = -EBUSY;
523b37e3 4359+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 4360+ AuDbgFile(file);
1facf9fc 4361+ FiMustNoWaiters(file);
4362+ fi_read_unlock(file);
7f207e10 4363+ goto out_array;
1facf9fc 4364+ }
4365+
e49829fe
JR
4366+ hfile = &au_fi(file)->fi_htop;
4367+ hf = hfile->hf_file;
7e9cd9fe 4368+ if (!d_is_reg(file->f_path.dentry)
1facf9fc 4369+ || !(file->f_mode & FMODE_WRITE)
e49829fe 4370+ || hfile->hf_br->br_id != br_id
7f207e10
AM
4371+ || !(hf->f_mode & FMODE_WRITE))
4372+ array[ull] = NULL;
4373+ else {
4374+ do_warn = 1;
4375+ get_file(file);
1facf9fc 4376+ }
4377+
1facf9fc 4378+ FiMustNoWaiters(file);
4379+ fi_read_unlock(file);
7f207e10
AM
4380+ fput(file);
4381+ }
1facf9fc 4382+
4383+ err = 0;
7f207e10 4384+ if (do_warn)
dece6358 4385+ au_warn_ima();
7f207e10
AM
4386+
4387+ for (ull = 0; ull < max; ull++) {
4388+ file = array[ull];
4389+ if (!file)
4390+ continue;
4391+
1facf9fc 4392+ /* todo: already flushed? */
523b37e3
AM
4393+ /*
4394+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
4395+ * approach which resets f_mode and calls mnt_drop_write() and
4396+ * file_release_write() for each file, because the branch
4397+ * attribute in aufs world is totally different from the native
4398+ * fs rw/ro mode.
4399+ */
7f207e10
AM
4400+ /* fi_read_lock(file); */
4401+ hfile = &au_fi(file)->fi_htop;
4402+ hf = hfile->hf_file;
4403+ /* fi_read_unlock(file); */
027c5e7a 4404+ spin_lock(&hf->f_lock);
38d290e6
JR
4405+ writer = !!(hf->f_mode & FMODE_WRITER);
4406+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
027c5e7a 4407+ spin_unlock(&hf->f_lock);
38d290e6
JR
4408+ if (writer) {
4409+ put_write_access(file_inode(hf));
c06a8ce3 4410+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 4411+ }
4412+ }
4413+
7f207e10
AM
4414+out_array:
4415+ au_farray_free(array, max);
4f0767ce 4416+out:
7f207e10 4417+ AuTraceErr(err);
1facf9fc 4418+ return err;
4419+}
4420+
4421+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4422+ int *do_refresh)
1facf9fc 4423+{
4424+ int err, rerr;
4425+ aufs_bindex_t bindex;
4426+ struct dentry *root;
4427+ struct au_branch *br;
076b876e 4428+ struct au_br_fhsm *bf;
1facf9fc 4429+
4430+ root = sb->s_root;
1facf9fc 4431+ bindex = au_find_dbindex(root, mod->h_root);
4432+ if (bindex < 0) {
4433+ if (remount)
4434+ return 0; /* success */
4435+ err = -ENOENT;
4a4d8108 4436+ pr_err("%s no such branch\n", mod->path);
1facf9fc 4437+ goto out;
4438+ }
4439+ AuDbg("bindex b%d\n", bindex);
4440+
5527c038 4441+ err = test_br(d_inode(mod->h_root), mod->perm, mod->path);
1facf9fc 4442+ if (unlikely(err))
4443+ goto out;
4444+
4445+ br = au_sbr(sb, bindex);
86dc4139 4446+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 4447+ if (br->br_perm == mod->perm)
4448+ return 0; /* success */
4449+
076b876e
AM
4450+ /* pre-allocate for non-fhsm --> fhsm */
4451+ bf = NULL;
4452+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
4453+ err = au_fhsm_br_alloc(br);
4454+ if (unlikely(err))
4455+ goto out;
4456+ bf = br->br_fhsm;
4457+ br->br_fhsm = NULL;
4458+ }
4459+
1facf9fc 4460+ if (au_br_writable(br->br_perm)) {
4461+ /* remove whiteout base */
86dc4139 4462+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 4463+ if (unlikely(err))
076b876e 4464+ goto out_bf;
1facf9fc 4465+
4466+ if (!au_br_writable(mod->perm)) {
4467+ /* rw --> ro, file might be mmapped */
4468+ DiMustNoWaiters(root);
5527c038 4469+ IiMustNoWaiters(d_inode(root));
1facf9fc 4470+ di_write_unlock(root);
4471+ err = au_br_mod_files_ro(sb, bindex);
4472+ /* aufs_write_lock() calls ..._child() */
4473+ di_write_lock_child(root);
4474+
4475+ if (unlikely(err)) {
4476+ rerr = -ENOMEM;
be52b249 4477+ br->br_wbr = kzalloc(sizeof(*br->br_wbr),
1facf9fc 4478+ GFP_NOFS);
86dc4139
AM
4479+ if (br->br_wbr)
4480+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 4481+ if (unlikely(rerr)) {
4482+ AuIOErr("nested error %d (%d)\n",
4483+ rerr, err);
4484+ br->br_perm = mod->perm;
4485+ }
4486+ }
4487+ }
4488+ } else if (au_br_writable(mod->perm)) {
4489+ /* ro --> rw */
4490+ err = -ENOMEM;
be52b249 4491+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), GFP_NOFS);
1facf9fc 4492+ if (br->br_wbr) {
86dc4139 4493+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 4494+ if (unlikely(err)) {
1c60b727 4495+ kfree(br->br_wbr);
1facf9fc 4496+ br->br_wbr = NULL;
4497+ }
4498+ }
4499+ }
076b876e
AM
4500+ if (unlikely(err))
4501+ goto out_bf;
4502+
4503+ if (au_br_fhsm(br->br_perm)) {
4504+ if (!au_br_fhsm(mod->perm)) {
4505+ /* fhsm --> non-fhsm */
4506+ au_br_fhsm_fin(br->br_fhsm);
1c60b727 4507+ kfree(br->br_fhsm);
076b876e
AM
4508+ br->br_fhsm = NULL;
4509+ }
4510+ } else if (au_br_fhsm(mod->perm))
4511+ /* non-fhsm --> fhsm */
4512+ br->br_fhsm = bf;
4513+
076b876e
AM
4514+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
4515+ br->br_perm = mod->perm;
4516+ goto out; /* success */
1facf9fc 4517+
076b876e 4518+out_bf:
8b6a4947 4519+ kfree(bf);
076b876e
AM
4520+out:
4521+ AuTraceErr(err);
4522+ return err;
4523+}
4524+
4525+/* ---------------------------------------------------------------------- */
4526+
4527+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
4528+{
4529+ int err;
4530+ struct kstatfs kstfs;
4531+
4532+ err = vfs_statfs(&br->br_path, &kstfs);
1facf9fc 4533+ if (!err) {
076b876e
AM
4534+ stfs->f_blocks = kstfs.f_blocks;
4535+ stfs->f_bavail = kstfs.f_bavail;
4536+ stfs->f_files = kstfs.f_files;
4537+ stfs->f_ffree = kstfs.f_ffree;
1facf9fc 4538+ }
4539+
1facf9fc 4540+ return err;
4541+}
7f207e10
AM
4542diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
4543--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
4544+++ linux/fs/aufs/branch.h 2018-10-23 12:33:35.592708932 +0200
4545@@ -0,0 +1,367 @@
062440b3 4546+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 4547+/*
b00004a5 4548+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 4549+ *
4550+ * This program, aufs is free software; you can redistribute it and/or modify
4551+ * it under the terms of the GNU General Public License as published by
4552+ * the Free Software Foundation; either version 2 of the License, or
4553+ * (at your option) any later version.
dece6358
AM
4554+ *
4555+ * This program is distributed in the hope that it will be useful,
4556+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4557+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4558+ * GNU General Public License for more details.
4559+ *
4560+ * You should have received a copy of the GNU General Public License
523b37e3 4561+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4562+ */
4563+
4564+/*
4565+ * branch filesystems and xino for them
4566+ */
4567+
4568+#ifndef __AUFS_BRANCH_H__
4569+#define __AUFS_BRANCH_H__
4570+
4571+#ifdef __KERNEL__
4572+
1facf9fc 4573+#include <linux/mount.h>
8b6a4947 4574+#include "dirren.h"
4a4d8108 4575+#include "dynop.h"
acd2b654 4576+#include "lcnt.h"
1facf9fc 4577+#include "rwsem.h"
4578+#include "super.h"
4579+
4580+/* ---------------------------------------------------------------------- */
4581+
4582+/* a xino file */
062440b3 4583+struct au_xino {
acd2b654
AM
4584+ struct file **xi_file;
4585+ unsigned int xi_nfile;
4586+
521ced18
JR
4587+ struct {
4588+ spinlock_t spin;
4589+ ino_t *array;
4590+ int total;
4591+ /* reserved for future use */
4592+ /* unsigned long *bitmap; */
4593+ wait_queue_head_t wqh;
4594+ } xi_nondir;
1facf9fc 4595+
acd2b654
AM
4596+ struct mutex xi_mtx; /* protects xi_file array */
4597+ /* reserved for future use */
4598+ /* wait_queue_head_t xi_wq; */
4599+ /* atomic_t xi_pending; */
4600+
062440b3 4601+ atomic_t xi_truncating;
1facf9fc 4602+
062440b3 4603+ struct kref xi_kref;
1facf9fc 4604+};
4605+
076b876e
AM
4606+/* File-based Hierarchical Storage Management */
4607+struct au_br_fhsm {
4608+#ifdef CONFIG_AUFS_FHSM
4609+ struct mutex bf_lock;
4610+ unsigned long bf_jiffy;
4611+ struct aufs_stfs bf_stfs;
4612+ int bf_readable;
4613+#endif
4614+};
4615+
1facf9fc 4616+/* members for writable branch only */
4617+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
4618+struct au_wbr {
dece6358 4619+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 4620+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 4621+ atomic_t wbr_wh_running;
1facf9fc 4622+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
4623+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
4624+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
4625+
4626+ /* mfs mode */
4627+ unsigned long long wbr_bytes;
4628+};
4629+
4a4d8108
AM
4630+/* ext2 has 3 types of operations at least, ext3 has 4 */
4631+#define AuBrDynOp (AuDyLast * 4)
4632+
1716fcea
AM
4633+#ifdef CONFIG_AUFS_HFSNOTIFY
4634+/* support for asynchronous destruction */
4635+struct au_br_hfsnotify {
4636+ struct fsnotify_group *hfsn_group;
4637+};
4638+#endif
4639+
392086de
AM
4640+/* sysfs entries */
4641+struct au_brsysfs {
4642+ char name[16];
4643+ struct attribute attr;
4644+};
4645+
4646+enum {
4647+ AuBrSysfs_BR,
4648+ AuBrSysfs_BRID,
4649+ AuBrSysfs_Last
4650+};
4651+
1facf9fc 4652+/* protected by superblock rwsem */
4653+struct au_branch {
062440b3 4654+ struct au_xino *br_xino;
1facf9fc 4655+
4656+ aufs_bindex_t br_id;
4657+
4658+ int br_perm;
86dc4139 4659+ struct path br_path;
4a4d8108
AM
4660+ spinlock_t br_dykey_lock;
4661+ struct au_dykey *br_dykey[AuBrDynOp];
acd2b654
AM
4662+ au_lcnt_t br_nfiles; /* opened files */
4663+ au_lcnt_t br_count; /* in-use for other */
1facf9fc 4664+
4665+ struct au_wbr *br_wbr;
076b876e 4666+ struct au_br_fhsm *br_fhsm;
1facf9fc 4667+
027c5e7a 4668+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 4669+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
4670+#endif
4671+
1facf9fc 4672+#ifdef CONFIG_SYSFS
392086de
AM
4673+ /* entries under sysfs per mount-point */
4674+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 4675+#endif
8b6a4947 4676+
062440b3
AM
4677+#ifdef CONFIG_DEBUG_FS
4678+ struct dentry *br_dbgaufs; /* xino */
4679+#endif
4680+
8b6a4947 4681+ struct au_dr_br br_dirren;
1facf9fc 4682+};
4683+
4684+/* ---------------------------------------------------------------------- */
4685+
86dc4139
AM
4686+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
4687+{
4688+ return br->br_path.mnt;
4689+}
4690+
4691+static inline struct dentry *au_br_dentry(struct au_branch *br)
4692+{
4693+ return br->br_path.dentry;
4694+}
4695+
4696+static inline struct super_block *au_br_sb(struct au_branch *br)
4697+{
4698+ return au_br_mnt(br)->mnt_sb;
4699+}
4700+
1facf9fc 4701+static inline int au_br_rdonly(struct au_branch *br)
4702+{
8b6a4947 4703+ return (sb_rdonly(au_br_sb(br))
1facf9fc 4704+ || !au_br_writable(br->br_perm))
4705+ ? -EROFS : 0;
4706+}
4707+
4a4d8108 4708+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 4709+{
4a4d8108 4710+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 4711+ return !(brperm & AuBrPerm_RR);
1facf9fc 4712+#else
4713+ return 0;
4714+#endif
4715+}
4716+
b912730e
AM
4717+static inline int au_br_test_oflag(int oflag, struct au_branch *br)
4718+{
4719+ int err, exec_flag;
4720+
4721+ err = 0;
4722+ exec_flag = oflag & __FMODE_EXEC;
79b8bda9 4723+ if (unlikely(exec_flag && path_noexec(&br->br_path)))
b912730e
AM
4724+ err = -EACCES;
4725+
4726+ return err;
4727+}
4728+
062440b3
AM
4729+static inline void au_xino_get(struct au_branch *br)
4730+{
4731+ struct au_xino *xi;
4732+
4733+ xi = br->br_xino;
4734+ if (xi)
4735+ kref_get(&xi->xi_kref);
4736+}
4737+
4738+static inline int au_xino_count(struct au_branch *br)
4739+{
4740+ int v;
4741+ struct au_xino *xi;
4742+
4743+ v = 0;
4744+ xi = br->br_xino;
4745+ if (xi)
4746+ v = kref_read(&xi->xi_kref);
4747+
4748+ return v;
4749+}
4750+
1facf9fc 4751+/* ---------------------------------------------------------------------- */
4752+
4753+/* branch.c */
4754+struct au_sbinfo;
4755+void au_br_free(struct au_sbinfo *sinfo);
4756+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
4757+struct au_opt_add;
4758+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
4759+struct au_opt_del;
4760+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
4761+long au_ibusy_ioctl(struct file *file, unsigned long arg);
4762+#ifdef CONFIG_COMPAT
4763+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
4764+#endif
1facf9fc 4765+struct au_opt_mod;
4766+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4767+ int *do_refresh);
076b876e
AM
4768+struct aufs_stfs;
4769+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
1facf9fc 4770+
4771+/* xino.c */
4772+static const loff_t au_loff_max = LLONG_MAX;
4773+
acd2b654 4774+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry);
062440b3
AM
4775+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent);
4776+struct file *au_xino_create2(struct super_block *sb, struct path *base,
4777+ struct file *copy_src);
acd2b654
AM
4778+struct au_xi_new {
4779+ struct au_xino *xi; /* switch between xino and xigen */
4780+ int idx;
4781+ struct path *base;
4782+ struct file *copy_src;
4783+};
4784+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew);
062440b3
AM
4785+
4786+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4787+ ino_t *ino);
4788+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4789+ ino_t ino);
5527c038 4790+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size,
1facf9fc 4791+ loff_t *pos);
5527c038
JR
4792+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
4793+ size_t size, loff_t *pos);
062440b3
AM
4794+
4795+int au_xib_trunc(struct super_block *sb);
acd2b654 4796+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin);
1facf9fc 4797+
acd2b654 4798+struct au_xino *au_xino_alloc(unsigned int nfile);
062440b3 4799+int au_xino_put(struct au_branch *br);
acd2b654 4800+struct file *au_xino_file1(struct au_xino *xi);
062440b3 4801+
1facf9fc 4802+struct au_opt_xino;
1facf9fc 4803+void au_xino_clr(struct super_block *sb);
062440b3 4804+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount);
1facf9fc 4805+struct file *au_xino_def(struct super_block *sb);
062440b3
AM
4806+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t hino,
4807+ struct path *base);
4808+
4809+ino_t au_xino_new_ino(struct super_block *sb);
4810+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 4811+
521ced18
JR
4812+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
4813+ ino_t h_ino, int idx);
4814+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4815+ int *idx);
4816+
062440b3
AM
4817+int au_xino_path(struct seq_file *seq, struct file *file);
4818+
1facf9fc 4819+/* ---------------------------------------------------------------------- */
4820+
acd2b654
AM
4821+/* @idx is signed to accept -1 meaning the first file */
4822+static inline struct file *au_xino_file(struct au_xino *xi, int idx)
4823+{
4824+ struct file *file;
4825+
4826+ file = NULL;
4827+ if (!xi)
4828+ goto out;
4829+
4830+ if (idx >= 0) {
4831+ if (idx < xi->xi_nfile)
4832+ file = xi->xi_file[idx];
4833+ } else
4834+ file = au_xino_file1(xi);
4835+
4836+out:
4837+ return file;
4838+}
4839+
4840+/* ---------------------------------------------------------------------- */
4841+
1facf9fc 4842+/* Superblock to branch */
4843+static inline
4844+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
4845+{
4846+ return au_sbr(sb, bindex)->br_id;
4847+}
4848+
4849+static inline
4850+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
4851+{
86dc4139 4852+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 4853+}
4854+
4855+static inline
4856+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
4857+{
86dc4139 4858+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 4859+}
4860+
1facf9fc 4861+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
4862+{
4863+ return au_sbr(sb, bindex)->br_perm;
4864+}
4865+
4866+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
4867+{
4868+ return au_br_whable(au_sbr_perm(sb, bindex));
4869+}
4870+
4871+/* ---------------------------------------------------------------------- */
4872+
8b6a4947
AM
4873+#define wbr_wh_read_lock(wbr) au_rw_read_lock(&(wbr)->wbr_wh_rwsem)
4874+#define wbr_wh_write_lock(wbr) au_rw_write_lock(&(wbr)->wbr_wh_rwsem)
4875+#define wbr_wh_read_trylock(wbr) au_rw_read_trylock(&(wbr)->wbr_wh_rwsem)
4876+#define wbr_wh_write_trylock(wbr) au_rw_write_trylock(&(wbr)->wbr_wh_rwsem)
1facf9fc 4877+/*
8b6a4947
AM
4878+#define wbr_wh_read_trylock_nested(wbr) \
4879+ au_rw_read_trylock_nested(&(wbr)->wbr_wh_rwsem)
4880+#define wbr_wh_write_trylock_nested(wbr) \
4881+ au_rw_write_trylock_nested(&(wbr)->wbr_wh_rwsem)
4882+*/
1facf9fc 4883+
8b6a4947
AM
4884+#define wbr_wh_read_unlock(wbr) au_rw_read_unlock(&(wbr)->wbr_wh_rwsem)
4885+#define wbr_wh_write_unlock(wbr) au_rw_write_unlock(&(wbr)->wbr_wh_rwsem)
4886+#define wbr_wh_downgrade_lock(wbr) au_rw_dgrade_lock(&(wbr)->wbr_wh_rwsem)
4887+
4888+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&(wbr)->wbr_wh_rwsem)
4889+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&(wbr)->wbr_wh_rwsem)
4890+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&(wbr)->wbr_wh_rwsem)
dece6358 4891+
076b876e
AM
4892+/* ---------------------------------------------------------------------- */
4893+
4894+#ifdef CONFIG_AUFS_FHSM
4895+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
4896+{
4897+ mutex_init(&brfhsm->bf_lock);
4898+ brfhsm->bf_jiffy = 0;
4899+ brfhsm->bf_readable = 0;
4900+}
4901+
4902+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
4903+{
4904+ mutex_destroy(&brfhsm->bf_lock);
4905+}
4906+#else
4907+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
4908+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
4909+#endif
4910+
1facf9fc 4911+#endif /* __KERNEL__ */
4912+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
4913diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
4914--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
b00004a5 4915+++ linux/fs/aufs/conf.mk 2018-06-04 09:08:09.181412645 +0200
2121bcd9
AM
4916@@ -0,0 +1,40 @@
4917+# SPDX-License-Identifier: GPL-2.0
4a4d8108
AM
4918+
4919+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
4920+
4921+define AuConf
4922+ifdef ${1}
4923+AuConfStr += ${1}=${${1}}
4924+endif
4925+endef
4926+
b752ccd1 4927+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 4928+ SBILIST \
7f207e10 4929+ HNOTIFY HFSNOTIFY \
4a4d8108 4930+ EXPORT INO_T_64 \
c1595e42 4931+ XATTR \
076b876e 4932+ FHSM \
4a4d8108 4933+ RDU \
8b6a4947 4934+ DIRREN \
4a4d8108
AM
4935+ SHWH \
4936+ BR_RAMFS \
4937+ BR_FUSE POLL \
4938+ BR_HFSPLUS \
4939+ BDEV_LOOP \
b752ccd1
AM
4940+ DEBUG MAGIC_SYSRQ
4941+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
4942+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
4943+
4944+AuConfName = ${obj}/conf.str
4945+${AuConfName}.tmp: FORCE
4946+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
4947+${AuConfName}: ${AuConfName}.tmp
4948+ @diff -q $< $@ > /dev/null 2>&1 || { \
4949+ echo ' GEN ' $@; \
4950+ cp -p $< $@; \
4951+ }
4952+FORCE:
4953+clean-files += ${AuConfName} ${AuConfName}.tmp
4954+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
4955+
4956+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
4957diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
4958--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
4959+++ linux/fs/aufs/cpup.c 2018-10-23 12:33:35.596042364 +0200
4960@@ -0,0 +1,1444 @@
cd7a4cd9 4961+// SPDX-License-Identifier: GPL-2.0
1facf9fc 4962+/*
b00004a5 4963+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 4964+ *
4965+ * This program, aufs is free software; you can redistribute it and/or modify
4966+ * it under the terms of the GNU General Public License as published by
4967+ * the Free Software Foundation; either version 2 of the License, or
4968+ * (at your option) any later version.
dece6358
AM
4969+ *
4970+ * This program is distributed in the hope that it will be useful,
4971+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4972+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4973+ * GNU General Public License for more details.
4974+ *
4975+ * You should have received a copy of the GNU General Public License
523b37e3 4976+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4977+ */
4978+
4979+/*
4980+ * copy-up functions, see wbr_policy.c for copy-down
4981+ */
4982+
4983+#include <linux/fs_stack.h>
dece6358 4984+#include <linux/mm.h>
8cdd5066 4985+#include <linux/task_work.h>
1facf9fc 4986+#include "aufs.h"
4987+
86dc4139 4988+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 4989+{
4990+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 4991+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 4992+
86dc4139
AM
4993+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
4994+
4995+ dst->i_flags |= iflags & ~mask;
1facf9fc 4996+ if (au_test_fs_notime(dst->i_sb))
4997+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
4998+}
4999+
5000+void au_cpup_attr_timesizes(struct inode *inode)
5001+{
5002+ struct inode *h_inode;
5003+
5afbbe0d 5004+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 5005+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 5006+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 5007+}
5008+
5009+void au_cpup_attr_nlink(struct inode *inode, int force)
5010+{
5011+ struct inode *h_inode;
5012+ struct super_block *sb;
5afbbe0d 5013+ aufs_bindex_t bindex, bbot;
1facf9fc 5014+
5015+ sb = inode->i_sb;
5afbbe0d 5016+ bindex = au_ibtop(inode);
1facf9fc 5017+ h_inode = au_h_iptr(inode, bindex);
5018+ if (!force
5019+ && !S_ISDIR(h_inode->i_mode)
5020+ && au_opt_test(au_mntflags(sb), PLINK)
5021+ && au_plink_test(inode))
5022+ return;
5023+
7eafdf33
AM
5024+ /*
5025+ * 0 can happen in revalidating.
38d290e6
JR
5026+ * h_inode->i_mutex may not be held here, but it is harmless since once
5027+ * i_nlink reaches 0, it will never become positive except O_TMPFILE
5028+ * case.
5029+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
5030+ * the incorrect link count.
7eafdf33 5031+ */
92d182d2 5032+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 5033+
5034+ /*
5035+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
5036+ * it may includes whplink directory.
5037+ */
5038+ if (S_ISDIR(h_inode->i_mode)) {
5afbbe0d
AM
5039+ bbot = au_ibbot(inode);
5040+ for (bindex++; bindex <= bbot; bindex++) {
1facf9fc 5041+ h_inode = au_h_iptr(inode, bindex);
5042+ if (h_inode)
5043+ au_add_nlink(inode, h_inode);
5044+ }
5045+ }
5046+}
5047+
5048+void au_cpup_attr_changeable(struct inode *inode)
5049+{
5050+ struct inode *h_inode;
5051+
5afbbe0d 5052+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 5053+ inode->i_mode = h_inode->i_mode;
5054+ inode->i_uid = h_inode->i_uid;
5055+ inode->i_gid = h_inode->i_gid;
5056+ au_cpup_attr_timesizes(inode);
86dc4139 5057+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 5058+}
5059+
5060+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
5061+{
5062+ struct au_iinfo *iinfo = au_ii(inode);
5063+
1308ab2a 5064+ IiMustWriteLock(inode);
5065+
1facf9fc 5066+ iinfo->ii_higen = h_inode->i_generation;
5067+ iinfo->ii_hsb1 = h_inode->i_sb;
5068+}
5069+
5070+void au_cpup_attr_all(struct inode *inode, int force)
5071+{
5072+ struct inode *h_inode;
5073+
5afbbe0d 5074+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 5075+ au_cpup_attr_changeable(inode);
5076+ if (inode->i_nlink > 0)
5077+ au_cpup_attr_nlink(inode, force);
5078+ inode->i_rdev = h_inode->i_rdev;
5079+ inode->i_blkbits = h_inode->i_blkbits;
5080+ au_cpup_igen(inode, h_inode);
5081+}
5082+
5083+/* ---------------------------------------------------------------------- */
5084+
5085+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
5086+
5087+/* keep the timestamps of the parent dir when cpup */
5088+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
5089+ struct path *h_path)
5090+{
5091+ struct inode *h_inode;
5092+
5093+ dt->dt_dentry = dentry;
5094+ dt->dt_h_path = *h_path;
5527c038 5095+ h_inode = d_inode(h_path->dentry);
1facf9fc 5096+ dt->dt_atime = h_inode->i_atime;
5097+ dt->dt_mtime = h_inode->i_mtime;
5098+ /* smp_mb(); */
5099+}
5100+
5101+void au_dtime_revert(struct au_dtime *dt)
5102+{
5103+ struct iattr attr;
5104+ int err;
5105+
5106+ attr.ia_atime = dt->dt_atime;
5107+ attr.ia_mtime = dt->dt_mtime;
5108+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
5109+ | ATTR_ATIME | ATTR_ATIME_SET;
5110+
523b37e3
AM
5111+ /* no delegation since this is a directory */
5112+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 5113+ if (unlikely(err))
0c3ec466 5114+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 5115+}
5116+
5117+/* ---------------------------------------------------------------------- */
5118+
86dc4139
AM
5119+/* internal use only */
5120+struct au_cpup_reg_attr {
5121+ int valid;
5122+ struct kstat st;
5123+ unsigned int iflags; /* inode->i_flags */
5124+};
5125+
1facf9fc 5126+static noinline_for_stack
86dc4139
AM
5127+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
5128+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5129+{
c1595e42 5130+ int err, sbits, icex;
7e9cd9fe
AM
5131+ unsigned int mnt_flags;
5132+ unsigned char verbose;
1facf9fc 5133+ struct iattr ia;
5134+ struct path h_path;
1308ab2a 5135+ struct inode *h_isrc, *h_idst;
86dc4139 5136+ struct kstat *h_st;
c1595e42 5137+ struct au_branch *br;
1facf9fc 5138+
5139+ h_path.dentry = au_h_dptr(dst, bindex);
5527c038 5140+ h_idst = d_inode(h_path.dentry);
c1595e42
JR
5141+ br = au_sbr(dst->d_sb, bindex);
5142+ h_path.mnt = au_br_mnt(br);
5527c038 5143+ h_isrc = d_inode(h_src);
1308ab2a 5144+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 5145+ | ATTR_ATIME | ATTR_MTIME
5146+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
5147+ if (h_src_attr && h_src_attr->valid) {
5148+ h_st = &h_src_attr->st;
5149+ ia.ia_uid = h_st->uid;
5150+ ia.ia_gid = h_st->gid;
5151+ ia.ia_atime = h_st->atime;
5152+ ia.ia_mtime = h_st->mtime;
5153+ if (h_idst->i_mode != h_st->mode
5154+ && !S_ISLNK(h_idst->i_mode)) {
5155+ ia.ia_valid |= ATTR_MODE;
5156+ ia.ia_mode = h_st->mode;
5157+ }
5158+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
5159+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
5160+ } else {
5161+ ia.ia_uid = h_isrc->i_uid;
5162+ ia.ia_gid = h_isrc->i_gid;
5163+ ia.ia_atime = h_isrc->i_atime;
5164+ ia.ia_mtime = h_isrc->i_mtime;
5165+ if (h_idst->i_mode != h_isrc->i_mode
5166+ && !S_ISLNK(h_idst->i_mode)) {
5167+ ia.ia_valid |= ATTR_MODE;
5168+ ia.ia_mode = h_isrc->i_mode;
5169+ }
5170+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
5171+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 5172+ }
523b37e3
AM
5173+ /* no delegation since it is just created */
5174+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 5175+
5176+ /* is this nfs only? */
5177+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
5178+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
5179+ ia.ia_mode = h_isrc->i_mode;
523b37e3 5180+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 5181+ }
5182+
c1595e42 5183+ icex = br->br_perm & AuBrAttr_ICEX;
7e9cd9fe
AM
5184+ if (!err) {
5185+ mnt_flags = au_mntflags(dst->d_sb);
5186+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
5187+ err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose);
5188+ }
c1595e42 5189+
1facf9fc 5190+ return err;
5191+}
5192+
5193+/* ---------------------------------------------------------------------- */
5194+
5195+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
5196+ char *buf, unsigned long blksize)
5197+{
5198+ int err;
5199+ size_t sz, rbytes, wbytes;
5200+ unsigned char all_zero;
5201+ char *p, *zp;
febd17d6 5202+ struct inode *h_inode;
1facf9fc 5203+ /* reduce stack usage */
5204+ struct iattr *ia;
5205+
5206+ zp = page_address(ZERO_PAGE(0));
5207+ if (unlikely(!zp))
5208+ return -ENOMEM; /* possible? */
5209+
5210+ err = 0;
5211+ all_zero = 0;
5212+ while (len) {
5213+ AuDbg("len %lld\n", len);
5214+ sz = blksize;
5215+ if (len < blksize)
5216+ sz = len;
5217+
5218+ rbytes = 0;
5219+ /* todo: signal_pending? */
5220+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
5221+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
5222+ err = rbytes;
5223+ }
5224+ if (unlikely(err < 0))
5225+ break;
5226+
5227+ all_zero = 0;
5228+ if (len >= rbytes && rbytes == blksize)
5229+ all_zero = !memcmp(buf, zp, rbytes);
5230+ if (!all_zero) {
5231+ wbytes = rbytes;
5232+ p = buf;
5233+ while (wbytes) {
5234+ size_t b;
5235+
5236+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
5237+ err = b;
5238+ /* todo: signal_pending? */
5239+ if (unlikely(err == -EAGAIN || err == -EINTR))
5240+ continue;
5241+ if (unlikely(err < 0))
5242+ break;
5243+ wbytes -= b;
5244+ p += b;
5245+ }
392086de
AM
5246+ if (unlikely(err < 0))
5247+ break;
1facf9fc 5248+ } else {
5249+ loff_t res;
5250+
5251+ AuLabel(hole);
5252+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
5253+ err = res;
5254+ if (unlikely(res < 0))
5255+ break;
5256+ }
5257+ len -= rbytes;
5258+ err = 0;
5259+ }
5260+
5261+ /* the last block may be a hole */
5262+ if (!err && all_zero) {
5263+ AuLabel(last hole);
5264+
5265+ err = 1;
2000de60 5266+ if (au_test_nfs(dst->f_path.dentry->d_sb)) {
1facf9fc 5267+ /* nfs requires this step to make last hole */
5268+ /* is this only nfs? */
5269+ do {
5270+ /* todo: signal_pending? */
5271+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
5272+ } while (err == -EAGAIN || err == -EINTR);
5273+ if (err == 1)
5274+ dst->f_pos--;
5275+ }
5276+
5277+ if (err == 1) {
5278+ ia = (void *)buf;
5279+ ia->ia_size = dst->f_pos;
5280+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
5281+ ia->ia_file = dst;
febd17d6
JR
5282+ h_inode = file_inode(dst);
5283+ inode_lock_nested(h_inode, AuLsc_I_CHILD2);
523b37e3
AM
5284+ /* no delegation since it is just created */
5285+ err = vfsub_notify_change(&dst->f_path, ia,
5286+ /*delegated*/NULL);
febd17d6 5287+ inode_unlock(h_inode);
1facf9fc 5288+ }
5289+ }
5290+
5291+ return err;
5292+}
5293+
5294+int au_copy_file(struct file *dst, struct file *src, loff_t len)
5295+{
5296+ int err;
5297+ unsigned long blksize;
5298+ unsigned char do_kfree;
5299+ char *buf;
5300+
5301+ err = -ENOMEM;
2000de60 5302+ blksize = dst->f_path.dentry->d_sb->s_blocksize;
1facf9fc 5303+ if (!blksize || PAGE_SIZE < blksize)
5304+ blksize = PAGE_SIZE;
5305+ AuDbg("blksize %lu\n", blksize);
5306+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
5307+ if (do_kfree)
5308+ buf = kmalloc(blksize, GFP_NOFS);
5309+ else
5310+ buf = (void *)__get_free_page(GFP_NOFS);
5311+ if (unlikely(!buf))
5312+ goto out;
5313+
5314+ if (len > (1 << 22))
5315+ AuDbg("copying a large file %lld\n", (long long)len);
5316+
5317+ src->f_pos = 0;
5318+ dst->f_pos = 0;
5319+ err = au_do_copy_file(dst, src, len, buf, blksize);
5320+ if (do_kfree)
1c60b727 5321+ kfree(buf);
1facf9fc 5322+ else
1c60b727 5323+ free_page((unsigned long)buf);
1facf9fc 5324+
4f0767ce 5325+out:
1facf9fc 5326+ return err;
5327+}
5328+
1c60b727
AM
5329+static int au_do_copy(struct file *dst, struct file *src, loff_t len)
5330+{
5331+ int err;
5332+ struct super_block *h_src_sb;
5333+ struct inode *h_src_inode;
5334+
5335+ h_src_inode = file_inode(src);
5336+ h_src_sb = h_src_inode->i_sb;
5337+
5338+ /* XFS acquires inode_lock */
5339+ if (!au_test_xfs(h_src_sb))
5340+ err = au_copy_file(dst, src, len);
5341+ else {
3c1bdaff 5342+ inode_unlock_shared(h_src_inode);
1c60b727 5343+ err = au_copy_file(dst, src, len);
be118d29 5344+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
1c60b727
AM
5345+ }
5346+
5347+ return err;
5348+}
5349+
5350+static int au_clone_or_copy(struct file *dst, struct file *src, loff_t len)
5351+{
5352+ int err;
5353+ struct super_block *h_src_sb;
5354+ struct inode *h_src_inode;
5355+
5356+ h_src_inode = file_inode(src);
5357+ h_src_sb = h_src_inode->i_sb;
5358+ if (h_src_sb != file_inode(dst)->i_sb
5359+ || !dst->f_op->clone_file_range) {
5360+ err = au_do_copy(dst, src, len);
5361+ goto out;
5362+ }
5363+
5364+ if (!au_test_nfs(h_src_sb)) {
3c1bdaff 5365+ inode_unlock_shared(h_src_inode);
1c60b727 5366+ err = vfsub_clone_file_range(src, dst, len);
be118d29 5367+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
1c60b727
AM
5368+ } else
5369+ err = vfsub_clone_file_range(src, dst, len);
5370+ /* older XFS has a condition in cloning */
5371+ if (unlikely(err != -EOPNOTSUPP))
5372+ goto out;
5373+
5374+ /* the backend fs on NFS may not support cloning */
5375+ err = au_do_copy(dst, src, len);
5376+
5377+out:
5378+ AuTraceErr(err);
5379+ return err;
5380+}
5381+
1facf9fc 5382+/*
5383+ * to support a sparse file which is opened with O_APPEND,
5384+ * we need to close the file.
5385+ */
c2b27bf2 5386+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 5387+{
5388+ int err, i;
5389+ enum { SRC, DST };
5390+ struct {
5391+ aufs_bindex_t bindex;
5392+ unsigned int flags;
5393+ struct dentry *dentry;
392086de 5394+ int force_wr;
1facf9fc 5395+ struct file *file;
523b37e3 5396+ void *label;
1facf9fc 5397+ } *f, file[] = {
5398+ {
c2b27bf2 5399+ .bindex = cpg->bsrc,
1facf9fc 5400+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
523b37e3 5401+ .label = &&out
1facf9fc 5402+ },
5403+ {
c2b27bf2 5404+ .bindex = cpg->bdst,
1facf9fc 5405+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 5406+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
523b37e3 5407+ .label = &&out_src
1facf9fc 5408+ }
5409+ };
acd2b654 5410+ struct au_branch *br;
521ced18 5411+ struct super_block *sb, *h_src_sb;
e2f27e51 5412+ struct inode *h_src_inode;
8cdd5066 5413+ struct task_struct *tsk = current;
1facf9fc 5414+
5415+ /* bsrc branch can be ro/rw. */
c2b27bf2 5416+ sb = cpg->dentry->d_sb;
1facf9fc 5417+ f = file;
5418+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
5419+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
5420+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 5421+ /*file*/NULL, f->force_wr);
1facf9fc 5422+ err = PTR_ERR(f->file);
5423+ if (IS_ERR(f->file))
5424+ goto *f->label;
1facf9fc 5425+ }
5426+
5427+ /* try stopping to update while we copyup */
e2f27e51 5428+ h_src_inode = d_inode(file[SRC].dentry);
521ced18
JR
5429+ h_src_sb = h_src_inode->i_sb;
5430+ if (!au_test_nfs(h_src_sb))
e2f27e51 5431+ IMustLock(h_src_inode);
1c60b727 5432+ err = au_clone_or_copy(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 5433+
8cdd5066
JR
5434+ /* i wonder if we had O_NO_DELAY_FPUT flag */
5435+ if (tsk->flags & PF_KTHREAD)
5436+ __fput_sync(file[DST].file);
5437+ else {
062440b3 5438+ /* it happened actually */
8cdd5066
JR
5439+ fput(file[DST].file);
5440+ /*
5441+ * too bad.
5442+ * we have to call both since we don't know which place the file
5443+ * was added to.
5444+ */
5445+ task_work_run();
5446+ flush_delayed_fput();
5447+ }
acd2b654
AM
5448+ br = au_sbr(sb, file[DST].bindex);
5449+ au_lcnt_dec(&br->br_nfiles);
523b37e3 5450+
4f0767ce 5451+out_src:
1facf9fc 5452+ fput(file[SRC].file);
acd2b654
AM
5453+ br = au_sbr(sb, file[SRC].bindex);
5454+ au_lcnt_dec(&br->br_nfiles);
4f0767ce 5455+out:
1facf9fc 5456+ return err;
5457+}
5458+
c2b27bf2 5459+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 5460+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5461+{
5462+ int err, rerr;
5463+ loff_t l;
86dc4139 5464+ struct path h_path;
38d290e6 5465+ struct inode *h_src_inode, *h_dst_inode;
1facf9fc 5466+
5467+ err = 0;
5527c038 5468+ h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc);
86dc4139 5469+ l = i_size_read(h_src_inode);
c2b27bf2
AM
5470+ if (cpg->len == -1 || l < cpg->len)
5471+ cpg->len = l;
5472+ if (cpg->len) {
86dc4139 5473+ /* try stopping to update while we are referencing */
be118d29 5474+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
c2b27bf2 5475+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 5476+
c2b27bf2
AM
5477+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5478+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139 5479+ h_src_attr->iflags = h_src_inode->i_flags;
5527c038 5480+ if (!au_test_nfs(h_src_inode->i_sb))
521ced18 5481+ err = vfsub_getattr(&h_path, &h_src_attr->st);
5527c038 5482+ else {
3c1bdaff 5483+ inode_unlock_shared(h_src_inode);
521ced18 5484+ err = vfsub_getattr(&h_path, &h_src_attr->st);
be118d29 5485+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
5527c038 5486+ }
86dc4139 5487+ if (unlikely(err)) {
3c1bdaff 5488+ inode_unlock_shared(h_src_inode);
86dc4139
AM
5489+ goto out;
5490+ }
5491+ h_src_attr->valid = 1;
e2f27e51
AM
5492+ if (!au_test_nfs(h_src_inode->i_sb)) {
5493+ err = au_cp_regular(cpg);
3c1bdaff 5494+ inode_unlock_shared(h_src_inode);
e2f27e51 5495+ } else {
3c1bdaff 5496+ inode_unlock_shared(h_src_inode);
e2f27e51
AM
5497+ err = au_cp_regular(cpg);
5498+ }
c2b27bf2 5499+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
5500+ if (!err && rerr)
5501+ err = rerr;
1facf9fc 5502+ }
38d290e6
JR
5503+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
5504+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
5527c038 5505+ h_dst_inode = d_inode(h_path.dentry);
38d290e6
JR
5506+ spin_lock(&h_dst_inode->i_lock);
5507+ h_dst_inode->i_state |= I_LINKABLE;
5508+ spin_unlock(&h_dst_inode->i_lock);
5509+ }
1facf9fc 5510+
4f0767ce 5511+out:
1facf9fc 5512+ return err;
5513+}
5514+
5515+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
5516+ struct inode *h_dir)
5517+{
5518+ int err, symlen;
5519+ mm_segment_t old_fs;
b752ccd1
AM
5520+ union {
5521+ char *k;
5522+ char __user *u;
5523+ } sym;
1facf9fc 5524+
5525+ err = -ENOMEM;
537831f9 5526+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 5527+ if (unlikely(!sym.k))
1facf9fc 5528+ goto out;
5529+
9dbd164d 5530+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 5531+ old_fs = get_fs();
5532+ set_fs(KERNEL_DS);
a2654f78 5533+ symlen = vfs_readlink(h_src, sym.u, PATH_MAX);
1facf9fc 5534+ err = symlen;
5535+ set_fs(old_fs);
5536+
5537+ if (symlen > 0) {
b752ccd1
AM
5538+ sym.k[symlen] = 0;
5539+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 5540+ }
1c60b727 5541+ free_page((unsigned long)sym.k);
1facf9fc 5542+
4f0767ce 5543+out:
1facf9fc 5544+ return err;
5545+}
5546+
8cdd5066
JR
5547+/*
5548+ * regardless 'acl' option, reset all ACL.
5549+ * All ACL will be copied up later from the original entry on the lower branch.
5550+ */
5551+static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode)
5552+{
5553+ int err;
5554+ struct dentry *h_dentry;
5555+ struct inode *h_inode;
5556+
5557+ h_dentry = h_path->dentry;
5558+ h_inode = d_inode(h_dentry);
5559+ /* forget_all_cached_acls(h_inode)); */
5560+ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS);
5561+ AuTraceErr(err);
5562+ if (err == -EOPNOTSUPP)
5563+ err = 0;
5564+ if (!err)
5565+ err = vfsub_acl_chmod(h_inode, mode);
5566+
5567+ AuTraceErr(err);
5568+ return err;
5569+}
5570+
5571+static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent,
5572+ struct inode *h_dir, struct path *h_path)
5573+{
5574+ int err;
5575+ struct inode *dir, *inode;
5576+
5577+ err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT);
5578+ AuTraceErr(err);
5579+ if (err == -EOPNOTSUPP)
5580+ err = 0;
5581+ if (unlikely(err))
5582+ goto out;
5583+
5584+ /*
5585+ * strange behaviour from the users view,
acd2b654 5586+ * particularly setattr case
8cdd5066
JR
5587+ */
5588+ dir = d_inode(dst_parent);
5afbbe0d 5589+ if (au_ibtop(dir) == cpg->bdst)
8cdd5066
JR
5590+ au_cpup_attr_nlink(dir, /*force*/1);
5591+ inode = d_inode(cpg->dentry);
5592+ au_cpup_attr_nlink(inode, /*force*/1);
5593+
5594+out:
5595+ return err;
5596+}
5597+
1facf9fc 5598+static noinline_for_stack
c2b27bf2 5599+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 5600+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5601+{
5602+ int err;
5603+ umode_t mode;
5604+ unsigned int mnt_flags;
076b876e 5605+ unsigned char isdir, isreg, force;
c2b27bf2 5606+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5607+ struct au_dtime dt;
5608+ struct path h_path;
5609+ struct dentry *h_src, *h_dst, *h_parent;
8cdd5066 5610+ struct inode *h_inode, *h_dir;
1facf9fc 5611+ struct super_block *sb;
5612+
5613+ /* bsrc branch can be ro/rw. */
c2b27bf2 5614+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038
JR
5615+ h_inode = d_inode(h_src);
5616+ AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc));
1facf9fc 5617+
5618+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
5619+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
5620+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
5621+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
5622+ AUFS_WH_PFX_LEN));
1facf9fc 5623+ h_parent = h_dst->d_parent; /* dir inode is locked */
5527c038 5624+ h_dir = d_inode(h_parent);
1facf9fc 5625+ IMustLock(h_dir);
5626+ AuDebugOn(h_parent != h_dst->d_parent);
5627+
c2b27bf2
AM
5628+ sb = cpg->dentry->d_sb;
5629+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 5630+ if (do_dt) {
5631+ h_path.dentry = h_parent;
5632+ au_dtime_store(&dt, dst_parent, &h_path);
5633+ }
5634+ h_path.dentry = h_dst;
5635+
076b876e 5636+ isreg = 0;
1facf9fc 5637+ isdir = 0;
5638+ mode = h_inode->i_mode;
5639+ switch (mode & S_IFMT) {
5640+ case S_IFREG:
076b876e 5641+ isreg = 1;
cd7a4cd9 5642+ err = vfsub_create(h_dir, &h_path, 0600, /*want_excl*/true);
1facf9fc 5643+ if (!err)
c2b27bf2 5644+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 5645+ break;
5646+ case S_IFDIR:
5647+ isdir = 1;
5648+ err = vfsub_mkdir(h_dir, &h_path, mode);
8cdd5066
JR
5649+ if (!err)
5650+ err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path);
1facf9fc 5651+ break;
5652+ case S_IFLNK:
5653+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
5654+ break;
5655+ case S_IFCHR:
5656+ case S_IFBLK:
5657+ AuDebugOn(!capable(CAP_MKNOD));
5658+ /*FALLTHROUGH*/
5659+ case S_IFIFO:
5660+ case S_IFSOCK:
5661+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
5662+ break;
5663+ default:
5664+ AuIOErr("Unknown inode type 0%o\n", mode);
5665+ err = -EIO;
5666+ }
8cdd5066
JR
5667+ if (!err)
5668+ err = au_reset_acl(h_dir, &h_path, mode);
1facf9fc 5669+
5670+ mnt_flags = au_mntflags(sb);
5671+ if (!au_opt_test(mnt_flags, UDBA_NONE)
5672+ && !isdir
5673+ && au_opt_test(mnt_flags, XINO)
38d290e6
JR
5674+ && (h_inode->i_nlink == 1
5675+ || (h_inode->i_state & I_LINKABLE))
1facf9fc 5676+ /* todo: unnecessary? */
5527c038 5677+ /* && d_inode(cpg->dentry)->i_nlink == 1 */
c2b27bf2
AM
5678+ && cpg->bdst < cpg->bsrc
5679+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
5680+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 5681+ /* ignore this error */
5682+
076b876e
AM
5683+ if (!err) {
5684+ force = 0;
5685+ if (isreg) {
5686+ force = !!cpg->len;
5687+ if (cpg->len == -1)
5688+ force = !!i_size_read(h_inode);
5689+ }
5690+ au_fhsm_wrote(sb, cpg->bdst, force);
5691+ }
5692+
1facf9fc 5693+ if (do_dt)
5694+ au_dtime_revert(&dt);
5695+ return err;
5696+}
5697+
392086de 5698+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
5699+{
5700+ int err;
392086de 5701+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 5702+ struct inode *h_dir;
392086de 5703+ aufs_bindex_t bdst;
86dc4139 5704+
392086de
AM
5705+ dentry = cpg->dentry;
5706+ bdst = cpg->bdst;
5707+ h_dentry = au_h_dptr(dentry, bdst);
5708+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
5709+ dget(h_dentry);
5710+ au_set_h_dptr(dentry, bdst, NULL);
5711+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
5712+ if (!err)
5713+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 5714+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
5715+ } else {
5716+ err = 0;
5717+ parent = dget_parent(dentry);
5718+ h_parent = au_h_dptr(parent, bdst);
5719+ dput(parent);
5720+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
5721+ if (IS_ERR(h_path->dentry))
5722+ err = PTR_ERR(h_path->dentry);
86dc4139 5723+ }
392086de
AM
5724+ if (unlikely(err))
5725+ goto out;
86dc4139 5726+
86dc4139 5727+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5527c038 5728+ h_dir = d_inode(h_parent);
86dc4139 5729+ IMustLock(h_dir);
523b37e3
AM
5730+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
5731+ /* no delegation since it is just created */
f2c43d5f
AM
5732+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL,
5733+ /*flags*/0);
86dc4139
AM
5734+ dput(h_path->dentry);
5735+
5736+out:
5737+ return err;
5738+}
5739+
1facf9fc 5740+/*
5741+ * copyup the @dentry from @bsrc to @bdst.
5742+ * the caller must set the both of lower dentries.
5743+ * @len is for truncating when it is -1 copyup the entire file.
5744+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 5745+ * basic->bsrc can be larger than basic->bdst.
f2c43d5f 5746+ * aufs doesn't touch the credential so
acd2b654 5747+ * security_inode_copy_up{,_xattr}() are unnecessary.
1facf9fc 5748+ */
c2b27bf2 5749+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5750+{
5751+ int err, rerr;
5afbbe0d 5752+ aufs_bindex_t old_ibtop;
1facf9fc 5753+ unsigned char isdir, plink;
1facf9fc 5754+ struct dentry *h_src, *h_dst, *h_parent;
5527c038 5755+ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode;
1facf9fc 5756+ struct super_block *sb;
86dc4139 5757+ struct au_branch *br;
acd2b654 5758+ /* to reduce stack size */
c2b27bf2
AM
5759+ struct {
5760+ struct au_dtime dt;
5761+ struct path h_path;
5762+ struct au_cpup_reg_attr h_src_attr;
5763+ } *a;
1facf9fc 5764+
c2b27bf2
AM
5765+ err = -ENOMEM;
5766+ a = kmalloc(sizeof(*a), GFP_NOFS);
5767+ if (unlikely(!a))
5768+ goto out;
5769+ a->h_src_attr.valid = 0;
1facf9fc 5770+
c2b27bf2
AM
5771+ sb = cpg->dentry->d_sb;
5772+ br = au_sbr(sb, cpg->bdst);
5773+ a->h_path.mnt = au_br_mnt(br);
5774+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 5775+ h_parent = h_dst->d_parent; /* dir inode is locked */
5527c038 5776+ h_dir = d_inode(h_parent);
1facf9fc 5777+ IMustLock(h_dir);
5778+
c2b27bf2 5779+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038 5780+ inode = d_inode(cpg->dentry);
1facf9fc 5781+
5782+ if (!dst_parent)
c2b27bf2 5783+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 5784+ else
5785+ dget(dst_parent);
5786+
5787+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 5788+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 5789+ if (dst_inode) {
5790+ if (unlikely(!plink)) {
5791+ err = -EIO;
027c5e7a
AM
5792+ AuIOErr("hi%lu(i%lu) exists on b%d "
5793+ "but plink is disabled\n",
c2b27bf2
AM
5794+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
5795+ goto out_parent;
1facf9fc 5796+ }
5797+
5798+ if (dst_inode->i_nlink) {
c2b27bf2 5799+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5800+
c2b27bf2 5801+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 5802+ err = PTR_ERR(h_src);
5803+ if (IS_ERR(h_src))
c2b27bf2 5804+ goto out_parent;
5527c038 5805+ if (unlikely(d_is_negative(h_src))) {
1facf9fc 5806+ err = -EIO;
79b8bda9 5807+ AuIOErr("i%lu exists on b%d "
027c5e7a 5808+ "but not pseudo-linked\n",
79b8bda9 5809+ inode->i_ino, cpg->bdst);
1facf9fc 5810+ dput(h_src);
c2b27bf2 5811+ goto out_parent;
1facf9fc 5812+ }
5813+
5814+ if (do_dt) {
c2b27bf2
AM
5815+ a->h_path.dentry = h_parent;
5816+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 5817+ }
86dc4139 5818+
c2b27bf2 5819+ a->h_path.dentry = h_dst;
523b37e3
AM
5820+ delegated = NULL;
5821+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 5822+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 5823+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 5824+ if (do_dt)
c2b27bf2 5825+ au_dtime_revert(&a->dt);
523b37e3
AM
5826+ if (unlikely(err == -EWOULDBLOCK)) {
5827+ pr_warn("cannot retry for NFSv4 delegation"
5828+ " for an internal link\n");
5829+ iput(delegated);
5830+ }
1facf9fc 5831+ dput(h_src);
c2b27bf2 5832+ goto out_parent;
1facf9fc 5833+ } else
5834+ /* todo: cpup_wh_file? */
5835+ /* udba work */
4a4d8108 5836+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 5837+ }
5838+
86dc4139 5839+ isdir = S_ISDIR(inode->i_mode);
5afbbe0d 5840+ old_ibtop = au_ibtop(inode);
c2b27bf2 5841+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 5842+ if (unlikely(err))
86dc4139 5843+ goto out_rev;
5527c038 5844+ dst_inode = d_inode(h_dst);
febd17d6 5845+ inode_lock_nested(dst_inode, AuLsc_I_CHILD2);
86dc4139 5846+ /* todo: necessary? */
c2b27bf2 5847+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 5848+
c2b27bf2 5849+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
5850+ if (unlikely(err)) {
5851+ /* todo: necessary? */
c2b27bf2 5852+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
febd17d6 5853+ inode_unlock(dst_inode);
86dc4139
AM
5854+ goto out_rev;
5855+ }
5856+
5afbbe0d 5857+ if (cpg->bdst < old_ibtop) {
86dc4139 5858+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 5859+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 5860+ if (unlikely(err)) {
c2b27bf2
AM
5861+ /* ignore an error */
5862+ /* au_pin_hdir_relock(cpg->pin); */
febd17d6 5863+ inode_unlock(dst_inode);
86dc4139 5864+ goto out_rev;
4a4d8108 5865+ }
4a4d8108 5866+ }
5afbbe0d 5867+ au_set_ibtop(inode, cpg->bdst);
c2b27bf2 5868+ } else
5afbbe0d 5869+ au_set_ibbot(inode, cpg->bdst);
c2b27bf2 5870+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
5871+ au_hi_flags(inode, isdir));
5872+
5873+ /* todo: necessary? */
c2b27bf2 5874+ /* err = au_pin_hdir_relock(cpg->pin); */
febd17d6 5875+ inode_unlock(dst_inode);
86dc4139
AM
5876+ if (unlikely(err))
5877+ goto out_rev;
5878+
5527c038 5879+ src_inode = d_inode(h_src);
86dc4139 5880+ if (!isdir
5527c038
JR
5881+ && (src_inode->i_nlink > 1
5882+ || src_inode->i_state & I_LINKABLE)
86dc4139 5883+ && plink)
c2b27bf2 5884+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 5885+
c2b27bf2
AM
5886+ if (au_ftest_cpup(cpg->flags, RENAME)) {
5887+ a->h_path.dentry = h_dst;
392086de 5888+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
5889+ }
5890+ if (!err)
c2b27bf2 5891+ goto out_parent; /* success */
1facf9fc 5892+
5893+ /* revert */
4a4d8108 5894+out_rev:
c2b27bf2
AM
5895+ a->h_path.dentry = h_parent;
5896+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5897+ a->h_path.dentry = h_dst;
86dc4139 5898+ rerr = 0;
5527c038 5899+ if (d_is_positive(h_dst)) {
523b37e3
AM
5900+ if (!isdir) {
5901+ /* no delegation since it is just created */
5902+ rerr = vfsub_unlink(h_dir, &a->h_path,
5903+ /*delegated*/NULL, /*force*/0);
5904+ } else
c2b27bf2 5905+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 5906+ }
c2b27bf2 5907+ au_dtime_revert(&a->dt);
1facf9fc 5908+ if (rerr) {
5909+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
5910+ err = -EIO;
5911+ }
c2b27bf2 5912+out_parent:
1facf9fc 5913+ dput(dst_parent);
1c60b727 5914+ kfree(a);
c2b27bf2 5915+out:
1facf9fc 5916+ return err;
5917+}
5918+
7e9cd9fe 5919+#if 0 /* reserved */
1facf9fc 5920+struct au_cpup_single_args {
5921+ int *errp;
c2b27bf2 5922+ struct au_cp_generic *cpg;
1facf9fc 5923+ struct dentry *dst_parent;
5924+};
5925+
5926+static void au_call_cpup_single(void *args)
5927+{
5928+ struct au_cpup_single_args *a = args;
86dc4139 5929+
c2b27bf2
AM
5930+ au_pin_hdir_acquire_nest(a->cpg->pin);
5931+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
5932+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5933+}
c2b27bf2 5934+#endif
1facf9fc 5935+
53392da6
AM
5936+/*
5937+ * prevent SIGXFSZ in copy-up.
5938+ * testing CAP_MKNOD is for generic fs,
5939+ * but CAP_FSETID is for xfs only, currently.
5940+ */
86dc4139 5941+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
5942+{
5943+ int do_sio;
86dc4139
AM
5944+ struct super_block *sb;
5945+ struct inode *h_dir;
53392da6
AM
5946+
5947+ do_sio = 0;
86dc4139 5948+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
5949+ if (!au_wkq_test()
5950+ && (!au_sbi(sb)->si_plink_maint_pid
5951+ || au_plink_maint(sb, AuLock_NOPLM))) {
5952+ switch (mode & S_IFMT) {
5953+ case S_IFREG:
5954+ /* no condition about RLIMIT_FSIZE and the file size */
5955+ do_sio = 1;
5956+ break;
5957+ case S_IFCHR:
5958+ case S_IFBLK:
5959+ do_sio = !capable(CAP_MKNOD);
5960+ break;
5961+ }
5962+ if (!do_sio)
5963+ do_sio = ((mode & (S_ISUID | S_ISGID))
5964+ && !capable(CAP_FSETID));
86dc4139
AM
5965+ /* this workaround may be removed in the future */
5966+ if (!do_sio) {
5967+ h_dir = au_pinned_h_dir(pin);
5968+ do_sio = h_dir->i_mode & S_ISVTX;
5969+ }
53392da6
AM
5970+ }
5971+
5972+ return do_sio;
5973+}
5974+
7e9cd9fe 5975+#if 0 /* reserved */
c2b27bf2 5976+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5977+{
5978+ int err, wkq_err;
1facf9fc 5979+ struct dentry *h_dentry;
5980+
c2b27bf2 5981+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038 5982+ if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode))
c2b27bf2 5983+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 5984+ else {
5985+ struct au_cpup_single_args args = {
5986+ .errp = &err,
c2b27bf2
AM
5987+ .cpg = cpg,
5988+ .dst_parent = dst_parent
1facf9fc 5989+ };
5990+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
5991+ if (unlikely(wkq_err))
5992+ err = wkq_err;
5993+ }
5994+
5995+ return err;
5996+}
c2b27bf2 5997+#endif
1facf9fc 5998+
5999+/*
6000+ * copyup the @dentry from the first active lower branch to @bdst,
6001+ * using au_cpup_single().
6002+ */
c2b27bf2 6003+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 6004+{
6005+ int err;
c2b27bf2
AM
6006+ unsigned int flags_orig;
6007+ struct dentry *dentry;
6008+
6009+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 6010+
c2b27bf2 6011+ dentry = cpg->dentry;
86dc4139 6012+ DiMustWriteLock(dentry);
1facf9fc 6013+
c2b27bf2 6014+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 6015+ if (!err) {
c2b27bf2
AM
6016+ flags_orig = cpg->flags;
6017+ au_fset_cpup(cpg->flags, RENAME);
6018+ err = au_cpup_single(cpg, NULL);
6019+ cpg->flags = flags_orig;
1facf9fc 6020+ if (!err)
6021+ return 0; /* success */
6022+
6023+ /* revert */
c2b27bf2 6024+ au_set_h_dptr(dentry, cpg->bdst, NULL);
5afbbe0d 6025+ au_set_dbtop(dentry, cpg->bsrc);
1facf9fc 6026+ }
6027+
6028+ return err;
6029+}
6030+
6031+struct au_cpup_simple_args {
6032+ int *errp;
c2b27bf2 6033+ struct au_cp_generic *cpg;
1facf9fc 6034+};
6035+
6036+static void au_call_cpup_simple(void *args)
6037+{
6038+ struct au_cpup_simple_args *a = args;
86dc4139 6039+
c2b27bf2
AM
6040+ au_pin_hdir_acquire_nest(a->cpg->pin);
6041+ *a->errp = au_cpup_simple(a->cpg);
6042+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 6043+}
6044+
c2b27bf2 6045+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 6046+{
6047+ int err, wkq_err;
c2b27bf2
AM
6048+ struct dentry *dentry, *parent;
6049+ struct file *h_file;
1facf9fc 6050+ struct inode *h_dir;
6051+
c2b27bf2
AM
6052+ dentry = cpg->dentry;
6053+ h_file = NULL;
6054+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
6055+ AuDebugOn(cpg->bsrc < 0);
392086de 6056+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
6057+ err = PTR_ERR(h_file);
6058+ if (IS_ERR(h_file))
6059+ goto out;
6060+ }
6061+
1facf9fc 6062+ parent = dget_parent(dentry);
5527c038 6063+ h_dir = au_h_iptr(d_inode(parent), cpg->bdst);
53392da6 6064+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
5527c038 6065+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
c2b27bf2 6066+ err = au_cpup_simple(cpg);
1facf9fc 6067+ else {
6068+ struct au_cpup_simple_args args = {
6069+ .errp = &err,
c2b27bf2 6070+ .cpg = cpg
1facf9fc 6071+ };
6072+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
6073+ if (unlikely(wkq_err))
6074+ err = wkq_err;
6075+ }
6076+
6077+ dput(parent);
c2b27bf2
AM
6078+ if (h_file)
6079+ au_h_open_post(dentry, cpg->bsrc, h_file);
6080+
6081+out:
1facf9fc 6082+ return err;
6083+}
6084+
c2b27bf2 6085+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 6086+{
5afbbe0d 6087+ aufs_bindex_t bsrc, bbot;
c2b27bf2 6088+ struct dentry *dentry, *h_dentry;
367653fa 6089+
c2b27bf2
AM
6090+ if (cpg->bsrc < 0) {
6091+ dentry = cpg->dentry;
5afbbe0d
AM
6092+ bbot = au_dbbot(dentry);
6093+ for (bsrc = cpg->bdst + 1; bsrc <= bbot; bsrc++) {
c2b27bf2
AM
6094+ h_dentry = au_h_dptr(dentry, bsrc);
6095+ if (h_dentry) {
5527c038 6096+ AuDebugOn(d_is_negative(h_dentry));
c2b27bf2
AM
6097+ break;
6098+ }
6099+ }
5afbbe0d 6100+ AuDebugOn(bsrc > bbot);
c2b27bf2 6101+ cpg->bsrc = bsrc;
367653fa 6102+ }
c2b27bf2
AM
6103+ AuDebugOn(cpg->bsrc <= cpg->bdst);
6104+ return au_do_sio_cpup_simple(cpg);
6105+}
367653fa 6106+
c2b27bf2
AM
6107+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
6108+{
6109+ AuDebugOn(cpg->bdst <= cpg->bsrc);
6110+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
6111+}
6112+
1facf9fc 6113+/* ---------------------------------------------------------------------- */
6114+
6115+/*
6116+ * copyup the deleted file for writing.
6117+ */
c2b27bf2
AM
6118+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
6119+ struct file *file)
1facf9fc 6120+{
6121+ int err;
c2b27bf2
AM
6122+ unsigned int flags_orig;
6123+ aufs_bindex_t bsrc_orig;
c2b27bf2 6124+ struct au_dinfo *dinfo;
5afbbe0d
AM
6125+ struct {
6126+ struct au_hdentry *hd;
6127+ struct dentry *h_dentry;
6128+ } hdst, hsrc;
1facf9fc 6129+
c2b27bf2 6130+ dinfo = au_di(cpg->dentry);
1308ab2a 6131+ AuRwMustWriteLock(&dinfo->di_rwsem);
6132+
c2b27bf2 6133+ bsrc_orig = cpg->bsrc;
5afbbe0d
AM
6134+ cpg->bsrc = dinfo->di_btop;
6135+ hdst.hd = au_hdentry(dinfo, cpg->bdst);
6136+ hdst.h_dentry = hdst.hd->hd_dentry;
6137+ hdst.hd->hd_dentry = wh_dentry;
6138+ dinfo->di_btop = cpg->bdst;
6139+
6140+ hsrc.h_dentry = NULL;
027c5e7a 6141+ if (file) {
5afbbe0d
AM
6142+ hsrc.hd = au_hdentry(dinfo, cpg->bsrc);
6143+ hsrc.h_dentry = hsrc.hd->hd_dentry;
6144+ hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry;
027c5e7a 6145+ }
c2b27bf2
AM
6146+ flags_orig = cpg->flags;
6147+ cpg->flags = !AuCpup_DTIME;
6148+ err = au_cpup_single(cpg, /*h_parent*/NULL);
6149+ cpg->flags = flags_orig;
027c5e7a
AM
6150+ if (file) {
6151+ if (!err)
6152+ err = au_reopen_nondir(file);
5afbbe0d 6153+ hsrc.hd->hd_dentry = hsrc.h_dentry;
1facf9fc 6154+ }
5afbbe0d
AM
6155+ hdst.hd->hd_dentry = hdst.h_dentry;
6156+ dinfo->di_btop = cpg->bsrc;
c2b27bf2 6157+ cpg->bsrc = bsrc_orig;
1facf9fc 6158+
6159+ return err;
6160+}
6161+
c2b27bf2 6162+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 6163+{
6164+ int err;
c2b27bf2 6165+ aufs_bindex_t bdst;
1facf9fc 6166+ struct au_dtime dt;
c2b27bf2 6167+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 6168+ struct au_branch *br;
6169+ struct path h_path;
6170+
c2b27bf2
AM
6171+ dentry = cpg->dentry;
6172+ bdst = cpg->bdst;
1facf9fc 6173+ br = au_sbr(dentry->d_sb, bdst);
6174+ parent = dget_parent(dentry);
6175+ h_parent = au_h_dptr(parent, bdst);
6176+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
6177+ err = PTR_ERR(wh_dentry);
6178+ if (IS_ERR(wh_dentry))
6179+ goto out;
6180+
6181+ h_path.dentry = h_parent;
86dc4139 6182+ h_path.mnt = au_br_mnt(br);
1facf9fc 6183+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 6184+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 6185+ if (unlikely(err))
6186+ goto out_wh;
6187+
6188+ dget(wh_dentry);
6189+ h_path.dentry = wh_dentry;
2000de60 6190+ if (!d_is_dir(wh_dentry)) {
523b37e3 6191+ /* no delegation since it is just created */
5527c038 6192+ err = vfsub_unlink(d_inode(h_parent), &h_path,
523b37e3
AM
6193+ /*delegated*/NULL, /*force*/0);
6194+ } else
5527c038 6195+ err = vfsub_rmdir(d_inode(h_parent), &h_path);
1facf9fc 6196+ if (unlikely(err)) {
523b37e3
AM
6197+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
6198+ wh_dentry, err);
1facf9fc 6199+ err = -EIO;
6200+ }
6201+ au_dtime_revert(&dt);
5527c038 6202+ au_set_hi_wh(d_inode(dentry), bdst, wh_dentry);
1facf9fc 6203+
4f0767ce 6204+out_wh:
1facf9fc 6205+ dput(wh_dentry);
4f0767ce 6206+out:
1facf9fc 6207+ dput(parent);
6208+ return err;
6209+}
6210+
6211+struct au_cpup_wh_args {
6212+ int *errp;
c2b27bf2 6213+ struct au_cp_generic *cpg;
1facf9fc 6214+ struct file *file;
6215+};
6216+
6217+static void au_call_cpup_wh(void *args)
6218+{
6219+ struct au_cpup_wh_args *a = args;
86dc4139 6220+
c2b27bf2
AM
6221+ au_pin_hdir_acquire_nest(a->cpg->pin);
6222+ *a->errp = au_cpup_wh(a->cpg, a->file);
6223+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 6224+}
6225+
c2b27bf2 6226+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 6227+{
6228+ int err, wkq_err;
c2b27bf2 6229+ aufs_bindex_t bdst;
c1595e42 6230+ struct dentry *dentry, *parent, *h_orph, *h_parent;
86dc4139 6231+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 6232+ struct au_wbr *wbr;
c2b27bf2 6233+ struct au_pin wh_pin, *pin_orig;
1facf9fc 6234+
c2b27bf2
AM
6235+ dentry = cpg->dentry;
6236+ bdst = cpg->bdst;
1facf9fc 6237+ parent = dget_parent(dentry);
5527c038 6238+ dir = d_inode(parent);
1facf9fc 6239+ h_orph = NULL;
6240+ h_parent = NULL;
6241+ h_dir = au_igrab(au_h_iptr(dir, bdst));
6242+ h_tmpdir = h_dir;
c2b27bf2 6243+ pin_orig = NULL;
1facf9fc 6244+ if (!h_dir->i_nlink) {
6245+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
6246+ h_orph = wbr->wbr_orph;
6247+
6248+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 6249+ au_set_h_dptr(parent, bdst, dget(h_orph));
5527c038 6250+ h_tmpdir = d_inode(h_orph);
1facf9fc 6251+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
6252+
febd17d6 6253+ inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3);
4a4d8108 6254+ /* todo: au_h_open_pre()? */
86dc4139 6255+
c2b27bf2 6256+ pin_orig = cpg->pin;
86dc4139 6257+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
6258+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
6259+ cpg->pin = &wh_pin;
1facf9fc 6260+ }
6261+
53392da6 6262+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
5527c038 6263+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
c2b27bf2 6264+ err = au_cpup_wh(cpg, file);
1facf9fc 6265+ else {
6266+ struct au_cpup_wh_args args = {
6267+ .errp = &err,
c2b27bf2
AM
6268+ .cpg = cpg,
6269+ .file = file
1facf9fc 6270+ };
6271+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
6272+ if (unlikely(wkq_err))
6273+ err = wkq_err;
6274+ }
6275+
6276+ if (h_orph) {
febd17d6 6277+ inode_unlock(h_tmpdir);
4a4d8108 6278+ /* todo: au_h_open_post()? */
1facf9fc 6279+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 6280+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
6281+ AuDebugOn(!pin_orig);
6282+ cpg->pin = pin_orig;
1facf9fc 6283+ }
6284+ iput(h_dir);
6285+ dput(parent);
6286+
6287+ return err;
6288+}
6289+
6290+/* ---------------------------------------------------------------------- */
6291+
6292+/*
6293+ * generic routine for both of copy-up and copy-down.
6294+ */
6295+/* cf. revalidate function in file.c */
6296+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
6297+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6298+ struct au_pin *pin,
1facf9fc 6299+ struct dentry *h_parent, void *arg),
6300+ void *arg)
6301+{
6302+ int err;
6303+ struct au_pin pin;
5527c038 6304+ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry;
1facf9fc 6305+
6306+ err = 0;
6307+ parent = dget_parent(dentry);
6308+ if (IS_ROOT(parent))
6309+ goto out;
6310+
6311+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
6312+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
6313+
6314+ /* do not use au_dpage */
6315+ real_parent = parent;
6316+ while (1) {
6317+ dput(parent);
6318+ parent = dget_parent(dentry);
6319+ h_parent = au_h_dptr(parent, bdst);
6320+ if (h_parent)
6321+ goto out; /* success */
6322+
6323+ /* find top dir which is necessary to cpup */
6324+ do {
6325+ d = parent;
6326+ dput(parent);
6327+ parent = dget_parent(d);
6328+ di_read_lock_parent3(parent, !AuLock_IR);
6329+ h_parent = au_h_dptr(parent, bdst);
6330+ di_read_unlock(parent, !AuLock_IR);
6331+ } while (!h_parent);
6332+
6333+ if (d != real_parent)
6334+ di_write_lock_child3(d);
6335+
6336+ /* somebody else might create while we were sleeping */
5527c038
JR
6337+ h_dentry = au_h_dptr(d, bdst);
6338+ if (!h_dentry || d_is_negative(h_dentry)) {
6339+ if (h_dentry)
5afbbe0d 6340+ au_update_dbtop(d);
1facf9fc 6341+
6342+ au_pin_set_dentry(&pin, d);
6343+ err = au_do_pin(&pin);
6344+ if (!err) {
86dc4139 6345+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 6346+ au_unpin(&pin);
6347+ }
6348+ }
6349+
6350+ if (d != real_parent)
6351+ di_write_unlock(d);
6352+ if (unlikely(err))
6353+ break;
6354+ }
6355+
4f0767ce 6356+out:
1facf9fc 6357+ dput(parent);
6358+ return err;
6359+}
6360+
6361+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6362+ struct au_pin *pin,
2000de60 6363+ struct dentry *h_parent __maybe_unused,
1facf9fc 6364+ void *arg __maybe_unused)
6365+{
c2b27bf2
AM
6366+ struct au_cp_generic cpg = {
6367+ .dentry = dentry,
6368+ .bdst = bdst,
6369+ .bsrc = -1,
6370+ .len = 0,
6371+ .pin = pin,
6372+ .flags = AuCpup_DTIME
6373+ };
6374+ return au_sio_cpup_simple(&cpg);
1facf9fc 6375+}
6376+
6377+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
6378+{
6379+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
6380+}
6381+
6382+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
6383+{
6384+ int err;
6385+ struct dentry *parent;
6386+ struct inode *dir;
6387+
6388+ parent = dget_parent(dentry);
5527c038 6389+ dir = d_inode(parent);
1facf9fc 6390+ err = 0;
6391+ if (au_h_iptr(dir, bdst))
6392+ goto out;
6393+
6394+ di_read_unlock(parent, AuLock_IR);
6395+ di_write_lock_parent(parent);
6396+ /* someone else might change our inode while we were sleeping */
6397+ if (!au_h_iptr(dir, bdst))
6398+ err = au_cpup_dirs(dentry, bdst);
6399+ di_downgrade_lock(parent, AuLock_IR);
6400+
4f0767ce 6401+out:
1facf9fc 6402+ dput(parent);
6403+ return err;
6404+}
7f207e10
AM
6405diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
6406--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 6407+++ linux/fs/aufs/cpup.h 2018-08-12 23:43:05.453457863 +0200
062440b3
AM
6408@@ -0,0 +1,100 @@
6409+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 6410+/*
b00004a5 6411+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 6412+ *
6413+ * This program, aufs is free software; you can redistribute it and/or modify
6414+ * it under the terms of the GNU General Public License as published by
6415+ * the Free Software Foundation; either version 2 of the License, or
6416+ * (at your option) any later version.
dece6358
AM
6417+ *
6418+ * This program is distributed in the hope that it will be useful,
6419+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6420+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6421+ * GNU General Public License for more details.
6422+ *
6423+ * You should have received a copy of the GNU General Public License
523b37e3 6424+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6425+ */
6426+
6427+/*
6428+ * copy-up/down functions
6429+ */
6430+
6431+#ifndef __AUFS_CPUP_H__
6432+#define __AUFS_CPUP_H__
6433+
6434+#ifdef __KERNEL__
6435+
dece6358 6436+#include <linux/path.h>
1facf9fc 6437+
dece6358
AM
6438+struct inode;
6439+struct file;
86dc4139 6440+struct au_pin;
dece6358 6441+
86dc4139 6442+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 6443+void au_cpup_attr_timesizes(struct inode *inode);
6444+void au_cpup_attr_nlink(struct inode *inode, int force);
6445+void au_cpup_attr_changeable(struct inode *inode);
6446+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
6447+void au_cpup_attr_all(struct inode *inode, int force);
6448+
6449+/* ---------------------------------------------------------------------- */
6450+
c2b27bf2
AM
6451+struct au_cp_generic {
6452+ struct dentry *dentry;
6453+ aufs_bindex_t bdst, bsrc;
6454+ loff_t len;
6455+ struct au_pin *pin;
6456+ unsigned int flags;
6457+};
6458+
1facf9fc 6459+/* cpup flags */
392086de
AM
6460+#define AuCpup_DTIME 1 /* do dtime_store/revert */
6461+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
6462+ for link(2) */
6463+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
6464+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
6465+ cpup */
6466+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
6467+ existing entry */
6468+#define AuCpup_RWDST (1 << 5) /* force write target even if
6469+ the branch is marked as RO */
c2b27bf2 6470+
8b6a4947
AM
6471+#ifndef CONFIG_AUFS_BR_HFSPLUS
6472+#undef AuCpup_HOPEN
6473+#define AuCpup_HOPEN 0
6474+#endif
6475+
1facf9fc 6476+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
6477+#define au_fset_cpup(flags, name) \
6478+ do { (flags) |= AuCpup_##name; } while (0)
6479+#define au_fclr_cpup(flags, name) \
6480+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 6481+
6482+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
6483+int au_sio_cpup_simple(struct au_cp_generic *cpg);
6484+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
6485+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 6486+
6487+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
6488+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6489+ struct au_pin *pin,
1facf9fc 6490+ struct dentry *h_parent, void *arg),
6491+ void *arg);
6492+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
6493+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
6494+
6495+/* ---------------------------------------------------------------------- */
6496+
6497+/* keep timestamps when copyup */
6498+struct au_dtime {
6499+ struct dentry *dt_dentry;
6500+ struct path dt_h_path;
cd7a4cd9 6501+ struct timespec64 dt_atime, dt_mtime;
1facf9fc 6502+};
6503+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
6504+ struct path *h_path);
6505+void au_dtime_revert(struct au_dtime *dt);
6506+
6507+#endif /* __KERNEL__ */
6508+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
6509diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
6510--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
6511+++ linux/fs/aufs/dbgaufs.c 2018-10-23 12:33:35.596042364 +0200
6512@@ -0,0 +1,519 @@
cd7a4cd9 6513+// SPDX-License-Identifier: GPL-2.0
1facf9fc 6514+/*
b00004a5 6515+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 6516+ *
6517+ * This program, aufs is free software; you can redistribute it and/or modify
6518+ * it under the terms of the GNU General Public License as published by
6519+ * the Free Software Foundation; either version 2 of the License, or
6520+ * (at your option) any later version.
dece6358
AM
6521+ *
6522+ * This program is distributed in the hope that it will be useful,
6523+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6524+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6525+ * GNU General Public License for more details.
6526+ *
6527+ * You should have received a copy of the GNU General Public License
523b37e3 6528+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6529+ */
6530+
6531+/*
6532+ * debugfs interface
6533+ */
6534+
6535+#include <linux/debugfs.h>
6536+#include "aufs.h"
6537+
6538+#ifndef CONFIG_SYSFS
6539+#error DEBUG_FS depends upon SYSFS
6540+#endif
6541+
6542+static struct dentry *dbgaufs;
cd7a4cd9 6543+static const mode_t dbgaufs_mode = 0444;
1facf9fc 6544+
6545+/* 20 is max digits length of ulong 64 */
6546+struct dbgaufs_arg {
6547+ int n;
6548+ char a[20 * 4];
6549+};
6550+
6551+/*
6552+ * common function for all XINO files
6553+ */
6554+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
6555+ struct file *file)
6556+{
1c60b727 6557+ kfree(file->private_data);
1facf9fc 6558+ return 0;
6559+}
6560+
062440b3
AM
6561+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt,
6562+ int cnt)
1facf9fc 6563+{
6564+ int err;
6565+ struct kstat st;
6566+ struct dbgaufs_arg *p;
6567+
6568+ err = -ENOMEM;
6569+ p = kmalloc(sizeof(*p), GFP_NOFS);
6570+ if (unlikely(!p))
6571+ goto out;
6572+
6573+ err = 0;
6574+ p->n = 0;
6575+ file->private_data = p;
6576+ if (!xf)
6577+ goto out;
6578+
521ced18 6579+ err = vfsub_getattr(&xf->f_path, &st);
1facf9fc 6580+ if (!err) {
6581+ if (do_fcnt)
6582+ p->n = snprintf
062440b3
AM
6583+ (p->a, sizeof(p->a), "%d, %llux%u %lld\n",
6584+ cnt, st.blocks, st.blksize,
1facf9fc 6585+ (long long)st.size);
6586+ else
521ced18 6587+ p->n = snprintf(p->a, sizeof(p->a), "%llux%u %lld\n",
1facf9fc 6588+ st.blocks, st.blksize,
6589+ (long long)st.size);
6590+ AuDebugOn(p->n >= sizeof(p->a));
6591+ } else {
6592+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
6593+ err = 0;
6594+ }
6595+
4f0767ce 6596+out:
1facf9fc 6597+ return err;
1facf9fc 6598+}
6599+
6600+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
6601+ size_t count, loff_t *ppos)
6602+{
6603+ struct dbgaufs_arg *p;
6604+
6605+ p = file->private_data;
6606+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6607+}
6608+
6609+/* ---------------------------------------------------------------------- */
6610+
86dc4139
AM
6611+struct dbgaufs_plink_arg {
6612+ int n;
6613+ char a[];
6614+};
6615+
6616+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
6617+ struct file *file)
6618+{
1c60b727 6619+ free_page((unsigned long)file->private_data);
86dc4139
AM
6620+ return 0;
6621+}
6622+
6623+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
6624+{
6625+ int err, i, limit;
6626+ unsigned long n, sum;
6627+ struct dbgaufs_plink_arg *p;
6628+ struct au_sbinfo *sbinfo;
6629+ struct super_block *sb;
8b6a4947 6630+ struct hlist_bl_head *hbl;
86dc4139
AM
6631+
6632+ err = -ENOMEM;
6633+ p = (void *)get_zeroed_page(GFP_NOFS);
6634+ if (unlikely(!p))
6635+ goto out;
6636+
6637+ err = -EFBIG;
6638+ sbinfo = inode->i_private;
6639+ sb = sbinfo->si_sb;
6640+ si_noflush_read_lock(sb);
6641+ if (au_opt_test(au_mntflags(sb), PLINK)) {
6642+ limit = PAGE_SIZE - sizeof(p->n);
6643+
6644+ /* the number of buckets */
6645+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
6646+ p->n += n;
6647+ limit -= n;
6648+
6649+ sum = 0;
8b6a4947
AM
6650+ for (i = 0, hbl = sbinfo->si_plink; i < AuPlink_NHASH;
6651+ i++, hbl++) {
6652+ n = au_hbl_count(hbl);
86dc4139
AM
6653+ sum += n;
6654+
6655+ n = snprintf(p->a + p->n, limit, "%lu ", n);
6656+ p->n += n;
6657+ limit -= n;
6658+ if (unlikely(limit <= 0))
6659+ goto out_free;
6660+ }
6661+ p->a[p->n - 1] = '\n';
6662+
6663+ /* the sum of plinks */
6664+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
6665+ p->n += n;
6666+ limit -= n;
6667+ if (unlikely(limit <= 0))
6668+ goto out_free;
6669+ } else {
6670+#define str "1\n0\n0\n"
6671+ p->n = sizeof(str) - 1;
6672+ strcpy(p->a, str);
6673+#undef str
6674+ }
6675+ si_read_unlock(sb);
6676+
6677+ err = 0;
6678+ file->private_data = p;
6679+ goto out; /* success */
6680+
6681+out_free:
1c60b727 6682+ free_page((unsigned long)p);
86dc4139
AM
6683+out:
6684+ return err;
6685+}
6686+
6687+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
6688+ size_t count, loff_t *ppos)
6689+{
6690+ struct dbgaufs_plink_arg *p;
6691+
6692+ p = file->private_data;
6693+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6694+}
6695+
6696+static const struct file_operations dbgaufs_plink_fop = {
6697+ .owner = THIS_MODULE,
6698+ .open = dbgaufs_plink_open,
6699+ .release = dbgaufs_plink_release,
6700+ .read = dbgaufs_plink_read
6701+};
6702+
6703+/* ---------------------------------------------------------------------- */
6704+
1facf9fc 6705+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
6706+{
6707+ int err;
6708+ struct au_sbinfo *sbinfo;
6709+ struct super_block *sb;
6710+
6711+ sbinfo = inode->i_private;
6712+ sb = sbinfo->si_sb;
6713+ si_noflush_read_lock(sb);
062440b3 6714+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0, /*cnt*/0);
1facf9fc 6715+ si_read_unlock(sb);
6716+ return err;
6717+}
6718+
6719+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 6720+ .owner = THIS_MODULE,
1facf9fc 6721+ .open = dbgaufs_xib_open,
6722+ .release = dbgaufs_xi_release,
6723+ .read = dbgaufs_xi_read
6724+};
6725+
6726+/* ---------------------------------------------------------------------- */
6727+
6728+#define DbgaufsXi_PREFIX "xi"
6729+
6730+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
6731+{
acd2b654 6732+ int err, idx;
1facf9fc 6733+ long l;
acd2b654
AM
6734+ aufs_bindex_t bindex;
6735+ char *p, a[sizeof(DbgaufsXi_PREFIX) + 8];
1facf9fc 6736+ struct au_sbinfo *sbinfo;
6737+ struct super_block *sb;
acd2b654 6738+ struct au_xino *xi;
1facf9fc 6739+ struct file *xf;
6740+ struct qstr *name;
062440b3 6741+ struct au_branch *br;
1facf9fc 6742+
6743+ err = -ENOENT;
2000de60 6744+ name = &file->f_path.dentry->d_name;
1facf9fc 6745+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
6746+ || memcmp(name->name, DbgaufsXi_PREFIX,
6747+ sizeof(DbgaufsXi_PREFIX) - 1)))
6748+ goto out;
acd2b654
AM
6749+
6750+ AuDebugOn(name->len >= sizeof(a));
6751+ memcpy(a, name->name, name->len);
6752+ a[name->len] = '\0';
6753+ p = strchr(a, '-');
6754+ if (p)
6755+ *p = '\0';
6756+ err = kstrtol(a + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 6757+ if (unlikely(err))
6758+ goto out;
acd2b654
AM
6759+ bindex = l;
6760+ idx = 0;
6761+ if (p) {
6762+ err = kstrtol(p + 1, 10, &l);
6763+ if (unlikely(err))
6764+ goto out;
6765+ idx = l;
6766+ }
1facf9fc 6767+
acd2b654 6768+ err = -ENOENT;
1facf9fc 6769+ sbinfo = inode->i_private;
6770+ sb = sbinfo->si_sb;
6771+ si_noflush_read_lock(sb);
acd2b654
AM
6772+ if (unlikely(bindex < 0 || bindex > au_sbbot(sb)))
6773+ goto out_si;
6774+ br = au_sbr(sb, bindex);
6775+ xi = br->br_xino;
6776+ if (unlikely(idx >= xi->xi_nfile))
6777+ goto out_si;
6778+ xf = au_xino_file(xi, idx);
6779+ if (xf)
062440b3
AM
6780+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1,
6781+ au_xino_count(br));
1facf9fc 6782+
acd2b654
AM
6783+out_si:
6784+ si_read_unlock(sb);
4f0767ce 6785+out:
acd2b654 6786+ AuTraceErr(err);
1facf9fc 6787+ return err;
6788+}
6789+
6790+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 6791+ .owner = THIS_MODULE,
1facf9fc 6792+ .open = dbgaufs_xino_open,
6793+ .release = dbgaufs_xi_release,
6794+ .read = dbgaufs_xi_read
6795+};
6796+
062440b3
AM
6797+void dbgaufs_xino_del(struct au_branch *br)
6798+{
6799+ struct dentry *dbgaufs;
6800+
6801+ dbgaufs = br->br_dbgaufs;
6802+ if (!dbgaufs)
6803+ return;
6804+
6805+ br->br_dbgaufs = NULL;
6806+ /* debugfs acquires the parent i_mutex */
6807+ lockdep_off();
6808+ debugfs_remove(dbgaufs);
6809+ lockdep_on();
6810+}
6811+
1facf9fc 6812+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
6813+{
5afbbe0d 6814+ aufs_bindex_t bbot;
1facf9fc 6815+ struct au_branch *br;
1facf9fc 6816+
6817+ if (!au_sbi(sb)->si_dbgaufs)
6818+ return;
6819+
5afbbe0d
AM
6820+ bbot = au_sbbot(sb);
6821+ for (; bindex <= bbot; bindex++) {
1facf9fc 6822+ br = au_sbr(sb, bindex);
062440b3
AM
6823+ dbgaufs_xino_del(br);
6824+ }
6825+}
6826+
acd2b654
AM
6827+static void dbgaufs_br_do_add(struct super_block *sb, aufs_bindex_t bindex,
6828+ unsigned int idx, struct dentry *parent,
6829+ struct au_sbinfo *sbinfo)
062440b3
AM
6830+{
6831+ struct au_branch *br;
6832+ struct dentry *d;
acd2b654
AM
6833+ /* "xi" bindex(5) "-" idx(2) NULL */
6834+ char name[sizeof(DbgaufsXi_PREFIX) + 8];
062440b3 6835+
acd2b654
AM
6836+ if (!idx)
6837+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
6838+ else
6839+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d-%u",
6840+ bindex, idx);
062440b3
AM
6841+ br = au_sbr(sb, bindex);
6842+ if (br->br_dbgaufs) {
6843+ struct qstr qstr = QSTR_INIT(name, strlen(name));
6844+
6845+ if (!au_qstreq(&br->br_dbgaufs->d_name, &qstr)) {
6846+ /* debugfs acquires the parent i_mutex */
6847+ lockdep_off();
6848+ d = debugfs_rename(parent, br->br_dbgaufs, parent,
6849+ name);
6850+ lockdep_on();
6851+ if (unlikely(!d))
6852+ pr_warn("failed renaming %pd/%s, ignored.\n",
6853+ parent, name);
6854+ }
6855+ } else {
e2f27e51 6856+ lockdep_off();
062440b3
AM
6857+ br->br_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
6858+ sbinfo, &dbgaufs_xino_fop);
e2f27e51 6859+ lockdep_on();
062440b3 6860+ if (unlikely(!br->br_dbgaufs))
acd2b654 6861+ pr_warn("failed creating %pd/%s, ignored.\n",
062440b3 6862+ parent, name);
1facf9fc 6863+ }
6864+}
6865+
acd2b654
AM
6866+static void dbgaufs_br_add(struct super_block *sb, aufs_bindex_t bindex,
6867+ struct dentry *parent, struct au_sbinfo *sbinfo)
6868+{
6869+ struct au_branch *br;
6870+ struct au_xino *xi;
6871+ unsigned int u;
6872+
6873+ br = au_sbr(sb, bindex);
6874+ xi = br->br_xino;
6875+ for (u = 0; u < xi->xi_nfile; u++)
6876+ dbgaufs_br_do_add(sb, bindex, u, parent, sbinfo);
6877+}
6878+
062440b3 6879+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown)
1facf9fc 6880+{
6881+ struct au_sbinfo *sbinfo;
6882+ struct dentry *parent;
5afbbe0d 6883+ aufs_bindex_t bbot;
062440b3
AM
6884+
6885+ if (!au_opt_test(au_mntflags(sb), XINO))
6886+ return;
1facf9fc 6887+
6888+ sbinfo = au_sbi(sb);
6889+ parent = sbinfo->si_dbgaufs;
6890+ if (!parent)
6891+ return;
6892+
5afbbe0d 6893+ bbot = au_sbbot(sb);
062440b3
AM
6894+ if (topdown)
6895+ for (; bindex <= bbot; bindex++)
6896+ dbgaufs_br_add(sb, bindex, parent, sbinfo);
6897+ else
6898+ for (; bbot >= bindex; bbot--)
6899+ dbgaufs_br_add(sb, bbot, parent, sbinfo);
1facf9fc 6900+}
6901+
6902+/* ---------------------------------------------------------------------- */
6903+
6904+#ifdef CONFIG_AUFS_EXPORT
6905+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
6906+{
6907+ int err;
6908+ struct au_sbinfo *sbinfo;
6909+ struct super_block *sb;
6910+
6911+ sbinfo = inode->i_private;
6912+ sb = sbinfo->si_sb;
6913+ si_noflush_read_lock(sb);
062440b3 6914+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0, /*cnt*/0);
1facf9fc 6915+ si_read_unlock(sb);
6916+ return err;
6917+}
6918+
6919+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 6920+ .owner = THIS_MODULE,
1facf9fc 6921+ .open = dbgaufs_xigen_open,
6922+ .release = dbgaufs_xi_release,
6923+ .read = dbgaufs_xi_read
6924+};
6925+
6926+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6927+{
6928+ int err;
6929+
dece6358 6930+ /*
c1595e42 6931+ * This function is a dynamic '__init' function actually,
dece6358
AM
6932+ * so the tiny check for si_rwsem is unnecessary.
6933+ */
6934+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6935+
1facf9fc 6936+ err = -EIO;
6937+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
6938+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6939+ &dbgaufs_xigen_fop);
6940+ if (sbinfo->si_dbgaufs_xigen)
6941+ err = 0;
6942+
6943+ return err;
6944+}
6945+#else
6946+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6947+{
6948+ return 0;
6949+}
6950+#endif /* CONFIG_AUFS_EXPORT */
6951+
6952+/* ---------------------------------------------------------------------- */
6953+
6954+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
6955+{
dece6358 6956+ /*
7e9cd9fe 6957+ * This function is a dynamic '__fin' function actually,
dece6358
AM
6958+ * so the tiny check for si_rwsem is unnecessary.
6959+ */
6960+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6961+
1facf9fc 6962+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
6963+ sbinfo->si_dbgaufs = NULL;
1facf9fc 6964+}
6965+
6966+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
6967+{
6968+ int err;
6969+ char name[SysaufsSiNameLen];
6970+
dece6358 6971+ /*
c1595e42 6972+ * This function is a dynamic '__init' function actually,
dece6358
AM
6973+ * so the tiny check for si_rwsem is unnecessary.
6974+ */
6975+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6976+
1facf9fc 6977+ err = -ENOENT;
6978+ if (!dbgaufs) {
6979+ AuErr1("/debug/aufs is uninitialized\n");
6980+ goto out;
6981+ }
6982+
6983+ err = -EIO;
6984+ sysaufs_name(sbinfo, name);
6985+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
6986+ if (unlikely(!sbinfo->si_dbgaufs))
6987+ goto out;
1facf9fc 6988+
062440b3 6989+ /* regardless plink/noplink option */
86dc4139
AM
6990+ sbinfo->si_dbgaufs_plink = debugfs_create_file
6991+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6992+ &dbgaufs_plink_fop);
6993+ if (unlikely(!sbinfo->si_dbgaufs_plink))
6994+ goto out_dir;
6995+
062440b3
AM
6996+ /* regardless xino/noxino option */
6997+ sbinfo->si_dbgaufs_xib = debugfs_create_file
6998+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6999+ &dbgaufs_xib_fop);
7000+ if (unlikely(!sbinfo->si_dbgaufs_xib))
7001+ goto out_dir;
7002+
1facf9fc 7003+ err = dbgaufs_xigen_init(sbinfo);
7004+ if (!err)
7005+ goto out; /* success */
7006+
4f0767ce 7007+out_dir:
1facf9fc 7008+ dbgaufs_si_fin(sbinfo);
4f0767ce 7009+out:
062440b3
AM
7010+ if (unlikely(err))
7011+ pr_err("debugfs/aufs failed\n");
1facf9fc 7012+ return err;
7013+}
7014+
7015+/* ---------------------------------------------------------------------- */
7016+
7017+void dbgaufs_fin(void)
7018+{
7019+ debugfs_remove(dbgaufs);
7020+}
7021+
7022+int __init dbgaufs_init(void)
7023+{
7024+ int err;
7025+
7026+ err = -EIO;
7027+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
7028+ if (dbgaufs)
7029+ err = 0;
7030+ return err;
7031+}
7f207e10
AM
7032diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
7033--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 7034+++ linux/fs/aufs/dbgaufs.h 2018-08-12 23:43:05.453457863 +0200
062440b3
AM
7035@@ -0,0 +1,53 @@
7036+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 7037+/*
b00004a5 7038+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 7039+ *
7040+ * This program, aufs is free software; you can redistribute it and/or modify
7041+ * it under the terms of the GNU General Public License as published by
7042+ * the Free Software Foundation; either version 2 of the License, or
7043+ * (at your option) any later version.
dece6358
AM
7044+ *
7045+ * This program is distributed in the hope that it will be useful,
7046+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7047+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7048+ * GNU General Public License for more details.
7049+ *
7050+ * You should have received a copy of the GNU General Public License
523b37e3 7051+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7052+ */
7053+
7054+/*
7055+ * debugfs interface
7056+ */
7057+
7058+#ifndef __DBGAUFS_H__
7059+#define __DBGAUFS_H__
7060+
7061+#ifdef __KERNEL__
7062+
dece6358 7063+struct super_block;
1facf9fc 7064+struct au_sbinfo;
062440b3 7065+struct au_branch;
dece6358 7066+
1facf9fc 7067+#ifdef CONFIG_DEBUG_FS
7068+/* dbgaufs.c */
062440b3 7069+void dbgaufs_xino_del(struct au_branch *br);
1facf9fc 7070+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
062440b3 7071+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown);
1facf9fc 7072+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
7073+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
7074+void dbgaufs_fin(void);
7075+int __init dbgaufs_init(void);
1facf9fc 7076+#else
062440b3 7077+AuStubVoid(dbgaufs_xino_del, struct au_branch *br)
4a4d8108 7078+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
062440b3
AM
7079+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex,
7080+ int topdown)
4a4d8108
AM
7081+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
7082+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
7083+AuStubVoid(dbgaufs_fin, void)
7084+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 7085+#endif /* CONFIG_DEBUG_FS */
7086+
7087+#endif /* __KERNEL__ */
7088+#endif /* __DBGAUFS_H__ */
7f207e10
AM
7089diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
7090--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9
AM
7091+++ linux/fs/aufs/dcsub.c 2018-08-12 23:43:05.453457863 +0200
7092@@ -0,0 +1,225 @@
7093+// SPDX-License-Identifier: GPL-2.0
1facf9fc 7094+/*
b00004a5 7095+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 7096+ *
7097+ * This program, aufs is free software; you can redistribute it and/or modify
7098+ * it under the terms of the GNU General Public License as published by
7099+ * the Free Software Foundation; either version 2 of the License, or
7100+ * (at your option) any later version.
dece6358
AM
7101+ *
7102+ * This program is distributed in the hope that it will be useful,
7103+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7104+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7105+ * GNU General Public License for more details.
7106+ *
7107+ * You should have received a copy of the GNU General Public License
523b37e3 7108+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7109+ */
7110+
7111+/*
7112+ * sub-routines for dentry cache
7113+ */
7114+
7115+#include "aufs.h"
7116+
7117+static void au_dpage_free(struct au_dpage *dpage)
7118+{
7119+ int i;
7120+ struct dentry **p;
7121+
7122+ p = dpage->dentries;
7123+ for (i = 0; i < dpage->ndentry; i++)
7124+ dput(*p++);
1c60b727 7125+ free_page((unsigned long)dpage->dentries);
1facf9fc 7126+}
7127+
7128+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
7129+{
7130+ int err;
7131+ void *p;
7132+
7133+ err = -ENOMEM;
7134+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
7135+ if (unlikely(!dpages->dpages))
7136+ goto out;
7137+
7138+ p = (void *)__get_free_page(gfp);
7139+ if (unlikely(!p))
7140+ goto out_dpages;
7141+
7142+ dpages->dpages[0].ndentry = 0;
7143+ dpages->dpages[0].dentries = p;
7144+ dpages->ndpage = 1;
7145+ return 0; /* success */
7146+
4f0767ce 7147+out_dpages:
1c60b727 7148+ kfree(dpages->dpages);
4f0767ce 7149+out:
1facf9fc 7150+ return err;
7151+}
7152+
7153+void au_dpages_free(struct au_dcsub_pages *dpages)
7154+{
7155+ int i;
7156+ struct au_dpage *p;
7157+
7158+ p = dpages->dpages;
7159+ for (i = 0; i < dpages->ndpage; i++)
7160+ au_dpage_free(p++);
1c60b727 7161+ kfree(dpages->dpages);
1facf9fc 7162+}
7163+
7164+static int au_dpages_append(struct au_dcsub_pages *dpages,
7165+ struct dentry *dentry, gfp_t gfp)
7166+{
7167+ int err, sz;
7168+ struct au_dpage *dpage;
7169+ void *p;
7170+
7171+ dpage = dpages->dpages + dpages->ndpage - 1;
7172+ sz = PAGE_SIZE / sizeof(dentry);
7173+ if (unlikely(dpage->ndentry >= sz)) {
7174+ AuLabel(new dpage);
7175+ err = -ENOMEM;
7176+ sz = dpages->ndpage * sizeof(*dpages->dpages);
7177+ p = au_kzrealloc(dpages->dpages, sz,
e2f27e51
AM
7178+ sz + sizeof(*dpages->dpages), gfp,
7179+ /*may_shrink*/0);
1facf9fc 7180+ if (unlikely(!p))
7181+ goto out;
7182+
7183+ dpages->dpages = p;
7184+ dpage = dpages->dpages + dpages->ndpage;
7185+ p = (void *)__get_free_page(gfp);
7186+ if (unlikely(!p))
7187+ goto out;
7188+
7189+ dpage->ndentry = 0;
7190+ dpage->dentries = p;
7191+ dpages->ndpage++;
7192+ }
7193+
c1595e42 7194+ AuDebugOn(au_dcount(dentry) <= 0);
027c5e7a 7195+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 7196+ return 0; /* success */
7197+
4f0767ce 7198+out:
1facf9fc 7199+ return err;
7200+}
7201+
c1595e42
JR
7202+/* todo: BAD approach */
7203+/* copied from linux/fs/dcache.c */
7204+enum d_walk_ret {
7205+ D_WALK_CONTINUE,
7206+ D_WALK_QUIT,
7207+ D_WALK_NORETRY,
7208+ D_WALK_SKIP,
7209+};
7210+
7211+extern void d_walk(struct dentry *parent, void *data,
cd7a4cd9 7212+ enum d_walk_ret (*enter)(void *, struct dentry *));
c1595e42
JR
7213+
7214+struct ac_dpages_arg {
1facf9fc 7215+ int err;
c1595e42
JR
7216+ struct au_dcsub_pages *dpages;
7217+ struct super_block *sb;
7218+ au_dpages_test test;
7219+ void *arg;
7220+};
1facf9fc 7221+
c1595e42
JR
7222+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry)
7223+{
7224+ enum d_walk_ret ret;
7225+ struct ac_dpages_arg *arg = _arg;
1facf9fc 7226+
c1595e42
JR
7227+ ret = D_WALK_CONTINUE;
7228+ if (dentry->d_sb == arg->sb
7229+ && !IS_ROOT(dentry)
7230+ && au_dcount(dentry) > 0
7231+ && au_di(dentry)
7232+ && (!arg->test || arg->test(dentry, arg->arg))) {
7233+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC);
7234+ if (unlikely(arg->err))
7235+ ret = D_WALK_QUIT;
1facf9fc 7236+ }
7237+
c1595e42
JR
7238+ return ret;
7239+}
027c5e7a 7240+
c1595e42
JR
7241+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
7242+ au_dpages_test test, void *arg)
7243+{
7244+ struct ac_dpages_arg args = {
7245+ .err = 0,
7246+ .dpages = dpages,
7247+ .sb = root->d_sb,
7248+ .test = test,
7249+ .arg = arg
7250+ };
027c5e7a 7251+
cd7a4cd9 7252+ d_walk(root, &args, au_call_dpages_append);
c1595e42
JR
7253+
7254+ return args.err;
1facf9fc 7255+}
7256+
7257+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
7258+ int do_include, au_dpages_test test, void *arg)
7259+{
7260+ int err;
7261+
7262+ err = 0;
027c5e7a
AM
7263+ write_seqlock(&rename_lock);
7264+ spin_lock(&dentry->d_lock);
7265+ if (do_include
c1595e42 7266+ && au_dcount(dentry) > 0
027c5e7a 7267+ && (!test || test(dentry, arg)))
1facf9fc 7268+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
7269+ spin_unlock(&dentry->d_lock);
7270+ if (unlikely(err))
7271+ goto out;
7272+
7273+ /*
523b37e3 7274+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
7275+ * mount
7276+ */
1facf9fc 7277+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
7278+ dentry = dentry->d_parent; /* rename_lock is locked */
7279+ spin_lock(&dentry->d_lock);
c1595e42 7280+ if (au_dcount(dentry) > 0
027c5e7a 7281+ && (!test || test(dentry, arg)))
1facf9fc 7282+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
7283+ spin_unlock(&dentry->d_lock);
7284+ if (unlikely(err))
7285+ break;
1facf9fc 7286+ }
7287+
4f0767ce 7288+out:
027c5e7a 7289+ write_sequnlock(&rename_lock);
1facf9fc 7290+ return err;
7291+}
7292+
027c5e7a
AM
7293+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
7294+{
7295+ return au_di(dentry) && dentry->d_sb == arg;
7296+}
7297+
7298+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
7299+ struct dentry *dentry, int do_include)
7300+{
7301+ return au_dcsub_pages_rev(dpages, dentry, do_include,
7302+ au_dcsub_dpages_aufs, dentry->d_sb);
7303+}
7304+
4a4d8108 7305+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 7306+{
4a4d8108
AM
7307+ struct path path[2] = {
7308+ {
7309+ .dentry = d1
7310+ },
7311+ {
7312+ .dentry = d2
7313+ }
7314+ };
1facf9fc 7315+
4a4d8108 7316+ return path_is_under(path + 0, path + 1);
1facf9fc 7317+}
7f207e10
AM
7318diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
7319--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 7320+++ linux/fs/aufs/dcsub.h 2018-08-12 23:43:05.453457863 +0200
062440b3
AM
7321@@ -0,0 +1,137 @@
7322+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 7323+/*
b00004a5 7324+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 7325+ *
7326+ * This program, aufs is free software; you can redistribute it and/or modify
7327+ * it under the terms of the GNU General Public License as published by
7328+ * the Free Software Foundation; either version 2 of the License, or
7329+ * (at your option) any later version.
dece6358
AM
7330+ *
7331+ * This program is distributed in the hope that it will be useful,
7332+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7333+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7334+ * GNU General Public License for more details.
7335+ *
7336+ * You should have received a copy of the GNU General Public License
523b37e3 7337+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7338+ */
7339+
7340+/*
7341+ * sub-routines for dentry cache
7342+ */
7343+
7344+#ifndef __AUFS_DCSUB_H__
7345+#define __AUFS_DCSUB_H__
7346+
7347+#ifdef __KERNEL__
7348+
7f207e10 7349+#include <linux/dcache.h>
027c5e7a 7350+#include <linux/fs.h>
dece6358 7351+
1facf9fc 7352+struct au_dpage {
7353+ int ndentry;
7354+ struct dentry **dentries;
7355+};
7356+
7357+struct au_dcsub_pages {
7358+ int ndpage;
7359+ struct au_dpage *dpages;
7360+};
7361+
7362+/* ---------------------------------------------------------------------- */
7363+
7f207e10 7364+/* dcsub.c */
1facf9fc 7365+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
7366+void au_dpages_free(struct au_dcsub_pages *dpages);
7367+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
7368+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
7369+ au_dpages_test test, void *arg);
7370+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
7371+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
7372+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
7373+ struct dentry *dentry, int do_include);
4a4d8108 7374+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 7375+
7f207e10
AM
7376+/* ---------------------------------------------------------------------- */
7377+
523b37e3
AM
7378+/*
7379+ * todo: in linux-3.13, several similar (but faster) helpers are added to
7380+ * include/linux/dcache.h. Try them (in the future).
7381+ */
7382+
027c5e7a
AM
7383+static inline int au_d_hashed_positive(struct dentry *d)
7384+{
7385+ int err;
5527c038 7386+ struct inode *inode = d_inode(d);
076b876e 7387+
027c5e7a 7388+ err = 0;
5527c038
JR
7389+ if (unlikely(d_unhashed(d)
7390+ || d_is_negative(d)
7391+ || !inode->i_nlink))
027c5e7a
AM
7392+ err = -ENOENT;
7393+ return err;
7394+}
7395+
38d290e6
JR
7396+static inline int au_d_linkable(struct dentry *d)
7397+{
7398+ int err;
5527c038 7399+ struct inode *inode = d_inode(d);
076b876e 7400+
38d290e6
JR
7401+ err = au_d_hashed_positive(d);
7402+ if (err
5527c038 7403+ && d_is_positive(d)
38d290e6
JR
7404+ && (inode->i_state & I_LINKABLE))
7405+ err = 0;
7406+ return err;
7407+}
7408+
027c5e7a
AM
7409+static inline int au_d_alive(struct dentry *d)
7410+{
7411+ int err;
7412+ struct inode *inode;
076b876e 7413+
027c5e7a
AM
7414+ err = 0;
7415+ if (!IS_ROOT(d))
7416+ err = au_d_hashed_positive(d);
7417+ else {
5527c038
JR
7418+ inode = d_inode(d);
7419+ if (unlikely(d_unlinked(d)
7420+ || d_is_negative(d)
7421+ || !inode->i_nlink))
027c5e7a
AM
7422+ err = -ENOENT;
7423+ }
7424+ return err;
7425+}
7426+
7427+static inline int au_alive_dir(struct dentry *d)
7f207e10 7428+{
027c5e7a 7429+ int err;
076b876e 7430+
027c5e7a 7431+ err = au_d_alive(d);
5527c038 7432+ if (unlikely(err || IS_DEADDIR(d_inode(d))))
027c5e7a
AM
7433+ err = -ENOENT;
7434+ return err;
7f207e10
AM
7435+}
7436+
38d290e6
JR
7437+static inline int au_qstreq(struct qstr *a, struct qstr *b)
7438+{
7439+ return a->len == b->len
7440+ && !memcmp(a->name, b->name, a->len);
7441+}
7442+
7e9cd9fe
AM
7443+/*
7444+ * by the commit
7445+ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without
7446+ * taking d_lock
7447+ * the type of d_lockref.count became int, but the inlined function d_count()
7448+ * still returns unsigned int.
7449+ * I don't know why. Maybe it is for every d_count() users?
7450+ * Anyway au_dcount() lives on.
7451+ */
c1595e42
JR
7452+static inline int au_dcount(struct dentry *d)
7453+{
7454+ return (int)d_count(d);
7455+}
7456+
1facf9fc 7457+#endif /* __KERNEL__ */
7458+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
7459diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
7460--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
7461+++ linux/fs/aufs/debug.c 2018-10-23 12:33:35.596042364 +0200
7462@@ -0,0 +1,440 @@
cd7a4cd9 7463+// SPDX-License-Identifier: GPL-2.0
1facf9fc 7464+/*
b00004a5 7465+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 7466+ *
7467+ * This program, aufs is free software; you can redistribute it and/or modify
7468+ * it under the terms of the GNU General Public License as published by
7469+ * the Free Software Foundation; either version 2 of the License, or
7470+ * (at your option) any later version.
dece6358
AM
7471+ *
7472+ * This program is distributed in the hope that it will be useful,
7473+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7474+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7475+ * GNU General Public License for more details.
7476+ *
7477+ * You should have received a copy of the GNU General Public License
523b37e3 7478+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7479+ */
7480+
7481+/*
7482+ * debug print functions
7483+ */
7484+
7485+#include "aufs.h"
7486+
392086de
AM
7487+/* Returns 0, or -errno. arg is in kp->arg. */
7488+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
7489+{
7490+ int err, n;
7491+
7492+ err = kstrtoint(val, 0, &n);
7493+ if (!err) {
7494+ if (n > 0)
7495+ au_debug_on();
7496+ else
7497+ au_debug_off();
7498+ }
7499+ return err;
7500+}
7501+
7502+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
7503+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
7504+{
7505+ atomic_t *a;
7506+
7507+ a = kp->arg;
7508+ return sprintf(buffer, "%d", atomic_read(a));
7509+}
7510+
7511+static struct kernel_param_ops param_ops_atomic_t = {
7512+ .set = param_atomic_t_set,
7513+ .get = param_atomic_t_get
7514+ /* void (*free)(void *arg) */
7515+};
7516+
7517+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 7518+MODULE_PARM_DESC(debug, "debug print");
cd7a4cd9 7519+module_param_named(debug, aufs_debug, atomic_t, 0664);
1facf9fc 7520+
c1595e42 7521+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */
1facf9fc 7522+char *au_plevel = KERN_DEBUG;
e49829fe
JR
7523+#define dpri(fmt, ...) do { \
7524+ if ((au_plevel \
7525+ && strcmp(au_plevel, KERN_DEBUG)) \
7526+ || au_debug_test()) \
7527+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 7528+} while (0)
7529+
7530+/* ---------------------------------------------------------------------- */
7531+
7532+void au_dpri_whlist(struct au_nhash *whlist)
7533+{
7534+ unsigned long ul, n;
7535+ struct hlist_head *head;
c06a8ce3 7536+ struct au_vdir_wh *pos;
1facf9fc 7537+
7538+ n = whlist->nh_num;
7539+ head = whlist->nh_head;
7540+ for (ul = 0; ul < n; ul++) {
c06a8ce3 7541+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 7542+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
7543+ pos->wh_bindex,
7544+ pos->wh_str.len, pos->wh_str.name,
7545+ pos->wh_str.len);
1facf9fc 7546+ head++;
7547+ }
7548+}
7549+
7550+void au_dpri_vdir(struct au_vdir *vdir)
7551+{
7552+ unsigned long ul;
7553+ union au_vdir_deblk_p p;
7554+ unsigned char *o;
7555+
7556+ if (!vdir || IS_ERR(vdir)) {
7557+ dpri("err %ld\n", PTR_ERR(vdir));
7558+ return;
7559+ }
7560+
be118d29 7561+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %llu\n",
1facf9fc 7562+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
7563+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
7564+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
7565+ p.deblk = vdir->vd_deblk[ul];
7566+ o = p.deblk;
7567+ dpri("[%lu]: %p\n", ul, o);
7568+ }
7569+}
7570+
53392da6 7571+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 7572+ struct dentry *wh)
7573+{
7574+ char *n = NULL;
7575+ int l = 0;
7576+
7577+ if (!inode || IS_ERR(inode)) {
7578+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
7579+ return -1;
7580+ }
7581+
c2b27bf2 7582+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 7583+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
7584+ && sizeof(inode->i_blocks) != sizeof(u64));
7585+ if (wh) {
7586+ n = (void *)wh->d_name.name;
7587+ l = wh->d_name.len;
7588+ }
7589+
53392da6
AM
7590+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
7591+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
7592+ bindex, inode,
1facf9fc 7593+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
7594+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
7595+ i_size_read(inode), (unsigned long long)inode->i_blocks,
cd7a4cd9 7596+ hn, (long long)timespec64_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 7597+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
be118d29 7598+ inode->i_state, inode->i_flags, inode_peek_iversion(inode),
b752ccd1 7599+ inode->i_generation,
1facf9fc 7600+ l ? ", wh " : "", l, n);
7601+ return 0;
7602+}
7603+
7604+void au_dpri_inode(struct inode *inode)
7605+{
7606+ struct au_iinfo *iinfo;
5afbbe0d 7607+ struct au_hinode *hi;
1facf9fc 7608+ aufs_bindex_t bindex;
53392da6 7609+ int err, hn;
1facf9fc 7610+
53392da6 7611+ err = do_pri_inode(-1, inode, -1, NULL);
5afbbe0d 7612+ if (err || !au_test_aufs(inode->i_sb) || au_is_bad_inode(inode))
1facf9fc 7613+ return;
7614+
7615+ iinfo = au_ii(inode);
5afbbe0d
AM
7616+ dpri("i-1: btop %d, bbot %d, gen %d\n",
7617+ iinfo->ii_btop, iinfo->ii_bbot, au_iigen(inode, NULL));
7618+ if (iinfo->ii_btop < 0)
1facf9fc 7619+ return;
53392da6 7620+ hn = 0;
5afbbe0d
AM
7621+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; bindex++) {
7622+ hi = au_hinode(iinfo, bindex);
7623+ hn = !!au_hn(hi);
7624+ do_pri_inode(bindex, hi->hi_inode, hn, hi->hi_whdentry);
53392da6 7625+ }
1facf9fc 7626+}
7627+
2cbb1c4b
JR
7628+void au_dpri_dalias(struct inode *inode)
7629+{
7630+ struct dentry *d;
7631+
7632+ spin_lock(&inode->i_lock);
c1595e42 7633+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias)
2cbb1c4b
JR
7634+ au_dpri_dentry(d);
7635+ spin_unlock(&inode->i_lock);
7636+}
7637+
1facf9fc 7638+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
7639+{
7640+ struct dentry *wh = NULL;
53392da6 7641+ int hn;
5afbbe0d 7642+ struct inode *inode;
076b876e 7643+ struct au_iinfo *iinfo;
5afbbe0d 7644+ struct au_hinode *hi;
1facf9fc 7645+
7646+ if (!dentry || IS_ERR(dentry)) {
7647+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
7648+ return -1;
7649+ }
7650+ /* do not call dget_parent() here */
027c5e7a 7651+ /* note: access d_xxx without d_lock */
523b37e3
AM
7652+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
7653+ bindex, dentry, dentry,
1facf9fc 7654+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
c1595e42 7655+ au_dcount(dentry), dentry->d_flags,
523b37e3 7656+ d_unhashed(dentry) ? "un" : "");
53392da6 7657+ hn = -1;
5afbbe0d
AM
7658+ inode = NULL;
7659+ if (d_is_positive(dentry))
7660+ inode = d_inode(dentry);
7661+ if (inode
7662+ && au_test_aufs(dentry->d_sb)
7663+ && bindex >= 0
7664+ && !au_is_bad_inode(inode)) {
7665+ iinfo = au_ii(inode);
7666+ hi = au_hinode(iinfo, bindex);
7667+ hn = !!au_hn(hi);
7668+ wh = hi->hi_whdentry;
7669+ }
7670+ do_pri_inode(bindex, inode, hn, wh);
1facf9fc 7671+ return 0;
7672+}
7673+
7674+void au_dpri_dentry(struct dentry *dentry)
7675+{
7676+ struct au_dinfo *dinfo;
7677+ aufs_bindex_t bindex;
7678+ int err;
7679+
7680+ err = do_pri_dentry(-1, dentry);
7681+ if (err || !au_test_aufs(dentry->d_sb))
7682+ return;
7683+
7684+ dinfo = au_di(dentry);
7685+ if (!dinfo)
7686+ return;
5afbbe0d
AM
7687+ dpri("d-1: btop %d, bbot %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
7688+ dinfo->di_btop, dinfo->di_bbot,
38d290e6
JR
7689+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
7690+ dinfo->di_tmpfile);
5afbbe0d 7691+ if (dinfo->di_btop < 0)
1facf9fc 7692+ return;
5afbbe0d
AM
7693+ for (bindex = dinfo->di_btop; bindex <= dinfo->di_bbot; bindex++)
7694+ do_pri_dentry(bindex, au_hdentry(dinfo, bindex)->hd_dentry);
1facf9fc 7695+}
7696+
7697+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
7698+{
7699+ char a[32];
7700+
7701+ if (!file || IS_ERR(file)) {
7702+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
7703+ return -1;
7704+ }
7705+ a[0] = 0;
7706+ if (bindex < 0
b912730e 7707+ && !IS_ERR_OR_NULL(file->f_path.dentry)
2000de60 7708+ && au_test_aufs(file->f_path.dentry->d_sb)
1facf9fc 7709+ && au_fi(file))
e49829fe 7710+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 7711+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 7712+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 7713+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 7714+ file->f_version, file->f_pos, a);
b912730e 7715+ if (!IS_ERR_OR_NULL(file->f_path.dentry))
2000de60 7716+ do_pri_dentry(bindex, file->f_path.dentry);
1facf9fc 7717+ return 0;
7718+}
7719+
7720+void au_dpri_file(struct file *file)
7721+{
7722+ struct au_finfo *finfo;
4a4d8108
AM
7723+ struct au_fidir *fidir;
7724+ struct au_hfile *hfile;
1facf9fc 7725+ aufs_bindex_t bindex;
7726+ int err;
7727+
7728+ err = do_pri_file(-1, file);
2000de60 7729+ if (err
b912730e 7730+ || IS_ERR_OR_NULL(file->f_path.dentry)
2000de60 7731+ || !au_test_aufs(file->f_path.dentry->d_sb))
1facf9fc 7732+ return;
7733+
7734+ finfo = au_fi(file);
7735+ if (!finfo)
7736+ return;
4a4d8108 7737+ if (finfo->fi_btop < 0)
1facf9fc 7738+ return;
4a4d8108
AM
7739+ fidir = finfo->fi_hdir;
7740+ if (!fidir)
7741+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
7742+ else
e49829fe
JR
7743+ for (bindex = finfo->fi_btop;
7744+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
7745+ bindex++) {
7746+ hfile = fidir->fd_hfile + bindex;
7747+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
7748+ }
1facf9fc 7749+}
7750+
7751+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
7752+{
7753+ struct vfsmount *mnt;
7754+ struct super_block *sb;
7755+
7756+ if (!br || IS_ERR(br))
7757+ goto out;
86dc4139 7758+ mnt = au_br_mnt(br);
1facf9fc 7759+ if (!mnt || IS_ERR(mnt))
7760+ goto out;
7761+ sb = mnt->mnt_sb;
7762+ if (!sb || IS_ERR(sb))
7763+ goto out;
7764+
acd2b654 7765+ dpri("s%d: {perm 0x%x, id %d, wbr %p}, "
b752ccd1 7766+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 7767+ "xino %d\n",
acd2b654
AM
7768+ bindex, br->br_perm, br->br_id, br->br_wbr,
7769+ au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 7770+ sb->s_flags, sb->s_count,
acd2b654
AM
7771+ atomic_read(&sb->s_active),
7772+ !!au_xino_file(br->br_xino, /*idx*/-1));
1facf9fc 7773+ return 0;
7774+
4f0767ce 7775+out:
1facf9fc 7776+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
7777+ return -1;
7778+}
7779+
7780+void au_dpri_sb(struct super_block *sb)
7781+{
7782+ struct au_sbinfo *sbinfo;
7783+ aufs_bindex_t bindex;
7784+ int err;
acd2b654 7785+ /* to reduce stack size */
1facf9fc 7786+ struct {
7787+ struct vfsmount mnt;
7788+ struct au_branch fake;
7789+ } *a;
7790+
7791+ /* this function can be called from magic sysrq */
7792+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
7793+ if (unlikely(!a)) {
7794+ dpri("no memory\n");
7795+ return;
7796+ }
7797+
7798+ a->mnt.mnt_sb = sb;
86dc4139 7799+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 7800+ err = do_pri_br(-1, &a->fake);
1c60b727 7801+ kfree(a);
1facf9fc 7802+ dpri("dev 0x%x\n", sb->s_dev);
7803+ if (err || !au_test_aufs(sb))
7804+ return;
7805+
7806+ sbinfo = au_sbi(sb);
7807+ if (!sbinfo)
7808+ return;
f0c0a007
AM
7809+ dpri("nw %d, gen %u, kobj %d\n",
7810+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
521ced18 7811+ kref_read(&sbinfo->si_kobj.kref));
5afbbe0d 7812+ for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++)
1facf9fc 7813+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
7814+}
7815+
7816+/* ---------------------------------------------------------------------- */
7817+
027c5e7a
AM
7818+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
7819+{
5527c038 7820+ struct inode *h_inode, *inode = d_inode(dentry);
027c5e7a 7821+ struct dentry *h_dentry;
5afbbe0d 7822+ aufs_bindex_t bindex, bbot, bi;
027c5e7a
AM
7823+
7824+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
7825+ return;
7826+
5afbbe0d
AM
7827+ bbot = au_dbbot(dentry);
7828+ bi = au_ibbot(inode);
7829+ if (bi < bbot)
7830+ bbot = bi;
7831+ bindex = au_dbtop(dentry);
7832+ bi = au_ibtop(inode);
027c5e7a
AM
7833+ if (bi > bindex)
7834+ bindex = bi;
7835+
5afbbe0d 7836+ for (; bindex <= bbot; bindex++) {
027c5e7a
AM
7837+ h_dentry = au_h_dptr(dentry, bindex);
7838+ if (!h_dentry)
7839+ continue;
7840+ h_inode = au_h_iptr(inode, bindex);
5527c038 7841+ if (unlikely(h_inode != d_inode(h_dentry))) {
392086de 7842+ au_debug_on();
027c5e7a
AM
7843+ AuDbg("b%d, %s:%d\n", bindex, func, line);
7844+ AuDbgDentry(dentry);
7845+ AuDbgInode(inode);
392086de 7846+ au_debug_off();
027c5e7a
AM
7847+ BUG();
7848+ }
7849+ }
7850+}
7851+
1facf9fc 7852+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
7853+{
7854+ int err, i, j;
7855+ struct au_dcsub_pages dpages;
7856+ struct au_dpage *dpage;
7857+ struct dentry **dentries;
7858+
7859+ err = au_dpages_init(&dpages, GFP_NOFS);
7860+ AuDebugOn(err);
027c5e7a 7861+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 7862+ AuDebugOn(err);
7863+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
7864+ dpage = dpages.dpages + i;
7865+ dentries = dpage->dentries;
7866+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 7867+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 7868+ }
7869+ au_dpages_free(&dpages);
7870+}
7871+
1facf9fc 7872+void au_dbg_verify_kthread(void)
7873+{
53392da6 7874+ if (au_wkq_test()) {
1facf9fc 7875+ au_dbg_blocked();
1e00d052
AM
7876+ /*
7877+ * It may be recursive, but udba=notify between two aufs mounts,
7878+ * where a single ro branch is shared, is not a problem.
7879+ */
7880+ /* WARN_ON(1); */
1facf9fc 7881+ }
7882+}
7883+
7884+/* ---------------------------------------------------------------------- */
7885+
1facf9fc 7886+int __init au_debug_init(void)
7887+{
7888+ aufs_bindex_t bindex;
7889+ struct au_vdir_destr destr;
7890+
7891+ bindex = -1;
7892+ AuDebugOn(bindex >= 0);
7893+
7894+ destr.len = -1;
7895+ AuDebugOn(destr.len < NAME_MAX);
7896+
7897+#ifdef CONFIG_4KSTACKS
0c3ec466 7898+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 7899+#endif
7900+
1facf9fc 7901+ return 0;
7902+}
7f207e10
AM
7903diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
7904--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 7905+++ linux/fs/aufs/debug.h 2018-08-12 23:43:05.453457863 +0200
062440b3
AM
7906@@ -0,0 +1,226 @@
7907+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 7908+/*
b00004a5 7909+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 7910+ *
7911+ * This program, aufs is free software; you can redistribute it and/or modify
7912+ * it under the terms of the GNU General Public License as published by
7913+ * the Free Software Foundation; either version 2 of the License, or
7914+ * (at your option) any later version.
dece6358
AM
7915+ *
7916+ * This program is distributed in the hope that it will be useful,
7917+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7918+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7919+ * GNU General Public License for more details.
7920+ *
7921+ * You should have received a copy of the GNU General Public License
523b37e3 7922+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7923+ */
7924+
7925+/*
7926+ * debug print functions
7927+ */
7928+
7929+#ifndef __AUFS_DEBUG_H__
7930+#define __AUFS_DEBUG_H__
7931+
7932+#ifdef __KERNEL__
7933+
392086de 7934+#include <linux/atomic.h>
4a4d8108
AM
7935+#include <linux/module.h>
7936+#include <linux/kallsyms.h>
1facf9fc 7937+#include <linux/sysrq.h>
4a4d8108 7938+
1facf9fc 7939+#ifdef CONFIG_AUFS_DEBUG
7940+#define AuDebugOn(a) BUG_ON(a)
7941+
7942+/* module parameter */
392086de
AM
7943+extern atomic_t aufs_debug;
7944+static inline void au_debug_on(void)
1facf9fc 7945+{
392086de
AM
7946+ atomic_inc(&aufs_debug);
7947+}
7948+static inline void au_debug_off(void)
7949+{
7950+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 7951+}
7952+
7953+static inline int au_debug_test(void)
7954+{
392086de 7955+ return atomic_read(&aufs_debug) > 0;
1facf9fc 7956+}
7957+#else
7958+#define AuDebugOn(a) do {} while (0)
392086de
AM
7959+AuStubVoid(au_debug_on, void)
7960+AuStubVoid(au_debug_off, void)
4a4d8108 7961+AuStubInt0(au_debug_test, void)
1facf9fc 7962+#endif /* CONFIG_AUFS_DEBUG */
7963+
392086de
AM
7964+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
7965+
1facf9fc 7966+/* ---------------------------------------------------------------------- */
7967+
7968+/* debug print */
7969+
4a4d8108 7970+#define AuDbg(fmt, ...) do { \
1facf9fc 7971+ if (au_debug_test()) \
4a4d8108 7972+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 7973+} while (0)
4a4d8108
AM
7974+#define AuLabel(l) AuDbg(#l "\n")
7975+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
7976+#define AuWarn1(fmt, ...) do { \
1facf9fc 7977+ static unsigned char _c; \
7978+ if (!_c++) \
0c3ec466 7979+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 7980+} while (0)
7981+
4a4d8108 7982+#define AuErr1(fmt, ...) do { \
1facf9fc 7983+ static unsigned char _c; \
7984+ if (!_c++) \
4a4d8108 7985+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 7986+} while (0)
7987+
4a4d8108 7988+#define AuIOErr1(fmt, ...) do { \
1facf9fc 7989+ static unsigned char _c; \
7990+ if (!_c++) \
4a4d8108 7991+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 7992+} while (0)
7993+
7994+#define AuUnsupportMsg "This operation is not supported." \
7995+ " Please report this application to aufs-users ML."
4a4d8108
AM
7996+#define AuUnsupport(fmt, ...) do { \
7997+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 7998+ dump_stack(); \
7999+} while (0)
8000+
8001+#define AuTraceErr(e) do { \
8002+ if (unlikely((e) < 0)) \
8003+ AuDbg("err %d\n", (int)(e)); \
8004+} while (0)
8005+
8006+#define AuTraceErrPtr(p) do { \
8007+ if (IS_ERR(p)) \
8008+ AuDbg("err %ld\n", PTR_ERR(p)); \
8009+} while (0)
8010+
8011+/* dirty macros for debug print, use with "%.*s" and caution */
8012+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 8013+
8014+/* ---------------------------------------------------------------------- */
8015+
dece6358 8016+struct dentry;
1facf9fc 8017+#ifdef CONFIG_AUFS_DEBUG
c1595e42 8018+extern struct mutex au_dbg_mtx;
1facf9fc 8019+extern char *au_plevel;
8020+struct au_nhash;
8021+void au_dpri_whlist(struct au_nhash *whlist);
8022+struct au_vdir;
8023+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 8024+struct inode;
1facf9fc 8025+void au_dpri_inode(struct inode *inode);
2cbb1c4b 8026+void au_dpri_dalias(struct inode *inode);
1facf9fc 8027+void au_dpri_dentry(struct dentry *dentry);
dece6358 8028+struct file;
1facf9fc 8029+void au_dpri_file(struct file *filp);
dece6358 8030+struct super_block;
1facf9fc 8031+void au_dpri_sb(struct super_block *sb);
8032+
027c5e7a
AM
8033+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
8034+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 8035+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 8036+void au_dbg_verify_kthread(void);
8037+
8038+int __init au_debug_init(void);
7e9cd9fe 8039+
1facf9fc 8040+#define AuDbgWhlist(w) do { \
c1595e42 8041+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8042+ AuDbg(#w "\n"); \
8043+ au_dpri_whlist(w); \
c1595e42 8044+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8045+} while (0)
8046+
8047+#define AuDbgVdir(v) do { \
c1595e42 8048+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8049+ AuDbg(#v "\n"); \
8050+ au_dpri_vdir(v); \
c1595e42 8051+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8052+} while (0)
8053+
8054+#define AuDbgInode(i) do { \
c1595e42 8055+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8056+ AuDbg(#i "\n"); \
8057+ au_dpri_inode(i); \
c1595e42 8058+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8059+} while (0)
8060+
2cbb1c4b 8061+#define AuDbgDAlias(i) do { \
c1595e42 8062+ mutex_lock(&au_dbg_mtx); \
2cbb1c4b
JR
8063+ AuDbg(#i "\n"); \
8064+ au_dpri_dalias(i); \
c1595e42 8065+ mutex_unlock(&au_dbg_mtx); \
2cbb1c4b
JR
8066+} while (0)
8067+
1facf9fc 8068+#define AuDbgDentry(d) do { \
c1595e42 8069+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8070+ AuDbg(#d "\n"); \
8071+ au_dpri_dentry(d); \
c1595e42 8072+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8073+} while (0)
8074+
8075+#define AuDbgFile(f) do { \
c1595e42 8076+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8077+ AuDbg(#f "\n"); \
8078+ au_dpri_file(f); \
c1595e42 8079+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8080+} while (0)
8081+
8082+#define AuDbgSb(sb) do { \
c1595e42 8083+ mutex_lock(&au_dbg_mtx); \
1facf9fc 8084+ AuDbg(#sb "\n"); \
8085+ au_dpri_sb(sb); \
c1595e42 8086+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 8087+} while (0)
8088+
4a4d8108
AM
8089+#define AuDbgSym(addr) do { \
8090+ char sym[KSYM_SYMBOL_LEN]; \
8091+ sprint_symbol(sym, (unsigned long)addr); \
8092+ AuDbg("%s\n", sym); \
8093+} while (0)
1facf9fc 8094+#else
027c5e7a 8095+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
8096+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
8097+AuStubVoid(au_dbg_verify_kthread, void)
8098+AuStubInt0(__init au_debug_init, void)
1facf9fc 8099+
1facf9fc 8100+#define AuDbgWhlist(w) do {} while (0)
8101+#define AuDbgVdir(v) do {} while (0)
8102+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 8103+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 8104+#define AuDbgDentry(d) do {} while (0)
8105+#define AuDbgFile(f) do {} while (0)
8106+#define AuDbgSb(sb) do {} while (0)
4a4d8108 8107+#define AuDbgSym(addr) do {} while (0)
1facf9fc 8108+#endif /* CONFIG_AUFS_DEBUG */
8109+
8110+/* ---------------------------------------------------------------------- */
8111+
8112+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
8113+int __init au_sysrq_init(void);
8114+void au_sysrq_fin(void);
8115+
8116+#ifdef CONFIG_HW_CONSOLE
8117+#define au_dbg_blocked() do { \
8118+ WARN_ON(1); \
0c5527e5 8119+ handle_sysrq('w'); \
1facf9fc 8120+} while (0)
8121+#else
4a4d8108 8122+AuStubVoid(au_dbg_blocked, void)
1facf9fc 8123+#endif
8124+
8125+#else
4a4d8108
AM
8126+AuStubInt0(__init au_sysrq_init, void)
8127+AuStubVoid(au_sysrq_fin, void)
8128+AuStubVoid(au_dbg_blocked, void)
1facf9fc 8129+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
8130+
8131+#endif /* __KERNEL__ */
8132+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
8133diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
8134--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 8135+++ linux/fs/aufs/dentry.c 2018-10-23 12:33:35.596042364 +0200
062440b3 8136@@ -0,0 +1,1153 @@
cd7a4cd9 8137+// SPDX-License-Identifier: GPL-2.0
1facf9fc 8138+/*
b00004a5 8139+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 8140+ *
8141+ * This program, aufs is free software; you can redistribute it and/or modify
8142+ * it under the terms of the GNU General Public License as published by
8143+ * the Free Software Foundation; either version 2 of the License, or
8144+ * (at your option) any later version.
dece6358
AM
8145+ *
8146+ * This program is distributed in the hope that it will be useful,
8147+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8148+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8149+ * GNU General Public License for more details.
8150+ *
8151+ * You should have received a copy of the GNU General Public License
523b37e3 8152+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8153+ */
8154+
8155+/*
8156+ * lookup and dentry operations
8157+ */
8158+
dece6358 8159+#include <linux/namei.h>
1facf9fc 8160+#include "aufs.h"
8161+
1facf9fc 8162+/*
8163+ * returns positive/negative dentry, NULL or an error.
8164+ * NULL means whiteout-ed or not-found.
8165+ */
8166+static struct dentry*
8167+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
8b6a4947 8168+ aufs_bindex_t bindex, struct au_do_lookup_args *args)
1facf9fc 8169+{
8170+ struct dentry *h_dentry;
2000de60 8171+ struct inode *h_inode;
1facf9fc 8172+ struct au_branch *br;
8173+ int wh_found, opq;
8174+ unsigned char wh_able;
8175+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
076b876e
AM
8176+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
8177+ IGNORE_PERM);
1facf9fc 8178+
1facf9fc 8179+ wh_found = 0;
8180+ br = au_sbr(dentry->d_sb, bindex);
8181+ wh_able = !!au_br_whable(br->br_perm);
8182+ if (wh_able)
8b6a4947 8183+ wh_found = au_wh_test(h_parent, &args->whname, ignore_perm);
1facf9fc 8184+ h_dentry = ERR_PTR(wh_found);
8185+ if (!wh_found)
8186+ goto real_lookup;
8187+ if (unlikely(wh_found < 0))
8188+ goto out;
8189+
8190+ /* We found a whiteout */
5afbbe0d 8191+ /* au_set_dbbot(dentry, bindex); */
1facf9fc 8192+ au_set_dbwh(dentry, bindex);
8193+ if (!allow_neg)
8194+ return NULL; /* success */
8195+
4f0767ce 8196+real_lookup:
076b876e 8197+ if (!ignore_perm)
8b6a4947 8198+ h_dentry = vfsub_lkup_one(args->name, h_parent);
076b876e 8199+ else
8b6a4947 8200+ h_dentry = au_sio_lkup_one(args->name, h_parent);
2000de60
JR
8201+ if (IS_ERR(h_dentry)) {
8202+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG
8203+ && !allow_neg)
8204+ h_dentry = NULL;
1facf9fc 8205+ goto out;
2000de60 8206+ }
1facf9fc 8207+
5527c038
JR
8208+ h_inode = d_inode(h_dentry);
8209+ if (d_is_negative(h_dentry)) {
1facf9fc 8210+ if (!allow_neg)
8211+ goto out_neg;
8212+ } else if (wh_found
8213+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
8214+ goto out_neg;
8b6a4947
AM
8215+ else if (au_ftest_lkup(args->flags, DIRREN)
8216+ /* && h_inode */
8217+ && !au_dr_lkup_h_ino(args, bindex, h_inode->i_ino)) {
8218+ AuDbg("b%d %pd ignored hi%llu\n", bindex, h_dentry,
8219+ (unsigned long long)h_inode->i_ino);
8220+ goto out_neg;
8221+ }
1facf9fc 8222+
5afbbe0d
AM
8223+ if (au_dbbot(dentry) <= bindex)
8224+ au_set_dbbot(dentry, bindex);
8225+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
8226+ au_set_dbtop(dentry, bindex);
1facf9fc 8227+ au_set_h_dptr(dentry, bindex, h_dentry);
8228+
2000de60
JR
8229+ if (!d_is_dir(h_dentry)
8230+ || !wh_able
5527c038 8231+ || (d_really_is_positive(dentry) && !d_is_dir(dentry)))
1facf9fc 8232+ goto out; /* success */
8233+
be118d29 8234+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD);
076b876e 8235+ opq = au_diropq_test(h_dentry);
3c1bdaff 8236+ inode_unlock_shared(h_inode);
1facf9fc 8237+ if (opq > 0)
8238+ au_set_dbdiropq(dentry, bindex);
8239+ else if (unlikely(opq < 0)) {
8240+ au_set_h_dptr(dentry, bindex, NULL);
8241+ h_dentry = ERR_PTR(opq);
8242+ }
8243+ goto out;
8244+
4f0767ce 8245+out_neg:
1facf9fc 8246+ dput(h_dentry);
8247+ h_dentry = NULL;
4f0767ce 8248+out:
1facf9fc 8249+ return h_dentry;
8250+}
8251+
dece6358
AM
8252+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
8253+{
8254+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
8255+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
8256+ return -EPERM;
8257+ return 0;
8258+}
8259+
1facf9fc 8260+/*
8261+ * returns the number of lower positive dentries,
8262+ * otherwise an error.
8263+ * can be called at unlinking with @type is zero.
8264+ */
5afbbe0d
AM
8265+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
8266+ unsigned int flags)
1facf9fc 8267+{
8268+ int npositive, err;
8269+ aufs_bindex_t bindex, btail, bdiropq;
8b6a4947 8270+ unsigned char isdir, dirperm1, dirren;
1facf9fc 8271+ struct au_do_lookup_args args = {
8b6a4947
AM
8272+ .flags = flags,
8273+ .name = &dentry->d_name
1facf9fc 8274+ };
1facf9fc 8275+ struct dentry *parent;
076b876e 8276+ struct super_block *sb;
1facf9fc 8277+
076b876e 8278+ sb = dentry->d_sb;
8b6a4947 8279+ err = au_test_shwh(sb, args.name);
dece6358 8280+ if (unlikely(err))
1facf9fc 8281+ goto out;
8282+
8b6a4947 8283+ err = au_wh_name_alloc(&args.whname, args.name);
1facf9fc 8284+ if (unlikely(err))
8285+ goto out;
8286+
2000de60 8287+ isdir = !!d_is_dir(dentry);
076b876e 8288+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
8b6a4947
AM
8289+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN);
8290+ if (dirren)
8291+ au_fset_lkup(args.flags, DIRREN);
1facf9fc 8292+
8293+ npositive = 0;
4a4d8108 8294+ parent = dget_parent(dentry);
1facf9fc 8295+ btail = au_dbtaildir(parent);
5afbbe0d 8296+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 8297+ struct dentry *h_parent, *h_dentry;
8298+ struct inode *h_inode, *h_dir;
8b6a4947 8299+ struct au_branch *br;
1facf9fc 8300+
8301+ h_dentry = au_h_dptr(dentry, bindex);
8302+ if (h_dentry) {
5527c038 8303+ if (d_is_positive(h_dentry))
1facf9fc 8304+ npositive++;
5afbbe0d 8305+ break;
1facf9fc 8306+ }
8307+ h_parent = au_h_dptr(parent, bindex);
2000de60 8308+ if (!h_parent || !d_is_dir(h_parent))
1facf9fc 8309+ continue;
8310+
8b6a4947
AM
8311+ if (dirren) {
8312+ /* if the inum matches, then use the prepared name */
8313+ err = au_dr_lkup_name(&args, bindex);
8314+ if (unlikely(err))
8315+ goto out_parent;
8316+ }
8317+
5527c038 8318+ h_dir = d_inode(h_parent);
be118d29 8319+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
8b6a4947 8320+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &args);
3c1bdaff 8321+ inode_unlock_shared(h_dir);
1facf9fc 8322+ err = PTR_ERR(h_dentry);
8323+ if (IS_ERR(h_dentry))
4a4d8108 8324+ goto out_parent;
2000de60
JR
8325+ if (h_dentry)
8326+ au_fclr_lkup(args.flags, ALLOW_NEG);
076b876e
AM
8327+ if (dirperm1)
8328+ au_fset_lkup(args.flags, IGNORE_PERM);
1facf9fc 8329+
79b8bda9 8330+ if (au_dbwh(dentry) == bindex)
1facf9fc 8331+ break;
8332+ if (!h_dentry)
8333+ continue;
5527c038 8334+ if (d_is_negative(h_dentry))
1facf9fc 8335+ continue;
5527c038 8336+ h_inode = d_inode(h_dentry);
1facf9fc 8337+ npositive++;
8338+ if (!args.type)
8339+ args.type = h_inode->i_mode & S_IFMT;
8340+ if (args.type != S_IFDIR)
8341+ break;
8342+ else if (isdir) {
8343+ /* the type of lower may be different */
8344+ bdiropq = au_dbdiropq(dentry);
8345+ if (bdiropq >= 0 && bdiropq <= bindex)
8346+ break;
8347+ }
8b6a4947
AM
8348+ br = au_sbr(sb, bindex);
8349+ if (dirren
8350+ && au_dr_hino_test_add(&br->br_dirren, h_inode->i_ino,
8351+ /*add_ent*/NULL)) {
8352+ /* prepare next name to lookup */
8353+ err = au_dr_lkup(&args, dentry, bindex);
8354+ if (unlikely(err))
8355+ goto out_parent;
8356+ }
1facf9fc 8357+ }
8358+
8359+ if (npositive) {
8360+ AuLabel(positive);
5afbbe0d 8361+ au_update_dbtop(dentry);
1facf9fc 8362+ }
8363+ err = npositive;
076b876e 8364+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
5afbbe0d 8365+ && au_dbtop(dentry) < 0)) {
1facf9fc 8366+ err = -EIO;
523b37e3
AM
8367+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
8368+ dentry, err);
027c5e7a 8369+ }
1facf9fc 8370+
4f0767ce 8371+out_parent:
4a4d8108 8372+ dput(parent);
8b6a4947
AM
8373+ kfree(args.whname.name);
8374+ if (dirren)
8375+ au_dr_lkup_fin(&args);
4f0767ce 8376+out:
1facf9fc 8377+ return err;
8378+}
8379+
076b876e 8380+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
1facf9fc 8381+{
8382+ struct dentry *dentry;
8383+ int wkq_err;
8384+
5527c038 8385+ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC))
b4510431 8386+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 8387+ else {
b4510431
AM
8388+ struct vfsub_lkup_one_args args = {
8389+ .errp = &dentry,
8390+ .name = name,
8391+ .parent = parent
1facf9fc 8392+ };
8393+
b4510431 8394+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 8395+ if (unlikely(wkq_err))
8396+ dentry = ERR_PTR(wkq_err);
8397+ }
8398+
8399+ return dentry;
8400+}
8401+
8402+/*
8403+ * lookup @dentry on @bindex which should be negative.
8404+ */
86dc4139 8405+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 8406+{
8407+ int err;
8408+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 8409+ struct au_branch *br;
1facf9fc 8410+
1facf9fc 8411+ parent = dget_parent(dentry);
8412+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
8413+ br = au_sbr(dentry->d_sb, bindex);
8414+ if (wh)
8415+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
8416+ else
076b876e 8417+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 8418+ err = PTR_ERR(h_dentry);
8419+ if (IS_ERR(h_dentry))
8420+ goto out;
5527c038 8421+ if (unlikely(d_is_positive(h_dentry))) {
1facf9fc 8422+ err = -EIO;
523b37e3 8423+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 8424+ dput(h_dentry);
8425+ goto out;
8426+ }
8427+
4a4d8108 8428+ err = 0;
5afbbe0d
AM
8429+ if (bindex < au_dbtop(dentry))
8430+ au_set_dbtop(dentry, bindex);
8431+ if (au_dbbot(dentry) < bindex)
8432+ au_set_dbbot(dentry, bindex);
1facf9fc 8433+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 8434+
4f0767ce 8435+out:
1facf9fc 8436+ dput(parent);
8437+ return err;
8438+}
8439+
8440+/* ---------------------------------------------------------------------- */
8441+
8442+/* subset of struct inode */
8443+struct au_iattr {
8444+ unsigned long i_ino;
8445+ /* unsigned int i_nlink; */
0c3ec466
AM
8446+ kuid_t i_uid;
8447+ kgid_t i_gid;
1facf9fc 8448+ u64 i_version;
8449+/*
8450+ loff_t i_size;
8451+ blkcnt_t i_blocks;
8452+*/
8453+ umode_t i_mode;
8454+};
8455+
8456+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
8457+{
8458+ ia->i_ino = h_inode->i_ino;
8459+ /* ia->i_nlink = h_inode->i_nlink; */
8460+ ia->i_uid = h_inode->i_uid;
8461+ ia->i_gid = h_inode->i_gid;
be118d29 8462+ ia->i_version = inode_query_iversion(h_inode);
1facf9fc 8463+/*
8464+ ia->i_size = h_inode->i_size;
8465+ ia->i_blocks = h_inode->i_blocks;
8466+*/
8467+ ia->i_mode = (h_inode->i_mode & S_IFMT);
8468+}
8469+
8470+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
8471+{
8472+ return ia->i_ino != h_inode->i_ino
8473+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 8474+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 8475+ || !gid_eq(ia->i_gid, h_inode->i_gid)
be118d29 8476+ || !inode_eq_iversion(h_inode, ia->i_version)
1facf9fc 8477+/*
8478+ || ia->i_size != h_inode->i_size
8479+ || ia->i_blocks != h_inode->i_blocks
8480+*/
8481+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
8482+}
8483+
8484+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
8485+ struct au_branch *br)
8486+{
8487+ int err;
8488+ struct au_iattr ia;
8489+ struct inode *h_inode;
8490+ struct dentry *h_d;
8491+ struct super_block *h_sb;
8492+
8493+ err = 0;
8494+ memset(&ia, -1, sizeof(ia));
8495+ h_sb = h_dentry->d_sb;
5527c038
JR
8496+ h_inode = NULL;
8497+ if (d_is_positive(h_dentry)) {
8498+ h_inode = d_inode(h_dentry);
1facf9fc 8499+ au_iattr_save(&ia, h_inode);
5527c038 8500+ } else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
1facf9fc 8501+ /* nfs d_revalidate may return 0 for negative dentry */
8502+ /* fuse d_revalidate always return 0 for negative dentry */
8503+ goto out;
8504+
8505+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 8506+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 8507+ err = PTR_ERR(h_d);
8508+ if (IS_ERR(h_d))
8509+ goto out;
8510+
8511+ err = 0;
8512+ if (unlikely(h_d != h_dentry
5527c038 8513+ || d_inode(h_d) != h_inode
1facf9fc 8514+ || (h_inode && au_iattr_test(&ia, h_inode))))
8515+ err = au_busy_or_stale();
8516+ dput(h_d);
8517+
4f0767ce 8518+out:
1facf9fc 8519+ AuTraceErr(err);
8520+ return err;
8521+}
8522+
8523+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8524+ struct dentry *h_parent, struct au_branch *br)
8525+{
8526+ int err;
8527+
8528+ err = 0;
027c5e7a
AM
8529+ if (udba == AuOpt_UDBA_REVAL
8530+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 8531+ IMustLock(h_dir);
5527c038 8532+ err = (d_inode(h_dentry->d_parent) != h_dir);
027c5e7a 8533+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 8534+ err = au_h_verify_dentry(h_dentry, h_parent, br);
8535+
8536+ return err;
8537+}
8538+
8539+/* ---------------------------------------------------------------------- */
8540+
027c5e7a 8541+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 8542+{
027c5e7a 8543+ int err;
5afbbe0d 8544+ aufs_bindex_t new_bindex, bindex, bbot, bwh, bdiropq;
027c5e7a
AM
8545+ struct au_hdentry tmp, *p, *q;
8546+ struct au_dinfo *dinfo;
8547+ struct super_block *sb;
1facf9fc 8548+
027c5e7a 8549+ DiMustWriteLock(dentry);
1308ab2a 8550+
027c5e7a
AM
8551+ sb = dentry->d_sb;
8552+ dinfo = au_di(dentry);
5afbbe0d 8553+ bbot = dinfo->di_bbot;
1facf9fc 8554+ bwh = dinfo->di_bwh;
8555+ bdiropq = dinfo->di_bdiropq;
5afbbe0d
AM
8556+ bindex = dinfo->di_btop;
8557+ p = au_hdentry(dinfo, bindex);
8558+ for (; bindex <= bbot; bindex++, p++) {
027c5e7a 8559+ if (!p->hd_dentry)
1facf9fc 8560+ continue;
8561+
027c5e7a
AM
8562+ new_bindex = au_br_index(sb, p->hd_id);
8563+ if (new_bindex == bindex)
1facf9fc 8564+ continue;
1facf9fc 8565+
1facf9fc 8566+ if (dinfo->di_bwh == bindex)
8567+ bwh = new_bindex;
8568+ if (dinfo->di_bdiropq == bindex)
8569+ bdiropq = new_bindex;
8570+ if (new_bindex < 0) {
8571+ au_hdput(p);
8572+ p->hd_dentry = NULL;
8573+ continue;
8574+ }
8575+
8576+ /* swap two lower dentries, and loop again */
5afbbe0d 8577+ q = au_hdentry(dinfo, new_bindex);
1facf9fc 8578+ tmp = *q;
8579+ *q = *p;
8580+ *p = tmp;
8581+ if (tmp.hd_dentry) {
8582+ bindex--;
8583+ p--;
8584+ }
8585+ }
8586+
1facf9fc 8587+ dinfo->di_bwh = -1;
5afbbe0d 8588+ if (bwh >= 0 && bwh <= au_sbbot(sb) && au_sbr_whable(sb, bwh))
1facf9fc 8589+ dinfo->di_bwh = bwh;
8590+
8591+ dinfo->di_bdiropq = -1;
8592+ if (bdiropq >= 0
5afbbe0d 8593+ && bdiropq <= au_sbbot(sb)
1facf9fc 8594+ && au_sbr_whable(sb, bdiropq))
8595+ dinfo->di_bdiropq = bdiropq;
8596+
027c5e7a 8597+ err = -EIO;
5afbbe0d
AM
8598+ dinfo->di_btop = -1;
8599+ dinfo->di_bbot = -1;
8600+ bbot = au_dbbot(parent);
8601+ bindex = 0;
8602+ p = au_hdentry(dinfo, bindex);
8603+ for (; bindex <= bbot; bindex++, p++)
1facf9fc 8604+ if (p->hd_dentry) {
5afbbe0d 8605+ dinfo->di_btop = bindex;
1facf9fc 8606+ break;
8607+ }
8608+
5afbbe0d
AM
8609+ if (dinfo->di_btop >= 0) {
8610+ bindex = bbot;
8611+ p = au_hdentry(dinfo, bindex);
8612+ for (; bindex >= 0; bindex--, p--)
027c5e7a 8613+ if (p->hd_dentry) {
5afbbe0d 8614+ dinfo->di_bbot = bindex;
027c5e7a
AM
8615+ err = 0;
8616+ break;
8617+ }
8618+ }
8619+
8620+ return err;
1facf9fc 8621+}
8622+
027c5e7a 8623+static void au_do_hide(struct dentry *dentry)
1facf9fc 8624+{
027c5e7a 8625+ struct inode *inode;
1facf9fc 8626+
5527c038
JR
8627+ if (d_really_is_positive(dentry)) {
8628+ inode = d_inode(dentry);
8629+ if (!d_is_dir(dentry)) {
027c5e7a
AM
8630+ if (inode->i_nlink && !d_unhashed(dentry))
8631+ drop_nlink(inode);
8632+ } else {
8633+ clear_nlink(inode);
8634+ /* stop next lookup */
8635+ inode->i_flags |= S_DEAD;
8636+ }
8637+ smp_mb(); /* necessary? */
8638+ }
8639+ d_drop(dentry);
8640+}
1308ab2a 8641+
027c5e7a
AM
8642+static int au_hide_children(struct dentry *parent)
8643+{
8644+ int err, i, j, ndentry;
8645+ struct au_dcsub_pages dpages;
8646+ struct au_dpage *dpage;
8647+ struct dentry *dentry;
1facf9fc 8648+
027c5e7a 8649+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 8650+ if (unlikely(err))
8651+ goto out;
027c5e7a
AM
8652+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
8653+ if (unlikely(err))
8654+ goto out_dpages;
1facf9fc 8655+
027c5e7a
AM
8656+ /* in reverse order */
8657+ for (i = dpages.ndpage - 1; i >= 0; i--) {
8658+ dpage = dpages.dpages + i;
8659+ ndentry = dpage->ndentry;
8660+ for (j = ndentry - 1; j >= 0; j--) {
8661+ dentry = dpage->dentries[j];
8662+ if (dentry != parent)
8663+ au_do_hide(dentry);
8664+ }
8665+ }
1facf9fc 8666+
027c5e7a
AM
8667+out_dpages:
8668+ au_dpages_free(&dpages);
4f0767ce 8669+out:
027c5e7a 8670+ return err;
1facf9fc 8671+}
8672+
027c5e7a 8673+static void au_hide(struct dentry *dentry)
1facf9fc 8674+{
027c5e7a 8675+ int err;
1facf9fc 8676+
027c5e7a 8677+ AuDbgDentry(dentry);
2000de60 8678+ if (d_is_dir(dentry)) {
027c5e7a
AM
8679+ /* shrink_dcache_parent(dentry); */
8680+ err = au_hide_children(dentry);
8681+ if (unlikely(err))
523b37e3
AM
8682+ AuIOErr("%pd, failed hiding children, ignored %d\n",
8683+ dentry, err);
027c5e7a
AM
8684+ }
8685+ au_do_hide(dentry);
8686+}
1facf9fc 8687+
027c5e7a
AM
8688+/*
8689+ * By adding a dirty branch, a cached dentry may be affected in various ways.
8690+ *
8691+ * a dirty branch is added
8692+ * - on the top of layers
8693+ * - in the middle of layers
8694+ * - to the bottom of layers
8695+ *
8696+ * on the added branch there exists
8697+ * - a whiteout
8698+ * - a diropq
8699+ * - a same named entry
8700+ * + exist
8701+ * * negative --> positive
8702+ * * positive --> positive
8703+ * - type is unchanged
8704+ * - type is changed
8705+ * + doesn't exist
8706+ * * negative --> negative
8707+ * * positive --> negative (rejected by au_br_del() for non-dir case)
8708+ * - none
8709+ */
8710+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
8711+ struct au_dinfo *tmp)
8712+{
8713+ int err;
5afbbe0d 8714+ aufs_bindex_t bindex, bbot;
027c5e7a
AM
8715+ struct {
8716+ struct dentry *dentry;
8717+ struct inode *inode;
8718+ mode_t mode;
be52b249
AM
8719+ } orig_h, tmp_h = {
8720+ .dentry = NULL
8721+ };
027c5e7a
AM
8722+ struct au_hdentry *hd;
8723+ struct inode *inode, *h_inode;
8724+ struct dentry *h_dentry;
8725+
8726+ err = 0;
5afbbe0d 8727+ AuDebugOn(dinfo->di_btop < 0);
027c5e7a 8728+ orig_h.mode = 0;
5afbbe0d 8729+ orig_h.dentry = au_hdentry(dinfo, dinfo->di_btop)->hd_dentry;
5527c038
JR
8730+ orig_h.inode = NULL;
8731+ if (d_is_positive(orig_h.dentry)) {
8732+ orig_h.inode = d_inode(orig_h.dentry);
027c5e7a 8733+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
5527c038 8734+ }
5afbbe0d
AM
8735+ if (tmp->di_btop >= 0) {
8736+ tmp_h.dentry = au_hdentry(tmp, tmp->di_btop)->hd_dentry;
5527c038
JR
8737+ if (d_is_positive(tmp_h.dentry)) {
8738+ tmp_h.inode = d_inode(tmp_h.dentry);
027c5e7a 8739+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
5527c038 8740+ }
027c5e7a
AM
8741+ }
8742+
5527c038
JR
8743+ inode = NULL;
8744+ if (d_really_is_positive(dentry))
8745+ inode = d_inode(dentry);
027c5e7a 8746+ if (!orig_h.inode) {
acd2b654 8747+ AuDbg("negative originally\n");
027c5e7a
AM
8748+ if (inode) {
8749+ au_hide(dentry);
8750+ goto out;
8751+ }
8752+ AuDebugOn(inode);
5afbbe0d 8753+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
027c5e7a
AM
8754+ AuDebugOn(dinfo->di_bdiropq != -1);
8755+
8756+ if (!tmp_h.inode) {
8757+ AuDbg("negative --> negative\n");
8758+ /* should have only one negative lower */
5afbbe0d
AM
8759+ if (tmp->di_btop >= 0
8760+ && tmp->di_btop < dinfo->di_btop) {
8761+ AuDebugOn(tmp->di_btop != tmp->di_bbot);
8762+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
8763+ au_set_h_dptr(dentry, dinfo->di_btop, NULL);
027c5e7a 8764+ au_di_cp(dinfo, tmp);
5afbbe0d
AM
8765+ hd = au_hdentry(tmp, tmp->di_btop);
8766+ au_set_h_dptr(dentry, tmp->di_btop,
027c5e7a
AM
8767+ dget(hd->hd_dentry));
8768+ }
8769+ au_dbg_verify_dinode(dentry);
8770+ } else {
8771+ AuDbg("negative --> positive\n");
8772+ /*
8773+ * similar to the behaviour of creating with bypassing
8774+ * aufs.
8775+ * unhash it in order to force an error in the
8776+ * succeeding create operation.
8777+ * we should not set S_DEAD here.
8778+ */
8779+ d_drop(dentry);
8780+ /* au_di_swap(tmp, dinfo); */
8781+ au_dbg_verify_dinode(dentry);
8782+ }
8783+ } else {
8784+ AuDbg("positive originally\n");
8785+ /* inode may be NULL */
8786+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
8787+ if (!tmp_h.inode) {
8788+ AuDbg("positive --> negative\n");
8789+ /* or bypassing aufs */
8790+ au_hide(dentry);
5afbbe0d 8791+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_btop)
027c5e7a
AM
8792+ dinfo->di_bwh = tmp->di_bwh;
8793+ if (inode)
8794+ err = au_refresh_hinode_self(inode);
8795+ au_dbg_verify_dinode(dentry);
8796+ } else if (orig_h.mode == tmp_h.mode) {
8797+ AuDbg("positive --> positive, same type\n");
8798+ if (!S_ISDIR(orig_h.mode)
5afbbe0d 8799+ && dinfo->di_btop > tmp->di_btop) {
027c5e7a
AM
8800+ /*
8801+ * similar to the behaviour of removing and
8802+ * creating.
8803+ */
8804+ au_hide(dentry);
8805+ if (inode)
8806+ err = au_refresh_hinode_self(inode);
8807+ au_dbg_verify_dinode(dentry);
8808+ } else {
8809+ /* fill empty slots */
5afbbe0d
AM
8810+ if (dinfo->di_btop > tmp->di_btop)
8811+ dinfo->di_btop = tmp->di_btop;
8812+ if (dinfo->di_bbot < tmp->di_bbot)
8813+ dinfo->di_bbot = tmp->di_bbot;
027c5e7a
AM
8814+ dinfo->di_bwh = tmp->di_bwh;
8815+ dinfo->di_bdiropq = tmp->di_bdiropq;
5afbbe0d
AM
8816+ bbot = dinfo->di_bbot;
8817+ bindex = tmp->di_btop;
8818+ hd = au_hdentry(tmp, bindex);
8819+ for (; bindex <= bbot; bindex++, hd++) {
027c5e7a
AM
8820+ if (au_h_dptr(dentry, bindex))
8821+ continue;
5afbbe0d 8822+ h_dentry = hd->hd_dentry;
027c5e7a
AM
8823+ if (!h_dentry)
8824+ continue;
5527c038
JR
8825+ AuDebugOn(d_is_negative(h_dentry));
8826+ h_inode = d_inode(h_dentry);
027c5e7a
AM
8827+ AuDebugOn(orig_h.mode
8828+ != (h_inode->i_mode
8829+ & S_IFMT));
8830+ au_set_h_dptr(dentry, bindex,
8831+ dget(h_dentry));
8832+ }
5afbbe0d
AM
8833+ if (inode)
8834+ err = au_refresh_hinode(inode, dentry);
027c5e7a
AM
8835+ au_dbg_verify_dinode(dentry);
8836+ }
8837+ } else {
8838+ AuDbg("positive --> positive, different type\n");
8839+ /* similar to the behaviour of removing and creating */
8840+ au_hide(dentry);
8841+ if (inode)
8842+ err = au_refresh_hinode_self(inode);
8843+ au_dbg_verify_dinode(dentry);
8844+ }
8845+ }
8846+
8847+out:
8848+ return err;
8849+}
8850+
79b8bda9
AM
8851+void au_refresh_dop(struct dentry *dentry, int force_reval)
8852+{
8853+ const struct dentry_operations *dop
8854+ = force_reval ? &aufs_dop : dentry->d_sb->s_d_op;
8855+ static const unsigned int mask
8856+ = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE;
8857+
8858+ BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags));
8859+
8860+ if (dentry->d_op == dop)
8861+ return;
8862+
8863+ AuDbg("%pd\n", dentry);
8864+ spin_lock(&dentry->d_lock);
8865+ if (dop == &aufs_dop)
8866+ dentry->d_flags |= mask;
8867+ else
8868+ dentry->d_flags &= ~mask;
8869+ dentry->d_op = dop;
8870+ spin_unlock(&dentry->d_lock);
8871+}
8872+
027c5e7a
AM
8873+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
8874+{
e2f27e51 8875+ int err, ebrange, nbr;
027c5e7a
AM
8876+ unsigned int sigen;
8877+ struct au_dinfo *dinfo, *tmp;
8878+ struct super_block *sb;
8879+ struct inode *inode;
8880+
8881+ DiMustWriteLock(dentry);
8882+ AuDebugOn(IS_ROOT(dentry));
5527c038 8883+ AuDebugOn(d_really_is_negative(parent));
027c5e7a
AM
8884+
8885+ sb = dentry->d_sb;
027c5e7a
AM
8886+ sigen = au_sigen(sb);
8887+ err = au_digen_test(parent, sigen);
8888+ if (unlikely(err))
8889+ goto out;
8890+
e2f27e51 8891+ nbr = au_sbbot(sb) + 1;
027c5e7a 8892+ dinfo = au_di(dentry);
e2f27e51 8893+ err = au_di_realloc(dinfo, nbr, /*may_shrink*/0);
027c5e7a
AM
8894+ if (unlikely(err))
8895+ goto out;
8896+ ebrange = au_dbrange_test(dentry);
8897+ if (!ebrange)
8898+ ebrange = au_do_refresh_hdentry(dentry, parent);
8899+
38d290e6 8900+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
5afbbe0d 8901+ AuDebugOn(au_dbtop(dentry) < 0 && au_dbbot(dentry) >= 0);
5527c038
JR
8902+ if (d_really_is_positive(dentry)) {
8903+ inode = d_inode(dentry);
027c5e7a 8904+ err = au_refresh_hinode_self(inode);
5527c038 8905+ }
027c5e7a
AM
8906+ au_dbg_verify_dinode(dentry);
8907+ if (!err)
8908+ goto out_dgen; /* success */
8909+ goto out;
8910+ }
8911+
8912+ /* temporary dinfo */
8913+ AuDbgDentry(dentry);
8914+ err = -ENOMEM;
8915+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
8916+ if (unlikely(!tmp))
8917+ goto out;
8918+ au_di_swap(tmp, dinfo);
8919+ /* returns the number of positive dentries */
8920+ /*
8921+ * if current working dir is removed, it returns an error.
8922+ * but the dentry is legal.
8923+ */
5afbbe0d 8924+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG);
027c5e7a
AM
8925+ AuDbgDentry(dentry);
8926+ au_di_swap(tmp, dinfo);
8927+ if (err == -ENOENT)
8928+ err = 0;
8929+ if (err >= 0) {
8930+ /* compare/refresh by dinfo */
8931+ AuDbgDentry(dentry);
8932+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
8933+ au_dbg_verify_dinode(dentry);
8934+ AuTraceErr(err);
8935+ }
e2f27e51 8936+ au_di_realloc(dinfo, nbr, /*may_shrink*/1); /* harmless if err */
027c5e7a
AM
8937+ au_rw_write_unlock(&tmp->di_rwsem);
8938+ au_di_free(tmp);
8939+ if (unlikely(err))
8940+ goto out;
8941+
8942+out_dgen:
8943+ au_update_digen(dentry);
8944+out:
8945+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 8946+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
8947+ AuDbgDentry(dentry);
8948+ }
8949+ AuTraceErr(err);
8950+ return err;
8951+}
8952+
b4510431
AM
8953+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
8954+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
8955+{
8956+ int err, valid;
027c5e7a
AM
8957+
8958+ err = 0;
8959+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
8960+ goto out;
027c5e7a
AM
8961+
8962+ AuDbg("b%d\n", bindex);
b4510431
AM
8963+ /*
8964+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
8965+ * due to whiteout and branch permission.
8966+ */
8967+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
8968+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
8969+ /* it may return tri-state */
8970+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 8971+
8972+ if (unlikely(valid < 0))
8973+ err = valid;
8974+ else if (!valid)
8975+ err = -EINVAL;
8976+
4f0767ce 8977+out:
1facf9fc 8978+ AuTraceErr(err);
8979+ return err;
8980+}
8981+
8982+/* todo: remove this */
8983+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
8b6a4947 8984+ unsigned int flags, int do_udba, int dirren)
1facf9fc 8985+{
8986+ int err;
8987+ umode_t mode, h_mode;
5afbbe0d 8988+ aufs_bindex_t bindex, btail, btop, ibs, ibe;
38d290e6 8989+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
4a4d8108 8990+ struct inode *h_inode, *h_cached_inode;
1facf9fc 8991+ struct dentry *h_dentry;
8992+ struct qstr *name, *h_name;
8993+
8994+ err = 0;
8995+ plus = 0;
8996+ mode = 0;
1facf9fc 8997+ ibs = -1;
8998+ ibe = -1;
8999+ unhashed = !!d_unhashed(dentry);
9000+ is_root = !!IS_ROOT(dentry);
9001+ name = &dentry->d_name;
38d290e6 9002+ tmpfile = au_di(dentry)->di_tmpfile;
1facf9fc 9003+
9004+ /*
7f207e10
AM
9005+ * Theoretically, REVAL test should be unnecessary in case of
9006+ * {FS,I}NOTIFY.
9007+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 9008+ * IN_ATTRIB for atime/nlink/pageio
1facf9fc 9009+ * Let's do REVAL test too.
9010+ */
9011+ if (do_udba && inode) {
9012+ mode = (inode->i_mode & S_IFMT);
9013+ plus = (inode->i_nlink > 0);
5afbbe0d
AM
9014+ ibs = au_ibtop(inode);
9015+ ibe = au_ibbot(inode);
1facf9fc 9016+ }
9017+
5afbbe0d
AM
9018+ btop = au_dbtop(dentry);
9019+ btail = btop;
1facf9fc 9020+ if (inode && S_ISDIR(inode->i_mode))
9021+ btail = au_dbtaildir(dentry);
5afbbe0d 9022+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 9023+ h_dentry = au_h_dptr(dentry, bindex);
9024+ if (!h_dentry)
9025+ continue;
9026+
523b37e3
AM
9027+ AuDbg("b%d, %pd\n", bindex, h_dentry);
9028+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 9029+ spin_lock(&h_dentry->d_lock);
1facf9fc 9030+ h_name = &h_dentry->d_name;
9031+ if (unlikely(do_udba
9032+ && !is_root
523b37e3
AM
9033+ && ((!h_nfs
9034+ && (unhashed != !!d_unhashed(h_dentry)
8b6a4947 9035+ || (!tmpfile && !dirren
38d290e6
JR
9036+ && !au_qstreq(name, h_name))
9037+ ))
523b37e3
AM
9038+ || (h_nfs
9039+ && !(flags & LOOKUP_OPEN)
9040+ && (h_dentry->d_flags
9041+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 9042+ )) {
38d290e6
JR
9043+ int h_unhashed;
9044+
9045+ h_unhashed = d_unhashed(h_dentry);
027c5e7a 9046+ spin_unlock(&h_dentry->d_lock);
38d290e6
JR
9047+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
9048+ unhashed, h_unhashed, dentry, h_dentry);
1facf9fc 9049+ goto err;
9050+ }
027c5e7a 9051+ spin_unlock(&h_dentry->d_lock);
1facf9fc 9052+
b4510431 9053+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 9054+ if (unlikely(err))
9055+ /* do not goto err, to keep the errno */
9056+ break;
9057+
9058+ /* todo: plink too? */
9059+ if (!do_udba)
9060+ continue;
9061+
9062+ /* UDBA tests */
5527c038 9063+ if (unlikely(!!inode != d_is_positive(h_dentry)))
1facf9fc 9064+ goto err;
9065+
5527c038
JR
9066+ h_inode = NULL;
9067+ if (d_is_positive(h_dentry))
9068+ h_inode = d_inode(h_dentry);
1facf9fc 9069+ h_plus = plus;
9070+ h_mode = mode;
9071+ h_cached_inode = h_inode;
9072+ if (h_inode) {
9073+ h_mode = (h_inode->i_mode & S_IFMT);
9074+ h_plus = (h_inode->i_nlink > 0);
9075+ }
9076+ if (inode && ibs <= bindex && bindex <= ibe)
9077+ h_cached_inode = au_h_iptr(inode, bindex);
9078+
523b37e3 9079+ if (!h_nfs) {
38d290e6 9080+ if (unlikely(plus != h_plus && !tmpfile))
523b37e3
AM
9081+ goto err;
9082+ } else {
9083+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
9084+ && !is_root
9085+ && !IS_ROOT(h_dentry)
9086+ && unhashed != d_unhashed(h_dentry)))
9087+ goto err;
9088+ }
9089+ if (unlikely(mode != h_mode
1facf9fc 9090+ || h_cached_inode != h_inode))
9091+ goto err;
9092+ continue;
9093+
f6b6e03d 9094+err:
1facf9fc 9095+ err = -EINVAL;
9096+ break;
9097+ }
9098+
523b37e3 9099+ AuTraceErr(err);
1facf9fc 9100+ return err;
9101+}
9102+
027c5e7a 9103+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 9104+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
9105+{
9106+ int err;
9107+ struct dentry *parent;
1facf9fc 9108+
027c5e7a 9109+ if (!au_digen_test(dentry, sigen))
1facf9fc 9110+ return 0;
9111+
9112+ parent = dget_parent(dentry);
9113+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 9114+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 9115+ au_dbg_verify_gen(parent, sigen);
027c5e7a 9116+ err = au_refresh_dentry(dentry, parent);
1facf9fc 9117+ di_read_unlock(parent, AuLock_IR);
9118+ dput(parent);
027c5e7a 9119+ AuTraceErr(err);
1facf9fc 9120+ return err;
9121+}
9122+
9123+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
9124+{
9125+ int err;
9126+ struct dentry *d, *parent;
1facf9fc 9127+
027c5e7a 9128+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 9129+ return simple_reval_dpath(dentry, sigen);
9130+
9131+ /* slow loop, keep it simple and stupid */
9132+ /* cf: au_cpup_dirs() */
9133+ err = 0;
9134+ parent = NULL;
027c5e7a 9135+ while (au_digen_test(dentry, sigen)) {
1facf9fc 9136+ d = dentry;
9137+ while (1) {
9138+ dput(parent);
9139+ parent = dget_parent(d);
027c5e7a 9140+ if (!au_digen_test(parent, sigen))
1facf9fc 9141+ break;
9142+ d = parent;
9143+ }
9144+
1facf9fc 9145+ if (d != dentry)
027c5e7a 9146+ di_write_lock_child2(d);
1facf9fc 9147+
9148+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
9149+ if (au_digen_test(d, sigen)) {
9150+ /*
9151+ * todo: consolidate with simple_reval_dpath(),
9152+ * do_refresh() and au_reval_for_attr().
9153+ */
1facf9fc 9154+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 9155+ err = au_refresh_dentry(d, parent);
1facf9fc 9156+ di_read_unlock(parent, AuLock_IR);
9157+ }
9158+
9159+ if (d != dentry)
9160+ di_write_unlock(d);
9161+ dput(parent);
9162+ if (unlikely(err))
9163+ break;
9164+ }
9165+
9166+ return err;
9167+}
9168+
9169+/*
9170+ * if valid returns 1, otherwise 0.
9171+ */
b4510431 9172+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 9173+{
9174+ int valid, err;
9175+ unsigned int sigen;
8b6a4947 9176+ unsigned char do_udba, dirren;
1facf9fc 9177+ struct super_block *sb;
9178+ struct inode *inode;
9179+
027c5e7a 9180+ /* todo: support rcu-walk? */
b4510431 9181+ if (flags & LOOKUP_RCU)
027c5e7a
AM
9182+ return -ECHILD;
9183+
9184+ valid = 0;
9185+ if (unlikely(!au_di(dentry)))
9186+ goto out;
9187+
e49829fe 9188+ valid = 1;
1facf9fc 9189+ sb = dentry->d_sb;
e49829fe
JR
9190+ /*
9191+ * todo: very ugly
9192+ * i_mutex of parent dir may be held,
9193+ * but we should not return 'invalid' due to busy.
9194+ */
9195+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
9196+ if (unlikely(err)) {
9197+ valid = err;
027c5e7a 9198+ AuTraceErr(err);
e49829fe
JR
9199+ goto out;
9200+ }
5527c038
JR
9201+ inode = NULL;
9202+ if (d_really_is_positive(dentry))
9203+ inode = d_inode(dentry);
5afbbe0d 9204+ if (unlikely(inode && au_is_bad_inode(inode))) {
c1595e42
JR
9205+ err = -EINVAL;
9206+ AuTraceErr(err);
9207+ goto out_dgrade;
9208+ }
027c5e7a
AM
9209+ if (unlikely(au_dbrange_test(dentry))) {
9210+ err = -EINVAL;
9211+ AuTraceErr(err);
9212+ goto out_dgrade;
1facf9fc 9213+ }
027c5e7a
AM
9214+
9215+ sigen = au_sigen(sb);
9216+ if (au_digen_test(dentry, sigen)) {
1facf9fc 9217+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
9218+ err = au_reval_dpath(dentry, sigen);
9219+ if (unlikely(err)) {
9220+ AuTraceErr(err);
1facf9fc 9221+ goto out_dgrade;
027c5e7a 9222+ }
1facf9fc 9223+ }
9224+ di_downgrade_lock(dentry, AuLock_IR);
9225+
1facf9fc 9226+ err = -EINVAL;
c1595e42 9227+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
523b37e3 9228+ && inode
38d290e6 9229+ && !(inode->i_state && I_LINKABLE)
79b8bda9
AM
9230+ && (IS_DEADDIR(inode) || !inode->i_nlink)) {
9231+ AuTraceErr(err);
027c5e7a 9232+ goto out_inval;
79b8bda9 9233+ }
027c5e7a 9234+
1facf9fc 9235+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
9236+ if (do_udba && inode) {
5afbbe0d 9237+ aufs_bindex_t btop = au_ibtop(inode);
027c5e7a 9238+ struct inode *h_inode;
1facf9fc 9239+
5afbbe0d
AM
9240+ if (btop >= 0) {
9241+ h_inode = au_h_iptr(inode, btop);
79b8bda9
AM
9242+ if (h_inode && au_test_higen(inode, h_inode)) {
9243+ AuTraceErr(err);
027c5e7a 9244+ goto out_inval;
79b8bda9 9245+ }
027c5e7a 9246+ }
1facf9fc 9247+ }
9248+
8b6a4947
AM
9249+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN);
9250+ err = h_d_revalidate(dentry, inode, flags, do_udba, dirren);
5afbbe0d 9251+ if (unlikely(!err && do_udba && au_dbtop(dentry) < 0)) {
1facf9fc 9252+ err = -EIO;
523b37e3
AM
9253+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
9254+ dentry, err);
027c5e7a 9255+ }
e49829fe 9256+ goto out_inval;
1facf9fc 9257+
4f0767ce 9258+out_dgrade:
1facf9fc 9259+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 9260+out_inval:
1facf9fc 9261+ aufs_read_unlock(dentry, AuLock_IR);
9262+ AuTraceErr(err);
9263+ valid = !err;
e49829fe 9264+out:
027c5e7a 9265+ if (!valid) {
523b37e3 9266+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
9267+ d_drop(dentry);
9268+ }
1facf9fc 9269+ return valid;
9270+}
9271+
9272+static void aufs_d_release(struct dentry *dentry)
9273+{
027c5e7a 9274+ if (au_di(dentry)) {
4a4d8108
AM
9275+ au_di_fin(dentry);
9276+ au_hn_di_reinit(dentry);
1facf9fc 9277+ }
1facf9fc 9278+}
9279+
4a4d8108 9280+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
9281+ .d_revalidate = aufs_d_revalidate,
9282+ .d_weak_revalidate = aufs_d_revalidate,
9283+ .d_release = aufs_d_release
1facf9fc 9284+};
79b8bda9
AM
9285+
9286+/* aufs_dop without d_revalidate */
9287+const struct dentry_operations aufs_dop_noreval = {
9288+ .d_release = aufs_d_release
9289+};
7f207e10
AM
9290diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
9291--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 9292+++ linux/fs/aufs/dentry.h 2018-08-12 23:43:05.453457863 +0200
062440b3
AM
9293@@ -0,0 +1,267 @@
9294+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 9295+/*
b00004a5 9296+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 9297+ *
9298+ * This program, aufs is free software; you can redistribute it and/or modify
9299+ * it under the terms of the GNU General Public License as published by
9300+ * the Free Software Foundation; either version 2 of the License, or
9301+ * (at your option) any later version.
dece6358
AM
9302+ *
9303+ * This program is distributed in the hope that it will be useful,
9304+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9305+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9306+ * GNU General Public License for more details.
9307+ *
9308+ * You should have received a copy of the GNU General Public License
523b37e3 9309+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9310+ */
9311+
9312+/*
9313+ * lookup and dentry operations
9314+ */
9315+
9316+#ifndef __AUFS_DENTRY_H__
9317+#define __AUFS_DENTRY_H__
9318+
9319+#ifdef __KERNEL__
9320+
dece6358 9321+#include <linux/dcache.h>
8b6a4947 9322+#include "dirren.h"
1facf9fc 9323+#include "rwsem.h"
9324+
1facf9fc 9325+struct au_hdentry {
9326+ struct dentry *hd_dentry;
027c5e7a 9327+ aufs_bindex_t hd_id;
1facf9fc 9328+};
9329+
9330+struct au_dinfo {
9331+ atomic_t di_generation;
9332+
dece6358 9333+ struct au_rwsem di_rwsem;
5afbbe0d 9334+ aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq;
38d290e6 9335+ unsigned char di_tmpfile; /* to allow the different name */
1c60b727 9336+ struct au_hdentry *di_hdentry;
4a4d8108 9337+} ____cacheline_aligned_in_smp;
1facf9fc 9338+
9339+/* ---------------------------------------------------------------------- */
9340+
5afbbe0d
AM
9341+/* flags for au_lkup_dentry() */
9342+#define AuLkup_ALLOW_NEG 1
9343+#define AuLkup_IGNORE_PERM (1 << 1)
8b6a4947 9344+#define AuLkup_DIRREN (1 << 2)
5afbbe0d
AM
9345+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
9346+#define au_fset_lkup(flags, name) \
9347+ do { (flags) |= AuLkup_##name; } while (0)
9348+#define au_fclr_lkup(flags, name) \
9349+ do { (flags) &= ~AuLkup_##name; } while (0)
9350+
8b6a4947
AM
9351+#ifndef CONFIG_AUFS_DIRREN
9352+#undef AuLkup_DIRREN
9353+#define AuLkup_DIRREN 0
9354+#endif
9355+
9356+struct au_do_lookup_args {
9357+ unsigned int flags;
9358+ mode_t type;
9359+ struct qstr whname, *name;
9360+ struct au_dr_lookup dirren;
9361+};
9362+
5afbbe0d
AM
9363+/* ---------------------------------------------------------------------- */
9364+
1facf9fc 9365+/* dentry.c */
79b8bda9 9366+extern const struct dentry_operations aufs_dop, aufs_dop_noreval;
1facf9fc 9367+struct au_branch;
076b876e 9368+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
1facf9fc 9369+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
9370+ struct dentry *h_parent, struct au_branch *br);
9371+
5afbbe0d
AM
9372+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
9373+ unsigned int flags);
86dc4139 9374+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 9375+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 9376+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
79b8bda9 9377+void au_refresh_dop(struct dentry *dentry, int force_reval);
1facf9fc 9378+
9379+/* dinfo.c */
4a4d8108 9380+void au_di_init_once(void *_di);
027c5e7a
AM
9381+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
9382+void au_di_free(struct au_dinfo *dinfo);
9383+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
9384+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
9385+int au_di_init(struct dentry *dentry);
9386+void au_di_fin(struct dentry *dentry);
e2f27e51 9387+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink);
1facf9fc 9388+
9389+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
9390+void di_read_unlock(struct dentry *d, int flags);
9391+void di_downgrade_lock(struct dentry *d, int flags);
9392+void di_write_lock(struct dentry *d, unsigned int lsc);
9393+void di_write_unlock(struct dentry *d);
9394+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
9395+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
9396+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
9397+
9398+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 9399+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 9400+aufs_bindex_t au_dbtail(struct dentry *dentry);
9401+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
9402+
9403+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9404+ struct dentry *h_dentry);
027c5e7a
AM
9405+int au_digen_test(struct dentry *dentry, unsigned int sigen);
9406+int au_dbrange_test(struct dentry *dentry);
1facf9fc 9407+void au_update_digen(struct dentry *dentry);
9408+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
5afbbe0d
AM
9409+void au_update_dbtop(struct dentry *dentry);
9410+void au_update_dbbot(struct dentry *dentry);
1facf9fc 9411+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
9412+
9413+/* ---------------------------------------------------------------------- */
9414+
9415+static inline struct au_dinfo *au_di(struct dentry *dentry)
9416+{
9417+ return dentry->d_fsdata;
9418+}
9419+
9420+/* ---------------------------------------------------------------------- */
9421+
9422+/* lock subclass for dinfo */
9423+enum {
9424+ AuLsc_DI_CHILD, /* child first */
4a4d8108 9425+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 9426+ AuLsc_DI_CHILD3, /* copyup dirs */
9427+ AuLsc_DI_PARENT,
9428+ AuLsc_DI_PARENT2,
027c5e7a
AM
9429+ AuLsc_DI_PARENT3,
9430+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 9431+};
9432+
9433+/*
9434+ * di_read_lock_child, di_write_lock_child,
9435+ * di_read_lock_child2, di_write_lock_child2,
9436+ * di_read_lock_child3, di_write_lock_child3,
9437+ * di_read_lock_parent, di_write_lock_parent,
9438+ * di_read_lock_parent2, di_write_lock_parent2,
9439+ * di_read_lock_parent3, di_write_lock_parent3,
9440+ */
9441+#define AuReadLockFunc(name, lsc) \
9442+static inline void di_read_lock_##name(struct dentry *d, int flags) \
9443+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
9444+
9445+#define AuWriteLockFunc(name, lsc) \
9446+static inline void di_write_lock_##name(struct dentry *d) \
9447+{ di_write_lock(d, AuLsc_DI_##lsc); }
9448+
9449+#define AuRWLockFuncs(name, lsc) \
9450+ AuReadLockFunc(name, lsc) \
9451+ AuWriteLockFunc(name, lsc)
9452+
9453+AuRWLockFuncs(child, CHILD);
9454+AuRWLockFuncs(child2, CHILD2);
9455+AuRWLockFuncs(child3, CHILD3);
9456+AuRWLockFuncs(parent, PARENT);
9457+AuRWLockFuncs(parent2, PARENT2);
9458+AuRWLockFuncs(parent3, PARENT3);
9459+
9460+#undef AuReadLockFunc
9461+#undef AuWriteLockFunc
9462+#undef AuRWLockFuncs
9463+
9464+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
9465+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
9466+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 9467+
9468+/* ---------------------------------------------------------------------- */
9469+
9470+/* todo: memory barrier? */
9471+static inline unsigned int au_digen(struct dentry *d)
9472+{
9473+ return atomic_read(&au_di(d)->di_generation);
9474+}
9475+
9476+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
9477+{
9478+ hdentry->hd_dentry = NULL;
9479+}
9480+
5afbbe0d
AM
9481+static inline struct au_hdentry *au_hdentry(struct au_dinfo *di,
9482+ aufs_bindex_t bindex)
9483+{
9484+ return di->di_hdentry + bindex;
9485+}
9486+
1facf9fc 9487+static inline void au_hdput(struct au_hdentry *hd)
9488+{
4a4d8108
AM
9489+ if (hd)
9490+ dput(hd->hd_dentry);
1facf9fc 9491+}
9492+
5afbbe0d 9493+static inline aufs_bindex_t au_dbtop(struct dentry *dentry)
1facf9fc 9494+{
1308ab2a 9495+ DiMustAnyLock(dentry);
5afbbe0d 9496+ return au_di(dentry)->di_btop;
1facf9fc 9497+}
9498+
5afbbe0d 9499+static inline aufs_bindex_t au_dbbot(struct dentry *dentry)
1facf9fc 9500+{
1308ab2a 9501+ DiMustAnyLock(dentry);
5afbbe0d 9502+ return au_di(dentry)->di_bbot;
1facf9fc 9503+}
9504+
9505+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
9506+{
1308ab2a 9507+ DiMustAnyLock(dentry);
1facf9fc 9508+ return au_di(dentry)->di_bwh;
9509+}
9510+
9511+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
9512+{
1308ab2a 9513+ DiMustAnyLock(dentry);
1facf9fc 9514+ return au_di(dentry)->di_bdiropq;
9515+}
9516+
9517+/* todo: hard/soft set? */
5afbbe0d 9518+static inline void au_set_dbtop(struct dentry *dentry, aufs_bindex_t bindex)
1facf9fc 9519+{
1308ab2a 9520+ DiMustWriteLock(dentry);
5afbbe0d 9521+ au_di(dentry)->di_btop = bindex;
1facf9fc 9522+}
9523+
5afbbe0d 9524+static inline void au_set_dbbot(struct dentry *dentry, aufs_bindex_t bindex)
1facf9fc 9525+{
1308ab2a 9526+ DiMustWriteLock(dentry);
5afbbe0d 9527+ au_di(dentry)->di_bbot = bindex;
1facf9fc 9528+}
9529+
9530+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
9531+{
1308ab2a 9532+ DiMustWriteLock(dentry);
5afbbe0d 9533+ /* dbwh can be outside of btop - bbot range */
1facf9fc 9534+ au_di(dentry)->di_bwh = bindex;
9535+}
9536+
9537+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
9538+{
1308ab2a 9539+ DiMustWriteLock(dentry);
1facf9fc 9540+ au_di(dentry)->di_bdiropq = bindex;
9541+}
9542+
9543+/* ---------------------------------------------------------------------- */
9544+
4a4d8108 9545+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 9546+static inline void au_digen_dec(struct dentry *d)
9547+{
e49829fe 9548+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 9549+}
9550+
4a4d8108 9551+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 9552+{
9553+ dentry->d_fsdata = NULL;
9554+}
9555+#else
4a4d8108
AM
9556+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
9557+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 9558+
9559+#endif /* __KERNEL__ */
9560+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
9561diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
9562--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 9563+++ linux/fs/aufs/dinfo.c 2018-08-12 23:43:05.453457863 +0200
062440b3 9564@@ -0,0 +1,554 @@
cd7a4cd9 9565+// SPDX-License-Identifier: GPL-2.0
1facf9fc 9566+/*
b00004a5 9567+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 9568+ *
9569+ * This program, aufs is free software; you can redistribute it and/or modify
9570+ * it under the terms of the GNU General Public License as published by
9571+ * the Free Software Foundation; either version 2 of the License, or
9572+ * (at your option) any later version.
dece6358
AM
9573+ *
9574+ * This program is distributed in the hope that it will be useful,
9575+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9576+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9577+ * GNU General Public License for more details.
9578+ *
9579+ * You should have received a copy of the GNU General Public License
523b37e3 9580+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9581+ */
9582+
9583+/*
9584+ * dentry private data
9585+ */
9586+
9587+#include "aufs.h"
9588+
e49829fe 9589+void au_di_init_once(void *_dinfo)
4a4d8108 9590+{
e49829fe 9591+ struct au_dinfo *dinfo = _dinfo;
4a4d8108 9592+
e49829fe 9593+ au_rw_init(&dinfo->di_rwsem);
4a4d8108
AM
9594+}
9595+
027c5e7a 9596+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 9597+{
9598+ struct au_dinfo *dinfo;
027c5e7a 9599+ int nbr, i;
1facf9fc 9600+
9601+ dinfo = au_cache_alloc_dinfo();
9602+ if (unlikely(!dinfo))
9603+ goto out;
9604+
5afbbe0d 9605+ nbr = au_sbbot(sb) + 1;
1facf9fc 9606+ if (nbr <= 0)
9607+ nbr = 1;
9608+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
9609+ if (dinfo->di_hdentry) {
9610+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
5afbbe0d
AM
9611+ dinfo->di_btop = -1;
9612+ dinfo->di_bbot = -1;
027c5e7a
AM
9613+ dinfo->di_bwh = -1;
9614+ dinfo->di_bdiropq = -1;
38d290e6 9615+ dinfo->di_tmpfile = 0;
027c5e7a
AM
9616+ for (i = 0; i < nbr; i++)
9617+ dinfo->di_hdentry[i].hd_id = -1;
9618+ goto out;
9619+ }
1facf9fc 9620+
1c60b727 9621+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
9622+ dinfo = NULL;
9623+
4f0767ce 9624+out:
027c5e7a 9625+ return dinfo;
1facf9fc 9626+}
9627+
027c5e7a 9628+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 9629+{
4a4d8108 9630+ struct au_hdentry *p;
5afbbe0d 9631+ aufs_bindex_t bbot, bindex;
4a4d8108
AM
9632+
9633+ /* dentry may not be revalidated */
5afbbe0d 9634+ bindex = dinfo->di_btop;
4a4d8108 9635+ if (bindex >= 0) {
5afbbe0d
AM
9636+ bbot = dinfo->di_bbot;
9637+ p = au_hdentry(dinfo, bindex);
9638+ while (bindex++ <= bbot)
4a4d8108
AM
9639+ au_hdput(p++);
9640+ }
1c60b727
AM
9641+ kfree(dinfo->di_hdentry);
9642+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
9643+}
9644+
9645+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
9646+{
9647+ struct au_hdentry *p;
9648+ aufs_bindex_t bi;
9649+
9650+ AuRwMustWriteLock(&a->di_rwsem);
9651+ AuRwMustWriteLock(&b->di_rwsem);
9652+
9653+#define DiSwap(v, name) \
9654+ do { \
9655+ v = a->di_##name; \
9656+ a->di_##name = b->di_##name; \
9657+ b->di_##name = v; \
9658+ } while (0)
9659+
9660+ DiSwap(p, hdentry);
5afbbe0d
AM
9661+ DiSwap(bi, btop);
9662+ DiSwap(bi, bbot);
027c5e7a
AM
9663+ DiSwap(bi, bwh);
9664+ DiSwap(bi, bdiropq);
9665+ /* smp_mb(); */
9666+
9667+#undef DiSwap
9668+}
9669+
9670+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
9671+{
9672+ AuRwMustWriteLock(&dst->di_rwsem);
9673+ AuRwMustWriteLock(&src->di_rwsem);
9674+
5afbbe0d
AM
9675+ dst->di_btop = src->di_btop;
9676+ dst->di_bbot = src->di_bbot;
027c5e7a
AM
9677+ dst->di_bwh = src->di_bwh;
9678+ dst->di_bdiropq = src->di_bdiropq;
9679+ /* smp_mb(); */
9680+}
9681+
9682+int au_di_init(struct dentry *dentry)
9683+{
9684+ int err;
9685+ struct super_block *sb;
9686+ struct au_dinfo *dinfo;
9687+
9688+ err = 0;
9689+ sb = dentry->d_sb;
9690+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
9691+ if (dinfo) {
9692+ atomic_set(&dinfo->di_generation, au_sigen(sb));
9693+ /* smp_mb(); */ /* atomic_set */
9694+ dentry->d_fsdata = dinfo;
9695+ } else
9696+ err = -ENOMEM;
9697+
9698+ return err;
9699+}
9700+
9701+void au_di_fin(struct dentry *dentry)
9702+{
9703+ struct au_dinfo *dinfo;
9704+
9705+ dinfo = au_di(dentry);
9706+ AuRwDestroy(&dinfo->di_rwsem);
9707+ au_di_free(dinfo);
4a4d8108
AM
9708+}
9709+
e2f27e51 9710+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink)
1facf9fc 9711+{
9712+ int err, sz;
9713+ struct au_hdentry *hdp;
9714+
1308ab2a 9715+ AuRwMustWriteLock(&dinfo->di_rwsem);
9716+
1facf9fc 9717+ err = -ENOMEM;
5afbbe0d 9718+ sz = sizeof(*hdp) * (dinfo->di_bbot + 1);
1facf9fc 9719+ if (!sz)
9720+ sz = sizeof(*hdp);
e2f27e51
AM
9721+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS,
9722+ may_shrink);
1facf9fc 9723+ if (hdp) {
9724+ dinfo->di_hdentry = hdp;
9725+ err = 0;
9726+ }
9727+
9728+ return err;
9729+}
9730+
9731+/* ---------------------------------------------------------------------- */
9732+
9733+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
9734+{
9735+ switch (lsc) {
9736+ case AuLsc_DI_CHILD:
9737+ ii_write_lock_child(inode);
9738+ break;
9739+ case AuLsc_DI_CHILD2:
9740+ ii_write_lock_child2(inode);
9741+ break;
9742+ case AuLsc_DI_CHILD3:
9743+ ii_write_lock_child3(inode);
9744+ break;
9745+ case AuLsc_DI_PARENT:
9746+ ii_write_lock_parent(inode);
9747+ break;
9748+ case AuLsc_DI_PARENT2:
9749+ ii_write_lock_parent2(inode);
9750+ break;
9751+ case AuLsc_DI_PARENT3:
9752+ ii_write_lock_parent3(inode);
9753+ break;
9754+ default:
9755+ BUG();
9756+ }
9757+}
9758+
9759+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
9760+{
9761+ switch (lsc) {
9762+ case AuLsc_DI_CHILD:
9763+ ii_read_lock_child(inode);
9764+ break;
9765+ case AuLsc_DI_CHILD2:
9766+ ii_read_lock_child2(inode);
9767+ break;
9768+ case AuLsc_DI_CHILD3:
9769+ ii_read_lock_child3(inode);
9770+ break;
9771+ case AuLsc_DI_PARENT:
9772+ ii_read_lock_parent(inode);
9773+ break;
9774+ case AuLsc_DI_PARENT2:
9775+ ii_read_lock_parent2(inode);
9776+ break;
9777+ case AuLsc_DI_PARENT3:
9778+ ii_read_lock_parent3(inode);
9779+ break;
9780+ default:
9781+ BUG();
9782+ }
9783+}
9784+
9785+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
9786+{
5527c038
JR
9787+ struct inode *inode;
9788+
dece6358 9789+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
5527c038
JR
9790+ if (d_really_is_positive(d)) {
9791+ inode = d_inode(d);
1facf9fc 9792+ if (au_ftest_lock(flags, IW))
5527c038 9793+ do_ii_write_lock(inode, lsc);
1facf9fc 9794+ else if (au_ftest_lock(flags, IR))
5527c038 9795+ do_ii_read_lock(inode, lsc);
1facf9fc 9796+ }
9797+}
9798+
9799+void di_read_unlock(struct dentry *d, int flags)
9800+{
5527c038
JR
9801+ struct inode *inode;
9802+
9803+ if (d_really_is_positive(d)) {
9804+ inode = d_inode(d);
027c5e7a
AM
9805+ if (au_ftest_lock(flags, IW)) {
9806+ au_dbg_verify_dinode(d);
5527c038 9807+ ii_write_unlock(inode);
027c5e7a
AM
9808+ } else if (au_ftest_lock(flags, IR)) {
9809+ au_dbg_verify_dinode(d);
5527c038 9810+ ii_read_unlock(inode);
027c5e7a 9811+ }
1facf9fc 9812+ }
dece6358 9813+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 9814+}
9815+
9816+void di_downgrade_lock(struct dentry *d, int flags)
9817+{
5527c038
JR
9818+ if (d_really_is_positive(d) && au_ftest_lock(flags, IR))
9819+ ii_downgrade_lock(d_inode(d));
dece6358 9820+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 9821+}
9822+
9823+void di_write_lock(struct dentry *d, unsigned int lsc)
9824+{
dece6358 9825+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
5527c038
JR
9826+ if (d_really_is_positive(d))
9827+ do_ii_write_lock(d_inode(d), lsc);
1facf9fc 9828+}
9829+
9830+void di_write_unlock(struct dentry *d)
9831+{
027c5e7a 9832+ au_dbg_verify_dinode(d);
5527c038
JR
9833+ if (d_really_is_positive(d))
9834+ ii_write_unlock(d_inode(d));
dece6358 9835+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 9836+}
9837+
9838+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
9839+{
9840+ AuDebugOn(d1 == d2
5527c038 9841+ || d_inode(d1) == d_inode(d2)
1facf9fc 9842+ || d1->d_sb != d2->d_sb);
9843+
521ced18
JR
9844+ if ((isdir && au_test_subdir(d1, d2))
9845+ || d1 < d2) {
1facf9fc 9846+ di_write_lock_child(d1);
9847+ di_write_lock_child2(d2);
9848+ } else {
1facf9fc 9849+ di_write_lock_child(d2);
9850+ di_write_lock_child2(d1);
9851+ }
9852+}
9853+
9854+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
9855+{
9856+ AuDebugOn(d1 == d2
5527c038 9857+ || d_inode(d1) == d_inode(d2)
1facf9fc 9858+ || d1->d_sb != d2->d_sb);
9859+
521ced18
JR
9860+ if ((isdir && au_test_subdir(d1, d2))
9861+ || d1 < d2) {
1facf9fc 9862+ di_write_lock_parent(d1);
9863+ di_write_lock_parent2(d2);
9864+ } else {
1facf9fc 9865+ di_write_lock_parent(d2);
9866+ di_write_lock_parent2(d1);
9867+ }
9868+}
9869+
9870+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
9871+{
9872+ di_write_unlock(d1);
5527c038 9873+ if (d_inode(d1) == d_inode(d2))
dece6358 9874+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 9875+ else
9876+ di_write_unlock(d2);
9877+}
9878+
9879+/* ---------------------------------------------------------------------- */
9880+
9881+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
9882+{
9883+ struct dentry *d;
9884+
1308ab2a 9885+ DiMustAnyLock(dentry);
9886+
5afbbe0d 9887+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
1facf9fc 9888+ return NULL;
9889+ AuDebugOn(bindex < 0);
5afbbe0d 9890+ d = au_hdentry(au_di(dentry), bindex)->hd_dentry;
c1595e42 9891+ AuDebugOn(d && au_dcount(d) <= 0);
1facf9fc 9892+ return d;
9893+}
9894+
2cbb1c4b
JR
9895+/*
9896+ * extended version of au_h_dptr().
38d290e6
JR
9897+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
9898+ * error.
2cbb1c4b
JR
9899+ */
9900+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
9901+{
9902+ struct dentry *h_dentry;
9903+ struct inode *inode, *h_inode;
9904+
5527c038 9905+ AuDebugOn(d_really_is_negative(dentry));
2cbb1c4b
JR
9906+
9907+ h_dentry = NULL;
5afbbe0d
AM
9908+ if (au_dbtop(dentry) <= bindex
9909+ && bindex <= au_dbbot(dentry))
2cbb1c4b 9910+ h_dentry = au_h_dptr(dentry, bindex);
38d290e6 9911+ if (h_dentry && !au_d_linkable(h_dentry)) {
2cbb1c4b
JR
9912+ dget(h_dentry);
9913+ goto out; /* success */
9914+ }
9915+
5527c038 9916+ inode = d_inode(dentry);
5afbbe0d
AM
9917+ AuDebugOn(bindex < au_ibtop(inode));
9918+ AuDebugOn(au_ibbot(inode) < bindex);
2cbb1c4b
JR
9919+ h_inode = au_h_iptr(inode, bindex);
9920+ h_dentry = d_find_alias(h_inode);
9921+ if (h_dentry) {
9922+ if (!IS_ERR(h_dentry)) {
38d290e6 9923+ if (!au_d_linkable(h_dentry))
2cbb1c4b
JR
9924+ goto out; /* success */
9925+ dput(h_dentry);
9926+ } else
9927+ goto out;
9928+ }
9929+
9930+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
9931+ h_dentry = au_plink_lkup(inode, bindex);
9932+ AuDebugOn(!h_dentry);
9933+ if (!IS_ERR(h_dentry)) {
9934+ if (!au_d_hashed_positive(h_dentry))
9935+ goto out; /* success */
9936+ dput(h_dentry);
9937+ h_dentry = NULL;
9938+ }
9939+ }
9940+
9941+out:
9942+ AuDbgDentry(h_dentry);
9943+ return h_dentry;
9944+}
9945+
1facf9fc 9946+aufs_bindex_t au_dbtail(struct dentry *dentry)
9947+{
5afbbe0d 9948+ aufs_bindex_t bbot, bwh;
1facf9fc 9949+
5afbbe0d
AM
9950+ bbot = au_dbbot(dentry);
9951+ if (0 <= bbot) {
1facf9fc 9952+ bwh = au_dbwh(dentry);
9953+ if (!bwh)
9954+ return bwh;
5afbbe0d 9955+ if (0 < bwh && bwh < bbot)
1facf9fc 9956+ return bwh - 1;
9957+ }
5afbbe0d 9958+ return bbot;
1facf9fc 9959+}
9960+
9961+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
9962+{
5afbbe0d 9963+ aufs_bindex_t bbot, bopq;
1facf9fc 9964+
5afbbe0d
AM
9965+ bbot = au_dbtail(dentry);
9966+ if (0 <= bbot) {
1facf9fc 9967+ bopq = au_dbdiropq(dentry);
5afbbe0d
AM
9968+ if (0 <= bopq && bopq < bbot)
9969+ bbot = bopq;
1facf9fc 9970+ }
5afbbe0d 9971+ return bbot;
1facf9fc 9972+}
9973+
9974+/* ---------------------------------------------------------------------- */
9975+
9976+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9977+ struct dentry *h_dentry)
9978+{
5afbbe0d
AM
9979+ struct au_dinfo *dinfo;
9980+ struct au_hdentry *hd;
027c5e7a 9981+ struct au_branch *br;
1facf9fc 9982+
1308ab2a 9983+ DiMustWriteLock(dentry);
9984+
5afbbe0d
AM
9985+ dinfo = au_di(dentry);
9986+ hd = au_hdentry(dinfo, bindex);
4a4d8108 9987+ au_hdput(hd);
1facf9fc 9988+ hd->hd_dentry = h_dentry;
027c5e7a
AM
9989+ if (h_dentry) {
9990+ br = au_sbr(dentry->d_sb, bindex);
9991+ hd->hd_id = br->br_id;
9992+ }
9993+}
9994+
9995+int au_dbrange_test(struct dentry *dentry)
9996+{
9997+ int err;
5afbbe0d 9998+ aufs_bindex_t btop, bbot;
027c5e7a
AM
9999+
10000+ err = 0;
5afbbe0d
AM
10001+ btop = au_dbtop(dentry);
10002+ bbot = au_dbbot(dentry);
10003+ if (btop >= 0)
10004+ AuDebugOn(bbot < 0 && btop > bbot);
027c5e7a
AM
10005+ else {
10006+ err = -EIO;
5afbbe0d 10007+ AuDebugOn(bbot >= 0);
027c5e7a
AM
10008+ }
10009+
10010+ return err;
10011+}
10012+
10013+int au_digen_test(struct dentry *dentry, unsigned int sigen)
10014+{
10015+ int err;
10016+
10017+ err = 0;
10018+ if (unlikely(au_digen(dentry) != sigen
5527c038 10019+ || au_iigen_test(d_inode(dentry), sigen)))
027c5e7a
AM
10020+ err = -EIO;
10021+
10022+ return err;
1facf9fc 10023+}
10024+
10025+void au_update_digen(struct dentry *dentry)
10026+{
10027+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
10028+ /* smp_mb(); */ /* atomic_set */
10029+}
10030+
10031+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
10032+{
10033+ struct au_dinfo *dinfo;
10034+ struct dentry *h_d;
4a4d8108 10035+ struct au_hdentry *hdp;
5afbbe0d 10036+ aufs_bindex_t bindex, bbot;
1facf9fc 10037+
1308ab2a 10038+ DiMustWriteLock(dentry);
10039+
1facf9fc 10040+ dinfo = au_di(dentry);
5afbbe0d 10041+ if (!dinfo || dinfo->di_btop < 0)
1facf9fc 10042+ return;
10043+
10044+ if (do_put_zero) {
5afbbe0d
AM
10045+ bbot = dinfo->di_bbot;
10046+ bindex = dinfo->di_btop;
10047+ hdp = au_hdentry(dinfo, bindex);
10048+ for (; bindex <= bbot; bindex++, hdp++) {
10049+ h_d = hdp->hd_dentry;
5527c038 10050+ if (h_d && d_is_negative(h_d))
1facf9fc 10051+ au_set_h_dptr(dentry, bindex, NULL);
10052+ }
10053+ }
10054+
5afbbe0d
AM
10055+ dinfo->di_btop = 0;
10056+ hdp = au_hdentry(dinfo, dinfo->di_btop);
10057+ for (; dinfo->di_btop <= dinfo->di_bbot; dinfo->di_btop++, hdp++)
10058+ if (hdp->hd_dentry)
1facf9fc 10059+ break;
5afbbe0d
AM
10060+ if (dinfo->di_btop > dinfo->di_bbot) {
10061+ dinfo->di_btop = -1;
10062+ dinfo->di_bbot = -1;
1facf9fc 10063+ return;
10064+ }
10065+
5afbbe0d
AM
10066+ hdp = au_hdentry(dinfo, dinfo->di_bbot);
10067+ for (; dinfo->di_bbot >= 0; dinfo->di_bbot--, hdp--)
10068+ if (hdp->hd_dentry)
1facf9fc 10069+ break;
5afbbe0d 10070+ AuDebugOn(dinfo->di_btop > dinfo->di_bbot || dinfo->di_bbot < 0);
1facf9fc 10071+}
10072+
5afbbe0d 10073+void au_update_dbtop(struct dentry *dentry)
1facf9fc 10074+{
5afbbe0d 10075+ aufs_bindex_t bindex, bbot;
1facf9fc 10076+ struct dentry *h_dentry;
10077+
5afbbe0d
AM
10078+ bbot = au_dbbot(dentry);
10079+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) {
1facf9fc 10080+ h_dentry = au_h_dptr(dentry, bindex);
10081+ if (!h_dentry)
10082+ continue;
5527c038 10083+ if (d_is_positive(h_dentry)) {
5afbbe0d 10084+ au_set_dbtop(dentry, bindex);
1facf9fc 10085+ return;
10086+ }
10087+ au_set_h_dptr(dentry, bindex, NULL);
10088+ }
10089+}
10090+
5afbbe0d 10091+void au_update_dbbot(struct dentry *dentry)
1facf9fc 10092+{
5afbbe0d 10093+ aufs_bindex_t bindex, btop;
1facf9fc 10094+ struct dentry *h_dentry;
10095+
5afbbe0d
AM
10096+ btop = au_dbtop(dentry);
10097+ for (bindex = au_dbbot(dentry); bindex >= btop; bindex--) {
1facf9fc 10098+ h_dentry = au_h_dptr(dentry, bindex);
10099+ if (!h_dentry)
10100+ continue;
5527c038 10101+ if (d_is_positive(h_dentry)) {
5afbbe0d 10102+ au_set_dbbot(dentry, bindex);
1facf9fc 10103+ return;
10104+ }
10105+ au_set_h_dptr(dentry, bindex, NULL);
10106+ }
10107+}
10108+
10109+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
10110+{
5afbbe0d 10111+ aufs_bindex_t bindex, bbot;
1facf9fc 10112+
5afbbe0d
AM
10113+ bbot = au_dbbot(dentry);
10114+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++)
1facf9fc 10115+ if (au_h_dptr(dentry, bindex) == h_dentry)
10116+ return bindex;
10117+ return -1;
10118+}
7f207e10
AM
10119diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
10120--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
10121+++ linux/fs/aufs/dir.c 2018-10-23 12:33:35.596042364 +0200
10122@@ -0,0 +1,762 @@
cd7a4cd9 10123+// SPDX-License-Identifier: GPL-2.0
1facf9fc 10124+/*
b00004a5 10125+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 10126+ *
10127+ * This program, aufs is free software; you can redistribute it and/or modify
10128+ * it under the terms of the GNU General Public License as published by
10129+ * the Free Software Foundation; either version 2 of the License, or
10130+ * (at your option) any later version.
dece6358
AM
10131+ *
10132+ * This program is distributed in the hope that it will be useful,
10133+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10134+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10135+ * GNU General Public License for more details.
10136+ *
10137+ * You should have received a copy of the GNU General Public License
523b37e3 10138+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10139+ */
10140+
10141+/*
10142+ * directory operations
10143+ */
10144+
10145+#include <linux/fs_stack.h>
10146+#include "aufs.h"
10147+
10148+void au_add_nlink(struct inode *dir, struct inode *h_dir)
10149+{
9dbd164d
AM
10150+ unsigned int nlink;
10151+
1facf9fc 10152+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
10153+
9dbd164d
AM
10154+ nlink = dir->i_nlink;
10155+ nlink += h_dir->i_nlink - 2;
1facf9fc 10156+ if (h_dir->i_nlink < 2)
9dbd164d 10157+ nlink += 2;
f6b6e03d 10158+ smp_mb(); /* for i_nlink */
7eafdf33 10159+ /* 0 can happen in revaliding */
92d182d2 10160+ set_nlink(dir, nlink);
1facf9fc 10161+}
10162+
10163+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
10164+{
9dbd164d
AM
10165+ unsigned int nlink;
10166+
1facf9fc 10167+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
10168+
9dbd164d
AM
10169+ nlink = dir->i_nlink;
10170+ nlink -= h_dir->i_nlink - 2;
1facf9fc 10171+ if (h_dir->i_nlink < 2)
9dbd164d 10172+ nlink -= 2;
f6b6e03d 10173+ smp_mb(); /* for i_nlink */
92d182d2 10174+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 10175+ set_nlink(dir, nlink);
1facf9fc 10176+}
10177+
1308ab2a 10178+loff_t au_dir_size(struct file *file, struct dentry *dentry)
10179+{
10180+ loff_t sz;
5afbbe0d 10181+ aufs_bindex_t bindex, bbot;
1308ab2a 10182+ struct file *h_file;
10183+ struct dentry *h_dentry;
10184+
10185+ sz = 0;
10186+ if (file) {
2000de60 10187+ AuDebugOn(!d_is_dir(file->f_path.dentry));
1308ab2a 10188+
5afbbe0d
AM
10189+ bbot = au_fbbot_dir(file);
10190+ for (bindex = au_fbtop(file);
10191+ bindex <= bbot && sz < KMALLOC_MAX_SIZE;
1308ab2a 10192+ bindex++) {
4a4d8108 10193+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
10194+ if (h_file && file_inode(h_file))
10195+ sz += vfsub_f_size_read(h_file);
1308ab2a 10196+ }
10197+ } else {
10198+ AuDebugOn(!dentry);
2000de60 10199+ AuDebugOn(!d_is_dir(dentry));
1308ab2a 10200+
5afbbe0d
AM
10201+ bbot = au_dbtaildir(dentry);
10202+ for (bindex = au_dbtop(dentry);
10203+ bindex <= bbot && sz < KMALLOC_MAX_SIZE;
1308ab2a 10204+ bindex++) {
10205+ h_dentry = au_h_dptr(dentry, bindex);
5527c038
JR
10206+ if (h_dentry && d_is_positive(h_dentry))
10207+ sz += i_size_read(d_inode(h_dentry));
1308ab2a 10208+ }
10209+ }
10210+ if (sz < KMALLOC_MAX_SIZE)
10211+ sz = roundup_pow_of_two(sz);
10212+ if (sz > KMALLOC_MAX_SIZE)
10213+ sz = KMALLOC_MAX_SIZE;
10214+ else if (sz < NAME_MAX) {
10215+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
10216+ sz = AUFS_RDBLK_DEF;
10217+ }
10218+ return sz;
10219+}
10220+
b912730e
AM
10221+struct au_dir_ts_arg {
10222+ struct dentry *dentry;
10223+ aufs_bindex_t brid;
10224+};
10225+
10226+static void au_do_dir_ts(void *arg)
10227+{
10228+ struct au_dir_ts_arg *a = arg;
10229+ struct au_dtime dt;
10230+ struct path h_path;
10231+ struct inode *dir, *h_dir;
10232+ struct super_block *sb;
10233+ struct au_branch *br;
10234+ struct au_hinode *hdir;
10235+ int err;
5afbbe0d 10236+ aufs_bindex_t btop, bindex;
b912730e
AM
10237+
10238+ sb = a->dentry->d_sb;
5527c038 10239+ if (d_really_is_negative(a->dentry))
b912730e 10240+ goto out;
5527c038 10241+ /* no dir->i_mutex lock */
b95c5147
AM
10242+ aufs_read_lock(a->dentry, AuLock_DW); /* noflush */
10243+
5527c038 10244+ dir = d_inode(a->dentry);
5afbbe0d 10245+ btop = au_ibtop(dir);
b912730e 10246+ bindex = au_br_index(sb, a->brid);
5afbbe0d 10247+ if (bindex < btop)
b912730e
AM
10248+ goto out_unlock;
10249+
10250+ br = au_sbr(sb, bindex);
10251+ h_path.dentry = au_h_dptr(a->dentry, bindex);
10252+ if (!h_path.dentry)
10253+ goto out_unlock;
10254+ h_path.mnt = au_br_mnt(br);
10255+ au_dtime_store(&dt, a->dentry, &h_path);
10256+
5afbbe0d 10257+ br = au_sbr(sb, btop);
b912730e
AM
10258+ if (!au_br_writable(br->br_perm))
10259+ goto out_unlock;
5afbbe0d 10260+ h_path.dentry = au_h_dptr(a->dentry, btop);
b912730e
AM
10261+ h_path.mnt = au_br_mnt(br);
10262+ err = vfsub_mnt_want_write(h_path.mnt);
10263+ if (err)
10264+ goto out_unlock;
5afbbe0d
AM
10265+ hdir = au_hi(dir, btop);
10266+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
10267+ h_dir = au_h_iptr(dir, btop);
b912730e 10268+ if (h_dir->i_nlink
cd7a4cd9 10269+ && timespec64_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) {
b912730e
AM
10270+ dt.dt_h_path = h_path;
10271+ au_dtime_revert(&dt);
10272+ }
5afbbe0d 10273+ au_hn_inode_unlock(hdir);
b912730e
AM
10274+ vfsub_mnt_drop_write(h_path.mnt);
10275+ au_cpup_attr_timesizes(dir);
10276+
10277+out_unlock:
10278+ aufs_read_unlock(a->dentry, AuLock_DW);
10279+out:
10280+ dput(a->dentry);
10281+ au_nwt_done(&au_sbi(sb)->si_nowait);
1c60b727 10282+ kfree(arg);
b912730e
AM
10283+}
10284+
10285+void au_dir_ts(struct inode *dir, aufs_bindex_t bindex)
10286+{
10287+ int perm, wkq_err;
5afbbe0d 10288+ aufs_bindex_t btop;
b912730e
AM
10289+ struct au_dir_ts_arg *arg;
10290+ struct dentry *dentry;
10291+ struct super_block *sb;
10292+
10293+ IMustLock(dir);
10294+
10295+ dentry = d_find_any_alias(dir);
10296+ AuDebugOn(!dentry);
10297+ sb = dentry->d_sb;
5afbbe0d
AM
10298+ btop = au_ibtop(dir);
10299+ if (btop == bindex) {
b912730e
AM
10300+ au_cpup_attr_timesizes(dir);
10301+ goto out;
10302+ }
10303+
5afbbe0d 10304+ perm = au_sbr_perm(sb, btop);
b912730e
AM
10305+ if (!au_br_writable(perm))
10306+ goto out;
10307+
10308+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
10309+ if (!arg)
10310+ goto out;
10311+
10312+ arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */
10313+ arg->brid = au_sbr_id(sb, bindex);
10314+ wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0);
10315+ if (unlikely(wkq_err)) {
10316+ pr_err("wkq %d\n", wkq_err);
10317+ dput(dentry);
1c60b727 10318+ kfree(arg);
b912730e
AM
10319+ }
10320+
10321+out:
10322+ dput(dentry);
10323+}
10324+
1facf9fc 10325+/* ---------------------------------------------------------------------- */
10326+
10327+static int reopen_dir(struct file *file)
10328+{
10329+ int err;
10330+ unsigned int flags;
5afbbe0d 10331+ aufs_bindex_t bindex, btail, btop;
1facf9fc 10332+ struct dentry *dentry, *h_dentry;
10333+ struct file *h_file;
10334+
10335+ /* open all lower dirs */
2000de60 10336+ dentry = file->f_path.dentry;
5afbbe0d
AM
10337+ btop = au_dbtop(dentry);
10338+ for (bindex = au_fbtop(file); bindex < btop; bindex++)
1facf9fc 10339+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d 10340+ au_set_fbtop(file, btop);
1facf9fc 10341+
10342+ btail = au_dbtaildir(dentry);
5afbbe0d 10343+ for (bindex = au_fbbot_dir(file); btail < bindex; bindex--)
1facf9fc 10344+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d 10345+ au_set_fbbot_dir(file, btail);
1facf9fc 10346+
4a4d8108 10347+ flags = vfsub_file_flags(file);
5afbbe0d 10348+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 10349+ h_dentry = au_h_dptr(dentry, bindex);
10350+ if (!h_dentry)
10351+ continue;
4a4d8108 10352+ h_file = au_hf_dir(file, bindex);
1facf9fc 10353+ if (h_file)
10354+ continue;
10355+
392086de 10356+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 10357+ err = PTR_ERR(h_file);
10358+ if (IS_ERR(h_file))
10359+ goto out; /* close all? */
10360+ au_set_h_fptr(file, bindex, h_file);
10361+ }
10362+ au_update_figen(file);
10363+ /* todo: necessary? */
10364+ /* file->f_ra = h_file->f_ra; */
10365+ err = 0;
10366+
4f0767ce 10367+out:
1facf9fc 10368+ return err;
10369+}
10370+
b912730e 10371+static int do_open_dir(struct file *file, int flags, struct file *h_file)
1facf9fc 10372+{
10373+ int err;
10374+ aufs_bindex_t bindex, btail;
10375+ struct dentry *dentry, *h_dentry;
8cdd5066 10376+ struct vfsmount *mnt;
1facf9fc 10377+
1308ab2a 10378+ FiMustWriteLock(file);
b912730e 10379+ AuDebugOn(h_file);
1308ab2a 10380+
523b37e3 10381+ err = 0;
8cdd5066 10382+ mnt = file->f_path.mnt;
2000de60 10383+ dentry = file->f_path.dentry;
be118d29 10384+ file->f_version = inode_query_iversion(d_inode(dentry));
5afbbe0d
AM
10385+ bindex = au_dbtop(dentry);
10386+ au_set_fbtop(file, bindex);
1facf9fc 10387+ btail = au_dbtaildir(dentry);
5afbbe0d 10388+ au_set_fbbot_dir(file, btail);
1facf9fc 10389+ for (; !err && bindex <= btail; bindex++) {
10390+ h_dentry = au_h_dptr(dentry, bindex);
10391+ if (!h_dentry)
10392+ continue;
10393+
8cdd5066
JR
10394+ err = vfsub_test_mntns(mnt, h_dentry->d_sb);
10395+ if (unlikely(err))
10396+ break;
392086de 10397+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 10398+ if (IS_ERR(h_file)) {
10399+ err = PTR_ERR(h_file);
10400+ break;
10401+ }
10402+ au_set_h_fptr(file, bindex, h_file);
10403+ }
10404+ au_update_figen(file);
10405+ /* todo: necessary? */
10406+ /* file->f_ra = h_file->f_ra; */
10407+ if (!err)
10408+ return 0; /* success */
10409+
10410+ /* close all */
5afbbe0d 10411+ for (bindex = au_fbtop(file); bindex <= btail; bindex++)
1facf9fc 10412+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d
AM
10413+ au_set_fbtop(file, -1);
10414+ au_set_fbbot_dir(file, -1);
4a4d8108 10415+
1facf9fc 10416+ return err;
10417+}
10418+
10419+static int aufs_open_dir(struct inode *inode __maybe_unused,
10420+ struct file *file)
10421+{
4a4d8108
AM
10422+ int err;
10423+ struct super_block *sb;
10424+ struct au_fidir *fidir;
10425+
10426+ err = -ENOMEM;
2000de60 10427+ sb = file->f_path.dentry->d_sb;
4a4d8108 10428+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 10429+ fidir = au_fidir_alloc(sb);
4a4d8108 10430+ if (fidir) {
b912730e
AM
10431+ struct au_do_open_args args = {
10432+ .open = do_open_dir,
10433+ .fidir = fidir
10434+ };
10435+ err = au_do_open(file, &args);
4a4d8108 10436+ if (unlikely(err))
1c60b727 10437+ kfree(fidir);
4a4d8108
AM
10438+ }
10439+ si_read_unlock(sb);
10440+ return err;
1facf9fc 10441+}
10442+
10443+static int aufs_release_dir(struct inode *inode __maybe_unused,
10444+ struct file *file)
10445+{
10446+ struct au_vdir *vdir_cache;
4a4d8108
AM
10447+ struct au_finfo *finfo;
10448+ struct au_fidir *fidir;
f0c0a007 10449+ struct au_hfile *hf;
5afbbe0d 10450+ aufs_bindex_t bindex, bbot;
1facf9fc 10451+
4a4d8108
AM
10452+ finfo = au_fi(file);
10453+ fidir = finfo->fi_hdir;
10454+ if (fidir) {
8b6a4947
AM
10455+ au_hbl_del(&finfo->fi_hlist,
10456+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108
AM
10457+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
10458+ if (vdir_cache)
1c60b727 10459+ au_vdir_free(vdir_cache);
4a4d8108
AM
10460+
10461+ bindex = finfo->fi_btop;
10462+ if (bindex >= 0) {
f0c0a007 10463+ hf = fidir->fd_hfile + bindex;
4a4d8108
AM
10464+ /*
10465+ * calls fput() instead of filp_close(),
10466+ * since no dnotify or lock for the lower file.
10467+ */
5afbbe0d 10468+ bbot = fidir->fd_bbot;
f0c0a007
AM
10469+ for (; bindex <= bbot; bindex++, hf++)
10470+ if (hf->hf_file)
1c60b727 10471+ au_hfput(hf, /*execed*/0);
4a4d8108 10472+ }
1c60b727 10473+ kfree(fidir);
4a4d8108 10474+ finfo->fi_hdir = NULL;
1facf9fc 10475+ }
1c60b727 10476+ au_finfo_fin(file);
1facf9fc 10477+ return 0;
10478+}
10479+
10480+/* ---------------------------------------------------------------------- */
10481+
4a4d8108
AM
10482+static int au_do_flush_dir(struct file *file, fl_owner_t id)
10483+{
10484+ int err;
5afbbe0d 10485+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
10486+ struct file *h_file;
10487+
10488+ err = 0;
5afbbe0d
AM
10489+ bbot = au_fbbot_dir(file);
10490+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) {
4a4d8108
AM
10491+ h_file = au_hf_dir(file, bindex);
10492+ if (h_file)
10493+ err = vfsub_flush(h_file, id);
10494+ }
10495+ return err;
10496+}
10497+
10498+static int aufs_flush_dir(struct file *file, fl_owner_t id)
10499+{
10500+ return au_do_flush(file, id, au_do_flush_dir);
10501+}
10502+
10503+/* ---------------------------------------------------------------------- */
10504+
1facf9fc 10505+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
10506+{
10507+ int err;
5afbbe0d 10508+ aufs_bindex_t bbot, bindex;
1facf9fc 10509+ struct inode *inode;
10510+ struct super_block *sb;
10511+
10512+ err = 0;
10513+ sb = dentry->d_sb;
5527c038 10514+ inode = d_inode(dentry);
1facf9fc 10515+ IMustLock(inode);
5afbbe0d
AM
10516+ bbot = au_dbbot(dentry);
10517+ for (bindex = au_dbtop(dentry); !err && bindex <= bbot; bindex++) {
1facf9fc 10518+ struct path h_path;
1facf9fc 10519+
10520+ if (au_test_ro(sb, bindex, inode))
10521+ continue;
10522+ h_path.dentry = au_h_dptr(dentry, bindex);
10523+ if (!h_path.dentry)
10524+ continue;
1facf9fc 10525+
1facf9fc 10526+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 10527+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 10528+ }
10529+
10530+ return err;
10531+}
10532+
10533+static int au_do_fsync_dir(struct file *file, int datasync)
10534+{
10535+ int err;
5afbbe0d 10536+ aufs_bindex_t bbot, bindex;
1facf9fc 10537+ struct file *h_file;
10538+ struct super_block *sb;
10539+ struct inode *inode;
1facf9fc 10540+
521ced18 10541+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0);
1facf9fc 10542+ if (unlikely(err))
10543+ goto out;
10544+
c06a8ce3 10545+ inode = file_inode(file);
b912730e 10546+ sb = inode->i_sb;
5afbbe0d
AM
10547+ bbot = au_fbbot_dir(file);
10548+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) {
4a4d8108 10549+ h_file = au_hf_dir(file, bindex);
1facf9fc 10550+ if (!h_file || au_test_ro(sb, bindex, inode))
10551+ continue;
10552+
53392da6 10553+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 10554+ }
10555+
4f0767ce 10556+out:
1facf9fc 10557+ return err;
10558+}
10559+
10560+/*
10561+ * @file may be NULL
10562+ */
1e00d052
AM
10563+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
10564+ int datasync)
1facf9fc 10565+{
10566+ int err;
b752ccd1 10567+ struct dentry *dentry;
5527c038 10568+ struct inode *inode;
1facf9fc 10569+ struct super_block *sb;
1facf9fc 10570+
10571+ err = 0;
2000de60 10572+ dentry = file->f_path.dentry;
5527c038 10573+ inode = d_inode(dentry);
febd17d6 10574+ inode_lock(inode);
1facf9fc 10575+ sb = dentry->d_sb;
10576+ si_noflush_read_lock(sb);
10577+ if (file)
10578+ err = au_do_fsync_dir(file, datasync);
10579+ else {
10580+ di_write_lock_child(dentry);
10581+ err = au_do_fsync_dir_no_file(dentry, datasync);
10582+ }
5527c038 10583+ au_cpup_attr_timesizes(inode);
1facf9fc 10584+ di_write_unlock(dentry);
10585+ if (file)
10586+ fi_write_unlock(file);
10587+
10588+ si_read_unlock(sb);
febd17d6 10589+ inode_unlock(inode);
1facf9fc 10590+ return err;
10591+}
10592+
10593+/* ---------------------------------------------------------------------- */
10594+
5afbbe0d 10595+static int aufs_iterate_shared(struct file *file, struct dir_context *ctx)
1facf9fc 10596+{
10597+ int err;
10598+ struct dentry *dentry;
9dbd164d 10599+ struct inode *inode, *h_inode;
1facf9fc 10600+ struct super_block *sb;
10601+
062440b3 10602+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos);
392086de 10603+
2000de60 10604+ dentry = file->f_path.dentry;
5527c038 10605+ inode = d_inode(dentry);
1facf9fc 10606+ IMustLock(inode);
10607+
10608+ sb = dentry->d_sb;
10609+ si_read_lock(sb, AuLock_FLUSH);
521ced18 10610+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0);
1facf9fc 10611+ if (unlikely(err))
10612+ goto out;
027c5e7a
AM
10613+ err = au_alive_dir(dentry);
10614+ if (!err)
10615+ err = au_vdir_init(file);
1facf9fc 10616+ di_downgrade_lock(dentry, AuLock_IR);
10617+ if (unlikely(err))
10618+ goto out_unlock;
10619+
5afbbe0d 10620+ h_inode = au_h_iptr(inode, au_ibtop(inode));
b752ccd1 10621+ if (!au_test_nfsd()) {
392086de 10622+ err = au_vdir_fill_de(file, ctx);
9dbd164d 10623+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 10624+ } else {
10625+ /*
10626+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
10627+ * encode_fh() and others.
10628+ */
9dbd164d 10629+ atomic_inc(&h_inode->i_count);
1facf9fc 10630+ di_read_unlock(dentry, AuLock_IR);
10631+ si_read_unlock(sb);
392086de 10632+ err = au_vdir_fill_de(file, ctx);
1facf9fc 10633+ fsstack_copy_attr_atime(inode, h_inode);
10634+ fi_write_unlock(file);
9dbd164d 10635+ iput(h_inode);
1facf9fc 10636+
10637+ AuTraceErr(err);
10638+ return err;
10639+ }
10640+
4f0767ce 10641+out_unlock:
1facf9fc 10642+ di_read_unlock(dentry, AuLock_IR);
10643+ fi_write_unlock(file);
4f0767ce 10644+out:
1facf9fc 10645+ si_read_unlock(sb);
10646+ return err;
10647+}
10648+
10649+/* ---------------------------------------------------------------------- */
10650+
10651+#define AuTestEmpty_WHONLY 1
dece6358
AM
10652+#define AuTestEmpty_CALLED (1 << 1)
10653+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 10654+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
10655+#define au_fset_testempty(flags, name) \
10656+ do { (flags) |= AuTestEmpty_##name; } while (0)
10657+#define au_fclr_testempty(flags, name) \
10658+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 10659+
dece6358
AM
10660+#ifndef CONFIG_AUFS_SHWH
10661+#undef AuTestEmpty_SHWH
10662+#define AuTestEmpty_SHWH 0
10663+#endif
10664+
1facf9fc 10665+struct test_empty_arg {
392086de 10666+ struct dir_context ctx;
1308ab2a 10667+ struct au_nhash *whlist;
1facf9fc 10668+ unsigned int flags;
10669+ int err;
10670+ aufs_bindex_t bindex;
10671+};
10672+
392086de
AM
10673+static int test_empty_cb(struct dir_context *ctx, const char *__name,
10674+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 10675+ unsigned int d_type)
1facf9fc 10676+{
392086de
AM
10677+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
10678+ ctx);
1facf9fc 10679+ char *name = (void *)__name;
10680+
10681+ arg->err = 0;
10682+ au_fset_testempty(arg->flags, CALLED);
10683+ /* smp_mb(); */
10684+ if (name[0] == '.'
10685+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
10686+ goto out; /* success */
10687+
10688+ if (namelen <= AUFS_WH_PFX_LEN
10689+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
10690+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 10691+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 10692+ arg->err = -ENOTEMPTY;
10693+ goto out;
10694+ }
10695+
10696+ name += AUFS_WH_PFX_LEN;
10697+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 10698+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 10699+ arg->err = au_nhash_append_wh
1308ab2a 10700+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 10701+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 10702+
4f0767ce 10703+out:
1facf9fc 10704+ /* smp_mb(); */
10705+ AuTraceErr(arg->err);
10706+ return arg->err;
10707+}
10708+
10709+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
10710+{
10711+ int err;
10712+ struct file *h_file;
acd2b654 10713+ struct au_branch *br;
1facf9fc 10714+
10715+ h_file = au_h_open(dentry, arg->bindex,
10716+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 10717+ /*file*/NULL, /*force_wr*/0);
1facf9fc 10718+ err = PTR_ERR(h_file);
10719+ if (IS_ERR(h_file))
10720+ goto out;
10721+
10722+ err = 0;
10723+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 10724+ && !file_inode(h_file)->i_nlink)
1facf9fc 10725+ goto out_put;
10726+
10727+ do {
10728+ arg->err = 0;
10729+ au_fclr_testempty(arg->flags, CALLED);
10730+ /* smp_mb(); */
392086de 10731+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 10732+ if (err >= 0)
10733+ err = arg->err;
10734+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
10735+
4f0767ce 10736+out_put:
1facf9fc 10737+ fput(h_file);
acd2b654
AM
10738+ br = au_sbr(dentry->d_sb, arg->bindex);
10739+ au_lcnt_dec(&br->br_nfiles);
4f0767ce 10740+out:
1facf9fc 10741+ return err;
10742+}
10743+
10744+struct do_test_empty_args {
10745+ int *errp;
10746+ struct dentry *dentry;
10747+ struct test_empty_arg *arg;
10748+};
10749+
10750+static void call_do_test_empty(void *args)
10751+{
10752+ struct do_test_empty_args *a = args;
10753+ *a->errp = do_test_empty(a->dentry, a->arg);
10754+}
10755+
10756+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
10757+{
10758+ int err, wkq_err;
10759+ struct dentry *h_dentry;
10760+ struct inode *h_inode;
10761+
10762+ h_dentry = au_h_dptr(dentry, arg->bindex);
5527c038 10763+ h_inode = d_inode(h_dentry);
53392da6 10764+ /* todo: i_mode changes anytime? */
be118d29 10765+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD);
1facf9fc 10766+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
3c1bdaff 10767+ inode_unlock_shared(h_inode);
1facf9fc 10768+ if (!err)
10769+ err = do_test_empty(dentry, arg);
10770+ else {
10771+ struct do_test_empty_args args = {
10772+ .errp = &err,
10773+ .dentry = dentry,
10774+ .arg = arg
10775+ };
10776+ unsigned int flags = arg->flags;
10777+
10778+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
10779+ if (unlikely(wkq_err))
10780+ err = wkq_err;
10781+ arg->flags = flags;
10782+ }
10783+
10784+ return err;
10785+}
10786+
10787+int au_test_empty_lower(struct dentry *dentry)
10788+{
10789+ int err;
1308ab2a 10790+ unsigned int rdhash;
5afbbe0d 10791+ aufs_bindex_t bindex, btop, btail;
1308ab2a 10792+ struct au_nhash whlist;
392086de
AM
10793+ struct test_empty_arg arg = {
10794+ .ctx = {
2000de60 10795+ .actor = test_empty_cb
392086de
AM
10796+ }
10797+ };
076b876e 10798+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
1facf9fc 10799+
dece6358
AM
10800+ SiMustAnyLock(dentry->d_sb);
10801+
1308ab2a 10802+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
10803+ if (!rdhash)
10804+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
10805+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 10806+ if (unlikely(err))
1facf9fc 10807+ goto out;
10808+
1facf9fc 10809+ arg.flags = 0;
1308ab2a 10810+ arg.whlist = &whlist;
5afbbe0d 10811+ btop = au_dbtop(dentry);
dece6358
AM
10812+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10813+ au_fset_testempty(arg.flags, SHWH);
076b876e
AM
10814+ test_empty = do_test_empty;
10815+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
10816+ test_empty = sio_test_empty;
5afbbe0d 10817+ arg.bindex = btop;
076b876e 10818+ err = test_empty(dentry, &arg);
1facf9fc 10819+ if (unlikely(err))
10820+ goto out_whlist;
10821+
10822+ au_fset_testempty(arg.flags, WHONLY);
10823+ btail = au_dbtaildir(dentry);
5afbbe0d 10824+ for (bindex = btop + 1; !err && bindex <= btail; bindex++) {
1facf9fc 10825+ struct dentry *h_dentry;
10826+
10827+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 10828+ if (h_dentry && d_is_positive(h_dentry)) {
1facf9fc 10829+ arg.bindex = bindex;
076b876e 10830+ err = test_empty(dentry, &arg);
1facf9fc 10831+ }
10832+ }
10833+
4f0767ce 10834+out_whlist:
1308ab2a 10835+ au_nhash_wh_free(&whlist);
4f0767ce 10836+out:
1facf9fc 10837+ return err;
10838+}
10839+
10840+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
10841+{
10842+ int err;
392086de
AM
10843+ struct test_empty_arg arg = {
10844+ .ctx = {
2000de60 10845+ .actor = test_empty_cb
392086de
AM
10846+ }
10847+ };
1facf9fc 10848+ aufs_bindex_t bindex, btail;
10849+
10850+ err = 0;
1308ab2a 10851+ arg.whlist = whlist;
1facf9fc 10852+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
10853+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10854+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 10855+ btail = au_dbtaildir(dentry);
5afbbe0d 10856+ for (bindex = au_dbtop(dentry); !err && bindex <= btail; bindex++) {
1facf9fc 10857+ struct dentry *h_dentry;
10858+
10859+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 10860+ if (h_dentry && d_is_positive(h_dentry)) {
1facf9fc 10861+ arg.bindex = bindex;
10862+ err = sio_test_empty(dentry, &arg);
10863+ }
10864+ }
10865+
10866+ return err;
10867+}
10868+
10869+/* ---------------------------------------------------------------------- */
10870+
10871+const struct file_operations aufs_dir_fop = {
4a4d8108 10872+ .owner = THIS_MODULE,
027c5e7a 10873+ .llseek = default_llseek,
1facf9fc 10874+ .read = generic_read_dir,
5afbbe0d 10875+ .iterate_shared = aufs_iterate_shared,
1facf9fc 10876+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
10877+#ifdef CONFIG_COMPAT
10878+ .compat_ioctl = aufs_compat_ioctl_dir,
10879+#endif
1facf9fc 10880+ .open = aufs_open_dir,
10881+ .release = aufs_release_dir,
4a4d8108 10882+ .flush = aufs_flush_dir,
1facf9fc 10883+ .fsync = aufs_fsync_dir
10884+};
7f207e10
AM
10885diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
10886--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 10887+++ linux/fs/aufs/dir.h 2018-08-12 23:43:05.453457863 +0200
062440b3
AM
10888@@ -0,0 +1,132 @@
10889+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 10890+/*
b00004a5 10891+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 10892+ *
10893+ * This program, aufs is free software; you can redistribute it and/or modify
10894+ * it under the terms of the GNU General Public License as published by
10895+ * the Free Software Foundation; either version 2 of the License, or
10896+ * (at your option) any later version.
dece6358
AM
10897+ *
10898+ * This program is distributed in the hope that it will be useful,
10899+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10900+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10901+ * GNU General Public License for more details.
10902+ *
10903+ * You should have received a copy of the GNU General Public License
523b37e3 10904+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10905+ */
10906+
10907+/*
10908+ * directory operations
10909+ */
10910+
10911+#ifndef __AUFS_DIR_H__
10912+#define __AUFS_DIR_H__
10913+
10914+#ifdef __KERNEL__
10915+
10916+#include <linux/fs.h>
1facf9fc 10917+
10918+/* ---------------------------------------------------------------------- */
10919+
10920+/* need to be faster and smaller */
10921+
10922+struct au_nhash {
dece6358
AM
10923+ unsigned int nh_num;
10924+ struct hlist_head *nh_head;
1facf9fc 10925+};
10926+
10927+struct au_vdir_destr {
10928+ unsigned char len;
10929+ unsigned char name[0];
10930+} __packed;
10931+
10932+struct au_vdir_dehstr {
10933+ struct hlist_node hash;
1c60b727 10934+ struct au_vdir_destr *str;
4a4d8108 10935+} ____cacheline_aligned_in_smp;
1facf9fc 10936+
10937+struct au_vdir_de {
10938+ ino_t de_ino;
10939+ unsigned char de_type;
10940+ /* caution: packed */
10941+ struct au_vdir_destr de_str;
10942+} __packed;
10943+
10944+struct au_vdir_wh {
10945+ struct hlist_node wh_hash;
dece6358
AM
10946+#ifdef CONFIG_AUFS_SHWH
10947+ ino_t wh_ino;
1facf9fc 10948+ aufs_bindex_t wh_bindex;
dece6358
AM
10949+ unsigned char wh_type;
10950+#else
10951+ aufs_bindex_t wh_bindex;
10952+#endif
10953+ /* caution: packed */
1facf9fc 10954+ struct au_vdir_destr wh_str;
10955+} __packed;
10956+
10957+union au_vdir_deblk_p {
10958+ unsigned char *deblk;
10959+ struct au_vdir_de *de;
10960+};
10961+
10962+struct au_vdir {
10963+ unsigned char **vd_deblk;
10964+ unsigned long vd_nblk;
1facf9fc 10965+ struct {
10966+ unsigned long ul;
10967+ union au_vdir_deblk_p p;
10968+ } vd_last;
10969+
be118d29 10970+ u64 vd_version;
dece6358 10971+ unsigned int vd_deblk_sz;
1c60b727 10972+ unsigned long vd_jiffy;
4a4d8108 10973+} ____cacheline_aligned_in_smp;
1facf9fc 10974+
10975+/* ---------------------------------------------------------------------- */
10976+
10977+/* dir.c */
10978+extern const struct file_operations aufs_dir_fop;
10979+void au_add_nlink(struct inode *dir, struct inode *h_dir);
10980+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 10981+loff_t au_dir_size(struct file *file, struct dentry *dentry);
b912730e 10982+void au_dir_ts(struct inode *dir, aufs_bindex_t bsrc);
1facf9fc 10983+int au_test_empty_lower(struct dentry *dentry);
10984+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
10985+
10986+/* vdir.c */
1308ab2a 10987+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
10988+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
10989+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 10990+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
10991+ int limit);
dece6358
AM
10992+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
10993+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
10994+ unsigned int d_type, aufs_bindex_t bindex,
10995+ unsigned char shwh);
1c60b727 10996+void au_vdir_free(struct au_vdir *vdir);
1facf9fc 10997+int au_vdir_init(struct file *file);
392086de 10998+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 10999+
11000+/* ioctl.c */
11001+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
11002+
1308ab2a 11003+#ifdef CONFIG_AUFS_RDU
11004+/* rdu.c */
11005+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
11006+#ifdef CONFIG_COMPAT
11007+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
11008+ unsigned long arg);
11009+#endif
1308ab2a 11010+#else
c1595e42
JR
11011+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file,
11012+ unsigned int cmd, unsigned long arg)
b752ccd1 11013+#ifdef CONFIG_COMPAT
c1595e42
JR
11014+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file,
11015+ unsigned int cmd, unsigned long arg)
b752ccd1 11016+#endif
1308ab2a 11017+#endif
11018+
1facf9fc 11019+#endif /* __KERNEL__ */
11020+#endif /* __AUFS_DIR_H__ */
8b6a4947
AM
11021diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c
11022--- /usr/share/empty/fs/aufs/dirren.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 11023+++ linux/fs/aufs/dirren.c 2018-10-23 12:33:35.596042364 +0200
062440b3 11024@@ -0,0 +1,1316 @@
cd7a4cd9 11025+// SPDX-License-Identifier: GPL-2.0
8b6a4947 11026+/*
b00004a5 11027+ * Copyright (C) 2017-2018 Junjiro R. Okajima
8b6a4947
AM
11028+ *
11029+ * This program, aufs is free software; you can redistribute it and/or modify
11030+ * it under the terms of the GNU General Public License as published by
11031+ * the Free Software Foundation; either version 2 of the License, or
11032+ * (at your option) any later version.
11033+ *
11034+ * This program is distributed in the hope that it will be useful,
11035+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11036+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11037+ * GNU General Public License for more details.
11038+ *
11039+ * You should have received a copy of the GNU General Public License
11040+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
11041+ */
11042+
11043+/*
acd2b654 11044+ * special handling in renaming a directory
8b6a4947
AM
11045+ * in order to support looking-up the before-renamed name on the lower readonly
11046+ * branches
11047+ */
11048+
11049+#include <linux/byteorder/generic.h>
11050+#include "aufs.h"
11051+
11052+static void au_dr_hino_del(struct au_dr_br *dr, struct au_dr_hino *ent)
11053+{
11054+ int idx;
11055+
11056+ idx = au_dr_ihash(ent->dr_h_ino);
11057+ au_hbl_del(&ent->dr_hnode, dr->dr_h_ino + idx);
11058+}
11059+
11060+static int au_dr_hino_test_empty(struct au_dr_br *dr)
11061+{
11062+ int ret, i;
11063+ struct hlist_bl_head *hbl;
11064+
11065+ ret = 1;
11066+ for (i = 0; ret && i < AuDirren_NHASH; i++) {
11067+ hbl = dr->dr_h_ino + i;
11068+ hlist_bl_lock(hbl);
11069+ ret &= hlist_bl_empty(hbl);
11070+ hlist_bl_unlock(hbl);
11071+ }
11072+
11073+ return ret;
11074+}
11075+
11076+static struct au_dr_hino *au_dr_hino_find(struct au_dr_br *dr, ino_t ino)
11077+{
11078+ struct au_dr_hino *found, *ent;
11079+ struct hlist_bl_head *hbl;
11080+ struct hlist_bl_node *pos;
11081+ int idx;
11082+
11083+ found = NULL;
11084+ idx = au_dr_ihash(ino);
11085+ hbl = dr->dr_h_ino + idx;
11086+ hlist_bl_lock(hbl);
11087+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode)
11088+ if (ent->dr_h_ino == ino) {
11089+ found = ent;
11090+ break;
11091+ }
11092+ hlist_bl_unlock(hbl);
11093+
11094+ return found;
11095+}
11096+
11097+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t ino,
11098+ struct au_dr_hino *add_ent)
11099+{
11100+ int found, idx;
11101+ struct hlist_bl_head *hbl;
11102+ struct hlist_bl_node *pos;
11103+ struct au_dr_hino *ent;
11104+
11105+ found = 0;
11106+ idx = au_dr_ihash(ino);
11107+ hbl = dr->dr_h_ino + idx;
11108+#if 0
11109+ {
11110+ struct hlist_bl_node *tmp;
11111+
11112+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode)
11113+ AuDbg("hi%llu\n", (unsigned long long)ent->dr_h_ino);
11114+ }
11115+#endif
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 = 1;
11120+ break;
11121+ }
11122+ if (!found && add_ent)
11123+ hlist_bl_add_head(&add_ent->dr_hnode, hbl);
11124+ hlist_bl_unlock(hbl);
11125+
11126+ if (!found && add_ent)
11127+ AuDbg("i%llu added\n", (unsigned long long)add_ent->dr_h_ino);
11128+
11129+ return found;
11130+}
11131+
11132+void au_dr_hino_free(struct au_dr_br *dr)
11133+{
11134+ int i;
11135+ struct hlist_bl_head *hbl;
11136+ struct hlist_bl_node *pos, *tmp;
11137+ struct au_dr_hino *ent;
11138+
11139+ /* SiMustWriteLock(sb); */
11140+
11141+ for (i = 0; i < AuDirren_NHASH; i++) {
11142+ hbl = dr->dr_h_ino + i;
11143+ /* no spinlock since sbinfo must be write-locked */
11144+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode)
11145+ kfree(ent);
11146+ INIT_HLIST_BL_HEAD(hbl);
11147+ }
11148+}
11149+
11150+/* returns the number of inodes or an error */
11151+static int au_dr_hino_store(struct super_block *sb, struct au_branch *br,
11152+ struct file *hinofile)
11153+{
11154+ int err, i;
11155+ ssize_t ssz;
11156+ loff_t pos, oldsize;
11157+ __be64 u64;
11158+ struct inode *hinoinode;
11159+ struct hlist_bl_head *hbl;
11160+ struct hlist_bl_node *n1, *n2;
11161+ struct au_dr_hino *ent;
11162+
11163+ SiMustWriteLock(sb);
11164+ AuDebugOn(!au_br_writable(br->br_perm));
11165+
11166+ hinoinode = file_inode(hinofile);
11167+ oldsize = i_size_read(hinoinode);
11168+
11169+ err = 0;
11170+ pos = 0;
11171+ hbl = br->br_dirren.dr_h_ino;
11172+ for (i = 0; !err && i < AuDirren_NHASH; i++, hbl++) {
11173+ /* no bit-lock since sbinfo must be write-locked */
11174+ hlist_bl_for_each_entry_safe(ent, n1, n2, hbl, dr_hnode) {
11175+ AuDbg("hi%llu, %pD2\n",
11176+ (unsigned long long)ent->dr_h_ino, hinofile);
11177+ u64 = cpu_to_be64(ent->dr_h_ino);
11178+ ssz = vfsub_write_k(hinofile, &u64, sizeof(u64), &pos);
11179+ if (ssz == sizeof(u64))
11180+ continue;
11181+
11182+ /* write error */
11183+ pr_err("ssz %zd, %pD2\n", ssz, hinofile);
11184+ err = -ENOSPC;
11185+ if (ssz < 0)
11186+ err = ssz;
11187+ break;
11188+ }
11189+ }
11190+ /* regardless the error */
11191+ if (pos < oldsize) {
11192+ err = vfsub_trunc(&hinofile->f_path, pos, /*attr*/0, hinofile);
11193+ AuTraceErr(err);
11194+ }
11195+
11196+ AuTraceErr(err);
11197+ return err;
11198+}
11199+
11200+static int au_dr_hino_load(struct au_dr_br *dr, struct file *hinofile)
11201+{
11202+ int err, hidx;
11203+ ssize_t ssz;
11204+ size_t sz, n;
11205+ loff_t pos;
11206+ uint64_t u64;
11207+ struct au_dr_hino *ent;
11208+ struct inode *hinoinode;
11209+ struct hlist_bl_head *hbl;
11210+
11211+ err = 0;
11212+ pos = 0;
11213+ hbl = dr->dr_h_ino;
11214+ hinoinode = file_inode(hinofile);
11215+ sz = i_size_read(hinoinode);
11216+ AuDebugOn(sz % sizeof(u64));
11217+ n = sz / sizeof(u64);
11218+ while (n--) {
11219+ ssz = vfsub_read_k(hinofile, &u64, sizeof(u64), &pos);
11220+ if (unlikely(ssz != sizeof(u64))) {
11221+ pr_err("ssz %zd, %pD2\n", ssz, hinofile);
11222+ err = -EINVAL;
11223+ if (ssz < 0)
11224+ err = ssz;
11225+ goto out_free;
11226+ }
11227+
11228+ ent = kmalloc(sizeof(*ent), GFP_NOFS);
11229+ if (!ent) {
11230+ err = -ENOMEM;
11231+ AuTraceErr(err);
11232+ goto out_free;
11233+ }
11234+ ent->dr_h_ino = be64_to_cpu((__force __be64)u64);
11235+ AuDbg("hi%llu, %pD2\n",
11236+ (unsigned long long)ent->dr_h_ino, hinofile);
11237+ hidx = au_dr_ihash(ent->dr_h_ino);
11238+ au_hbl_add(&ent->dr_hnode, hbl + hidx);
11239+ }
11240+ goto out; /* success */
11241+
11242+out_free:
11243+ au_dr_hino_free(dr);
11244+out:
11245+ AuTraceErr(err);
11246+ return err;
11247+}
11248+
11249+/*
11250+ * @bindex/@br is a switch to distinguish whether suspending hnotify or not.
11251+ * @path is a switch to distinguish load and store.
11252+ */
11253+static int au_dr_hino(struct super_block *sb, aufs_bindex_t bindex,
11254+ struct au_branch *br, const struct path *path)
11255+{
11256+ int err, flags;
11257+ unsigned char load, suspend;
11258+ struct file *hinofile;
11259+ struct au_hinode *hdir;
11260+ struct inode *dir, *delegated;
11261+ struct path hinopath;
11262+ struct qstr hinoname = QSTR_INIT(AUFS_WH_DR_BRHINO,
11263+ sizeof(AUFS_WH_DR_BRHINO) - 1);
11264+
11265+ AuDebugOn(bindex < 0 && !br);
11266+ AuDebugOn(bindex >= 0 && br);
11267+
11268+ err = -EINVAL;
11269+ suspend = !br;
11270+ if (suspend)
11271+ br = au_sbr(sb, bindex);
11272+ load = !!path;
11273+ if (!load) {
11274+ path = &br->br_path;
11275+ AuDebugOn(!au_br_writable(br->br_perm));
11276+ if (unlikely(!au_br_writable(br->br_perm)))
11277+ goto out;
11278+ }
11279+
11280+ hdir = NULL;
11281+ if (suspend) {
11282+ dir = d_inode(sb->s_root);
11283+ hdir = au_hinode(au_ii(dir), bindex);
11284+ dir = hdir->hi_inode;
11285+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD);
11286+ } else {
11287+ dir = d_inode(path->dentry);
11288+ inode_lock_nested(dir, AuLsc_I_CHILD);
11289+ }
11290+ hinopath.dentry = vfsub_lkup_one(&hinoname, path->dentry);
11291+ err = PTR_ERR(hinopath.dentry);
11292+ if (IS_ERR(hinopath.dentry))
11293+ goto out_unlock;
11294+
11295+ err = 0;
11296+ flags = O_RDONLY;
11297+ if (load) {
11298+ if (d_is_negative(hinopath.dentry))
11299+ goto out_dput; /* success */
11300+ } else {
11301+ if (au_dr_hino_test_empty(&br->br_dirren)) {
11302+ if (d_is_positive(hinopath.dentry)) {
11303+ delegated = NULL;
11304+ err = vfsub_unlink(dir, &hinopath, &delegated,
11305+ /*force*/0);
11306+ AuTraceErr(err);
11307+ if (unlikely(err))
11308+ pr_err("ignored err %d, %pd2\n",
11309+ err, hinopath.dentry);
11310+ if (unlikely(err == -EWOULDBLOCK))
11311+ iput(delegated);
11312+ err = 0;
11313+ }
11314+ goto out_dput;
11315+ } else if (!d_is_positive(hinopath.dentry)) {
11316+ err = vfsub_create(dir, &hinopath, 0600,
11317+ /*want_excl*/false);
11318+ AuTraceErr(err);
11319+ if (unlikely(err))
11320+ goto out_dput;
11321+ }
11322+ flags = O_WRONLY;
11323+ }
11324+ hinopath.mnt = path->mnt;
11325+ hinofile = vfsub_dentry_open(&hinopath, flags);
11326+ if (suspend)
11327+ au_hn_inode_unlock(hdir);
11328+ else
11329+ inode_unlock(dir);
11330+ dput(hinopath.dentry);
11331+ AuTraceErrPtr(hinofile);
11332+ if (IS_ERR(hinofile)) {
11333+ err = PTR_ERR(hinofile);
11334+ goto out;
11335+ }
11336+
11337+ if (load)
11338+ err = au_dr_hino_load(&br->br_dirren, hinofile);
11339+ else
11340+ err = au_dr_hino_store(sb, br, hinofile);
11341+ fput(hinofile);
11342+ goto out;
11343+
11344+out_dput:
11345+ dput(hinopath.dentry);
11346+out_unlock:
11347+ if (suspend)
11348+ au_hn_inode_unlock(hdir);
11349+ else
11350+ inode_unlock(dir);
11351+out:
11352+ AuTraceErr(err);
11353+ return err;
11354+}
11355+
11356+/* ---------------------------------------------------------------------- */
11357+
11358+static int au_dr_brid_init(struct au_dr_brid *brid, const struct path *path)
11359+{
11360+ int err;
11361+ struct kstatfs kstfs;
11362+ dev_t dev;
11363+ struct dentry *dentry;
11364+ struct super_block *sb;
11365+
11366+ err = vfs_statfs((void *)path, &kstfs);
11367+ AuTraceErr(err);
11368+ if (unlikely(err))
11369+ goto out;
11370+
11371+ /* todo: support for UUID */
11372+
11373+ if (kstfs.f_fsid.val[0] || kstfs.f_fsid.val[1]) {
11374+ brid->type = AuBrid_FSID;
11375+ brid->fsid = kstfs.f_fsid;
11376+ } else {
11377+ dentry = path->dentry;
11378+ sb = dentry->d_sb;
11379+ dev = sb->s_dev;
11380+ if (dev) {
11381+ brid->type = AuBrid_DEV;
11382+ brid->dev = dev;
11383+ }
11384+ }
11385+
11386+out:
11387+ return err;
11388+}
11389+
11390+int au_dr_br_init(struct super_block *sb, struct au_branch *br,
11391+ const struct path *path)
11392+{
11393+ int err, i;
11394+ struct au_dr_br *dr;
11395+ struct hlist_bl_head *hbl;
11396+
11397+ dr = &br->br_dirren;
11398+ hbl = dr->dr_h_ino;
11399+ for (i = 0; i < AuDirren_NHASH; i++, hbl++)
11400+ INIT_HLIST_BL_HEAD(hbl);
11401+
11402+ err = au_dr_brid_init(&dr->dr_brid, path);
11403+ if (unlikely(err))
11404+ goto out;
11405+
11406+ if (au_opt_test(au_mntflags(sb), DIRREN))
11407+ err = au_dr_hino(sb, /*bindex*/-1, br, path);
11408+
11409+out:
11410+ AuTraceErr(err);
11411+ return err;
11412+}
11413+
11414+int au_dr_br_fin(struct super_block *sb, struct au_branch *br)
11415+{
11416+ int err;
11417+
11418+ err = 0;
11419+ if (au_br_writable(br->br_perm))
11420+ err = au_dr_hino(sb, /*bindex*/-1, br, /*path*/NULL);
11421+ if (!err)
11422+ au_dr_hino_free(&br->br_dirren);
11423+
11424+ return err;
11425+}
11426+
11427+/* ---------------------------------------------------------------------- */
11428+
11429+static int au_brid_str(struct au_dr_brid *brid, struct inode *h_inode,
11430+ char *buf, size_t sz)
11431+{
11432+ int err;
11433+ unsigned int major, minor;
11434+ char *p;
11435+
11436+ p = buf;
11437+ err = snprintf(p, sz, "%d_", brid->type);
11438+ AuDebugOn(err > sz);
11439+ p += err;
11440+ sz -= err;
11441+ switch (brid->type) {
11442+ case AuBrid_Unset:
11443+ return -EINVAL;
11444+ case AuBrid_UUID:
11445+ err = snprintf(p, sz, "%pU", brid->uuid.b);
11446+ break;
11447+ case AuBrid_FSID:
11448+ err = snprintf(p, sz, "%08x-%08x",
11449+ brid->fsid.val[0], brid->fsid.val[1]);
11450+ break;
11451+ case AuBrid_DEV:
11452+ major = MAJOR(brid->dev);
11453+ minor = MINOR(brid->dev);
11454+ if (major <= 0xff && minor <= 0xff)
11455+ err = snprintf(p, sz, "%02x%02x", major, minor);
11456+ else
11457+ err = snprintf(p, sz, "%03x:%05x", major, minor);
11458+ break;
11459+ }
11460+ AuDebugOn(err > sz);
11461+ p += err;
11462+ sz -= err;
11463+ err = snprintf(p, sz, "_%llu", (unsigned long long)h_inode->i_ino);
11464+ AuDebugOn(err > sz);
11465+ p += err;
11466+ sz -= err;
11467+
11468+ return p - buf;
11469+}
11470+
11471+static int au_drinfo_name(struct au_branch *br, char *name, int len)
11472+{
11473+ int rlen;
11474+ struct dentry *br_dentry;
11475+ struct inode *br_inode;
11476+
11477+ br_dentry = au_br_dentry(br);
11478+ br_inode = d_inode(br_dentry);
11479+ rlen = au_brid_str(&br->br_dirren.dr_brid, br_inode, name, len);
11480+ AuDebugOn(rlen >= AUFS_DIRREN_ENV_VAL_SZ);
11481+ AuDebugOn(rlen > len);
11482+
11483+ return rlen;
11484+}
11485+
11486+/* ---------------------------------------------------------------------- */
11487+
11488+/*
11489+ * from the given @h_dentry, construct drinfo at @*fdata.
11490+ * when the size of @*fdata is not enough, reallocate and return new @fdata and
11491+ * @allocated.
11492+ */
11493+static int au_drinfo_construct(struct au_drinfo_fdata **fdata,
11494+ struct dentry *h_dentry,
11495+ unsigned char *allocated)
11496+{
11497+ int err, v;
11498+ struct au_drinfo_fdata *f, *p;
11499+ struct au_drinfo *drinfo;
11500+ struct inode *h_inode;
11501+ struct qstr *qname;
11502+
11503+ err = 0;
11504+ f = *fdata;
11505+ h_inode = d_inode(h_dentry);
11506+ qname = &h_dentry->d_name;
11507+ drinfo = &f->drinfo;
11508+ drinfo->ino = (__force uint64_t)cpu_to_be64(h_inode->i_ino);
11509+ drinfo->oldnamelen = qname->len;
11510+ if (*allocated < sizeof(*f) + qname->len) {
11511+ v = roundup_pow_of_two(*allocated + qname->len);
11512+ p = au_krealloc(f, v, GFP_NOFS, /*may_shrink*/0);
11513+ if (unlikely(!p)) {
11514+ err = -ENOMEM;
11515+ AuTraceErr(err);
11516+ goto out;
11517+ }
11518+ f = p;
11519+ *fdata = f;
11520+ *allocated = v;
11521+ drinfo = &f->drinfo;
11522+ }
11523+ memcpy(drinfo->oldname, qname->name, qname->len);
11524+ AuDbg("i%llu, %.*s\n",
11525+ be64_to_cpu((__force __be64)drinfo->ino), drinfo->oldnamelen,
11526+ drinfo->oldname);
11527+
11528+out:
11529+ AuTraceErr(err);
11530+ return err;
11531+}
11532+
11533+/* callers have to free the return value */
11534+static struct au_drinfo *au_drinfo_read_k(struct file *file, ino_t h_ino)
11535+{
11536+ struct au_drinfo *ret, *drinfo;
11537+ struct au_drinfo_fdata fdata;
11538+ int len;
11539+ loff_t pos;
11540+ ssize_t ssz;
11541+
11542+ ret = ERR_PTR(-EIO);
11543+ pos = 0;
11544+ ssz = vfsub_read_k(file, &fdata, sizeof(fdata), &pos);
11545+ if (unlikely(ssz != sizeof(fdata))) {
11546+ AuIOErr("ssz %zd, %u, %pD2\n",
11547+ ssz, (unsigned int)sizeof(fdata), file);
11548+ goto out;
11549+ }
11550+
11551+ fdata.magic = ntohl((__force __be32)fdata.magic);
11552+ switch (fdata.magic) {
11553+ case AUFS_DRINFO_MAGIC_V1:
11554+ break;
11555+ default:
11556+ AuIOErr("magic-num 0x%x, 0x%x, %pD2\n",
11557+ fdata.magic, AUFS_DRINFO_MAGIC_V1, file);
11558+ goto out;
11559+ }
11560+
11561+ drinfo = &fdata.drinfo;
11562+ len = drinfo->oldnamelen;
11563+ if (!len) {
11564+ AuIOErr("broken drinfo %pD2\n", file);
11565+ goto out;
11566+ }
11567+
11568+ ret = NULL;
11569+ drinfo->ino = be64_to_cpu((__force __be64)drinfo->ino);
11570+ if (unlikely(h_ino && drinfo->ino != h_ino)) {
11571+ AuDbg("ignored i%llu, i%llu, %pD2\n",
11572+ (unsigned long long)drinfo->ino,
11573+ (unsigned long long)h_ino, file);
11574+ goto out; /* success */
11575+ }
11576+
11577+ ret = kmalloc(sizeof(*ret) + len, GFP_NOFS);
11578+ if (unlikely(!ret)) {
11579+ ret = ERR_PTR(-ENOMEM);
11580+ AuTraceErrPtr(ret);
11581+ goto out;
11582+ }
11583+
11584+ *ret = *drinfo;
11585+ ssz = vfsub_read_k(file, (void *)ret->oldname, len, &pos);
11586+ if (unlikely(ssz != len)) {
11587+ kfree(ret);
11588+ ret = ERR_PTR(-EIO);
11589+ AuIOErr("ssz %zd, %u, %pD2\n", ssz, len, file);
11590+ goto out;
11591+ }
11592+
11593+ AuDbg("oldname %.*s\n", ret->oldnamelen, ret->oldname);
11594+
11595+out:
11596+ return ret;
11597+}
11598+
11599+/* ---------------------------------------------------------------------- */
11600+
11601+/* in order to be revertible */
11602+struct au_drinfo_rev_elm {
11603+ int created;
11604+ struct dentry *info_dentry;
11605+ struct au_drinfo *info_last;
11606+};
11607+
11608+struct au_drinfo_rev {
11609+ unsigned char already;
11610+ aufs_bindex_t nelm;
11611+ struct au_drinfo_rev_elm elm[0];
11612+};
11613+
11614+/* todo: isn't it too large? */
11615+struct au_drinfo_store {
11616+ struct path h_ppath;
11617+ struct dentry *h_dentry;
11618+ struct au_drinfo_fdata *fdata;
11619+ char *infoname; /* inside of whname, just after PFX */
11620+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ];
11621+ aufs_bindex_t btgt, btail;
11622+ unsigned char no_sio,
11623+ allocated, /* current size of *fdata */
11624+ infonamelen, /* room size for p */
acd2b654 11625+ whnamelen, /* length of the generated name */
8b6a4947
AM
11626+ renameback; /* renamed back */
11627+};
11628+
11629+/* on rename(2) error, the caller should revert it using @elm */
11630+static int au_drinfo_do_store(struct au_drinfo_store *w,
11631+ struct au_drinfo_rev_elm *elm)
11632+{
11633+ int err, len;
11634+ ssize_t ssz;
11635+ loff_t pos;
11636+ struct path infopath = {
11637+ .mnt = w->h_ppath.mnt
11638+ };
11639+ struct inode *h_dir, *h_inode, *delegated;
11640+ struct file *infofile;
11641+ struct qstr *qname;
11642+
11643+ AuDebugOn(elm
11644+ && memcmp(elm, page_address(ZERO_PAGE(0)), sizeof(*elm)));
11645+
11646+ infopath.dentry = vfsub_lookup_one_len(w->whname, w->h_ppath.dentry,
11647+ w->whnamelen);
11648+ AuTraceErrPtr(infopath.dentry);
11649+ if (IS_ERR(infopath.dentry)) {
11650+ err = PTR_ERR(infopath.dentry);
11651+ goto out;
11652+ }
11653+
11654+ err = 0;
11655+ h_dir = d_inode(w->h_ppath.dentry);
11656+ if (elm && d_is_negative(infopath.dentry)) {
11657+ err = vfsub_create(h_dir, &infopath, 0600, /*want_excl*/true);
11658+ AuTraceErr(err);
11659+ if (unlikely(err))
11660+ goto out_dput;
11661+ elm->created = 1;
11662+ elm->info_dentry = dget(infopath.dentry);
11663+ }
11664+
11665+ infofile = vfsub_dentry_open(&infopath, O_RDWR);
11666+ AuTraceErrPtr(infofile);
11667+ if (IS_ERR(infofile)) {
11668+ err = PTR_ERR(infofile);
11669+ goto out_dput;
11670+ }
11671+
11672+ h_inode = d_inode(infopath.dentry);
11673+ if (elm && i_size_read(h_inode)) {
11674+ h_inode = d_inode(w->h_dentry);
11675+ elm->info_last = au_drinfo_read_k(infofile, h_inode->i_ino);
11676+ AuTraceErrPtr(elm->info_last);
11677+ if (IS_ERR(elm->info_last)) {
11678+ err = PTR_ERR(elm->info_last);
11679+ elm->info_last = NULL;
11680+ AuDebugOn(elm->info_dentry);
11681+ goto out_fput;
11682+ }
11683+ }
11684+
11685+ if (elm && w->renameback) {
11686+ delegated = NULL;
11687+ err = vfsub_unlink(h_dir, &infopath, &delegated, /*force*/0);
11688+ AuTraceErr(err);
11689+ if (unlikely(err == -EWOULDBLOCK))
11690+ iput(delegated);
11691+ goto out_fput;
11692+ }
11693+
11694+ pos = 0;
11695+ qname = &w->h_dentry->d_name;
11696+ len = sizeof(*w->fdata) + qname->len;
11697+ if (!elm)
11698+ len = sizeof(*w->fdata) + w->fdata->drinfo.oldnamelen;
11699+ ssz = vfsub_write_k(infofile, w->fdata, len, &pos);
11700+ if (ssz == len) {
11701+ AuDbg("hi%llu, %.*s\n", w->fdata->drinfo.ino,
11702+ w->fdata->drinfo.oldnamelen, w->fdata->drinfo.oldname);
11703+ goto out_fput; /* success */
11704+ } else {
11705+ err = -EIO;
11706+ if (ssz < 0)
11707+ err = ssz;
11708+ /* the caller should revert it using @elm */
11709+ }
11710+
11711+out_fput:
11712+ fput(infofile);
11713+out_dput:
11714+ dput(infopath.dentry);
11715+out:
11716+ AuTraceErr(err);
11717+ return err;
11718+}
11719+
11720+struct au_call_drinfo_do_store_args {
11721+ int *errp;
11722+ struct au_drinfo_store *w;
11723+ struct au_drinfo_rev_elm *elm;
11724+};
11725+
11726+static void au_call_drinfo_do_store(void *args)
11727+{
11728+ struct au_call_drinfo_do_store_args *a = args;
11729+
11730+ *a->errp = au_drinfo_do_store(a->w, a->elm);
11731+}
11732+
11733+static int au_drinfo_store_sio(struct au_drinfo_store *w,
11734+ struct au_drinfo_rev_elm *elm)
11735+{
11736+ int err, wkq_err;
11737+
11738+ if (w->no_sio)
11739+ err = au_drinfo_do_store(w, elm);
11740+ else {
11741+ struct au_call_drinfo_do_store_args a = {
11742+ .errp = &err,
11743+ .w = w,
11744+ .elm = elm
11745+ };
11746+ wkq_err = au_wkq_wait(au_call_drinfo_do_store, &a);
11747+ if (unlikely(wkq_err))
11748+ err = wkq_err;
11749+ }
11750+ AuTraceErr(err);
11751+
11752+ return err;
11753+}
11754+
11755+static int au_drinfo_store_work_init(struct au_drinfo_store *w,
11756+ aufs_bindex_t btgt)
11757+{
11758+ int err;
11759+
11760+ memset(w, 0, sizeof(*w));
11761+ w->allocated = roundup_pow_of_two(sizeof(*w->fdata) + 40);
11762+ strcpy(w->whname, AUFS_WH_DR_INFO_PFX);
11763+ w->infoname = w->whname + sizeof(AUFS_WH_DR_INFO_PFX) - 1;
11764+ w->infonamelen = sizeof(w->whname) - sizeof(AUFS_WH_DR_INFO_PFX);
11765+ w->btgt = btgt;
11766+ w->no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID);
11767+
11768+ err = -ENOMEM;
11769+ w->fdata = kcalloc(1, w->allocated, GFP_NOFS);
11770+ if (unlikely(!w->fdata)) {
11771+ AuTraceErr(err);
11772+ goto out;
11773+ }
11774+ w->fdata->magic = (__force uint32_t)htonl(AUFS_DRINFO_MAGIC_V1);
11775+ err = 0;
11776+
11777+out:
11778+ return err;
11779+}
11780+
11781+static void au_drinfo_store_work_fin(struct au_drinfo_store *w)
11782+{
11783+ kfree(w->fdata);
11784+}
11785+
11786+static void au_drinfo_store_rev(struct au_drinfo_rev *rev,
11787+ struct au_drinfo_store *w)
11788+{
11789+ struct au_drinfo_rev_elm *elm;
11790+ struct inode *h_dir, *delegated;
11791+ int err, nelm;
11792+ struct path infopath = {
11793+ .mnt = w->h_ppath.mnt
11794+ };
11795+
11796+ h_dir = d_inode(w->h_ppath.dentry);
11797+ IMustLock(h_dir);
11798+
11799+ err = 0;
11800+ elm = rev->elm;
11801+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) {
11802+ AuDebugOn(elm->created && elm->info_last);
11803+ if (elm->created) {
11804+ AuDbg("here\n");
11805+ delegated = NULL;
11806+ infopath.dentry = elm->info_dentry;
11807+ err = vfsub_unlink(h_dir, &infopath, &delegated,
11808+ !w->no_sio);
11809+ AuTraceErr(err);
11810+ if (unlikely(err == -EWOULDBLOCK))
11811+ iput(delegated);
11812+ dput(elm->info_dentry);
11813+ } else if (elm->info_last) {
11814+ AuDbg("here\n");
11815+ w->fdata->drinfo = *elm->info_last;
11816+ memcpy(w->fdata->drinfo.oldname,
11817+ elm->info_last->oldname,
11818+ elm->info_last->oldnamelen);
11819+ err = au_drinfo_store_sio(w, /*elm*/NULL);
11820+ kfree(elm->info_last);
11821+ }
11822+ if (unlikely(err))
11823+ AuIOErr("%d, %s\n", err, w->whname);
11824+ /* go on even if err */
11825+ }
11826+}
11827+
11828+/* caller has to call au_dr_rename_fin() later */
11829+static int au_drinfo_store(struct dentry *dentry, aufs_bindex_t btgt,
11830+ struct qstr *dst_name, void *_rev)
11831+{
11832+ int err, sz, nelm;
11833+ aufs_bindex_t bindex, btail;
11834+ struct au_drinfo_store work;
11835+ struct au_drinfo_rev *rev, **p;
11836+ struct au_drinfo_rev_elm *elm;
11837+ struct super_block *sb;
11838+ struct au_branch *br;
11839+ struct au_hinode *hdir;
11840+
11841+ err = au_drinfo_store_work_init(&work, btgt);
11842+ AuTraceErr(err);
11843+ if (unlikely(err))
11844+ goto out;
11845+
11846+ err = -ENOMEM;
11847+ btail = au_dbtaildir(dentry);
11848+ nelm = btail - btgt;
11849+ sz = sizeof(*rev) + sizeof(*elm) * nelm;
11850+ rev = kcalloc(1, sz, GFP_NOFS);
11851+ if (unlikely(!rev)) {
11852+ AuTraceErr(err);
11853+ goto out_args;
11854+ }
11855+ rev->nelm = nelm;
11856+ elm = rev->elm;
11857+ p = _rev;
11858+ *p = rev;
11859+
11860+ err = 0;
11861+ sb = dentry->d_sb;
11862+ work.h_ppath.dentry = au_h_dptr(dentry, btgt);
11863+ work.h_ppath.mnt = au_sbr_mnt(sb, btgt);
11864+ hdir = au_hi(d_inode(dentry), btgt);
11865+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD);
11866+ for (bindex = btgt + 1; bindex <= btail; bindex++, elm++) {
11867+ work.h_dentry = au_h_dptr(dentry, bindex);
11868+ if (!work.h_dentry)
11869+ continue;
11870+
11871+ err = au_drinfo_construct(&work.fdata, work.h_dentry,
11872+ &work.allocated);
11873+ AuTraceErr(err);
11874+ if (unlikely(err))
11875+ break;
11876+
11877+ work.renameback = au_qstreq(&work.h_dentry->d_name, dst_name);
11878+ br = au_sbr(sb, bindex);
11879+ work.whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1;
11880+ work.whnamelen += au_drinfo_name(br, work.infoname,
11881+ work.infonamelen);
11882+ AuDbg("whname %.*s, i%llu, %.*s\n",
11883+ work.whnamelen, work.whname,
11884+ be64_to_cpu((__force __be64)work.fdata->drinfo.ino),
11885+ work.fdata->drinfo.oldnamelen,
11886+ work.fdata->drinfo.oldname);
11887+
11888+ err = au_drinfo_store_sio(&work, elm);
11889+ AuTraceErr(err);
11890+ if (unlikely(err))
11891+ break;
11892+ }
11893+ if (unlikely(err)) {
11894+ /* revert all drinfo */
11895+ au_drinfo_store_rev(rev, &work);
11896+ kfree(rev);
11897+ *p = NULL;
11898+ }
11899+ au_hn_inode_unlock(hdir);
11900+
11901+out_args:
11902+ au_drinfo_store_work_fin(&work);
11903+out:
11904+ return err;
11905+}
11906+
11907+/* ---------------------------------------------------------------------- */
11908+
11909+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
11910+ struct qstr *dst_name, void *_rev)
11911+{
11912+ int err, already;
11913+ ino_t ino;
11914+ struct super_block *sb;
11915+ struct au_branch *br;
11916+ struct au_dr_br *dr;
11917+ struct dentry *h_dentry;
11918+ struct inode *h_inode;
11919+ struct au_dr_hino *ent;
11920+ struct au_drinfo_rev *rev, **p;
11921+
11922+ AuDbg("bindex %d\n", bindex);
11923+
11924+ err = -ENOMEM;
11925+ ent = kmalloc(sizeof(*ent), GFP_NOFS);
11926+ if (unlikely(!ent))
11927+ goto out;
11928+
11929+ sb = src->d_sb;
11930+ br = au_sbr(sb, bindex);
11931+ dr = &br->br_dirren;
11932+ h_dentry = au_h_dptr(src, bindex);
11933+ h_inode = d_inode(h_dentry);
11934+ ino = h_inode->i_ino;
11935+ ent->dr_h_ino = ino;
11936+ already = au_dr_hino_test_add(dr, ino, ent);
11937+ AuDbg("b%d, hi%llu, already %d\n",
11938+ bindex, (unsigned long long)ino, already);
11939+
11940+ err = au_drinfo_store(src, bindex, dst_name, _rev);
11941+ AuTraceErr(err);
11942+ if (!err) {
11943+ p = _rev;
11944+ rev = *p;
11945+ rev->already = already;
11946+ goto out; /* success */
11947+ }
11948+
11949+ /* revert */
11950+ if (!already)
11951+ au_dr_hino_del(dr, ent);
11952+ kfree(ent);
11953+
11954+out:
11955+ AuTraceErr(err);
11956+ return err;
11957+}
11958+
11959+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *_rev)
11960+{
11961+ struct au_drinfo_rev *rev;
11962+ struct au_drinfo_rev_elm *elm;
11963+ int nelm;
11964+
11965+ rev = _rev;
11966+ elm = rev->elm;
11967+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) {
11968+ dput(elm->info_dentry);
11969+ kfree(elm->info_last);
11970+ }
11971+ kfree(rev);
11972+}
11973+
11974+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t btgt, void *_rev)
11975+{
11976+ int err;
11977+ struct au_drinfo_store work;
11978+ struct au_drinfo_rev *rev = _rev;
11979+ struct super_block *sb;
11980+ struct au_branch *br;
11981+ struct inode *h_inode;
11982+ struct au_dr_br *dr;
11983+ struct au_dr_hino *ent;
11984+
11985+ err = au_drinfo_store_work_init(&work, btgt);
11986+ if (unlikely(err))
11987+ goto out;
11988+
11989+ sb = src->d_sb;
11990+ br = au_sbr(sb, btgt);
11991+ work.h_ppath.dentry = au_h_dptr(src, btgt);
11992+ work.h_ppath.mnt = au_br_mnt(br);
11993+ au_drinfo_store_rev(rev, &work);
11994+ au_drinfo_store_work_fin(&work);
11995+ if (rev->already)
11996+ goto out;
11997+
11998+ dr = &br->br_dirren;
11999+ h_inode = d_inode(work.h_ppath.dentry);
12000+ ent = au_dr_hino_find(dr, h_inode->i_ino);
12001+ BUG_ON(!ent);
12002+ au_dr_hino_del(dr, ent);
12003+ kfree(ent);
12004+
12005+out:
12006+ kfree(rev);
12007+ if (unlikely(err))
12008+ pr_err("failed to remove dirren info\n");
12009+}
12010+
12011+/* ---------------------------------------------------------------------- */
12012+
12013+static struct au_drinfo *au_drinfo_do_load(struct path *h_ppath,
12014+ char *whname, int whnamelen,
12015+ struct dentry **info_dentry)
12016+{
12017+ struct au_drinfo *drinfo;
12018+ struct file *f;
12019+ struct inode *h_dir;
12020+ struct path infopath;
12021+ int unlocked;
12022+
12023+ AuDbg("%pd/%.*s\n", h_ppath->dentry, whnamelen, whname);
12024+
12025+ *info_dentry = NULL;
12026+ drinfo = NULL;
12027+ unlocked = 0;
12028+ h_dir = d_inode(h_ppath->dentry);
be118d29 12029+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
8b6a4947
AM
12030+ infopath.dentry = vfsub_lookup_one_len(whname, h_ppath->dentry,
12031+ whnamelen);
12032+ if (IS_ERR(infopath.dentry)) {
12033+ drinfo = (void *)infopath.dentry;
12034+ goto out;
12035+ }
12036+
12037+ if (d_is_negative(infopath.dentry))
12038+ goto out_dput; /* success */
12039+
12040+ infopath.mnt = h_ppath->mnt;
12041+ f = vfsub_dentry_open(&infopath, O_RDONLY);
12042+ inode_unlock_shared(h_dir);
12043+ unlocked = 1;
12044+ if (IS_ERR(f)) {
12045+ drinfo = (void *)f;
12046+ goto out_dput;
12047+ }
12048+
12049+ drinfo = au_drinfo_read_k(f, /*h_ino*/0);
12050+ if (IS_ERR_OR_NULL(drinfo))
12051+ goto out_fput;
12052+
12053+ AuDbg("oldname %.*s\n", drinfo->oldnamelen, drinfo->oldname);
12054+ *info_dentry = dget(infopath.dentry); /* keep it alive */
12055+
12056+out_fput:
12057+ fput(f);
12058+out_dput:
12059+ dput(infopath.dentry);
12060+out:
12061+ if (!unlocked)
12062+ inode_unlock_shared(h_dir);
12063+ AuTraceErrPtr(drinfo);
12064+ return drinfo;
12065+}
12066+
12067+struct au_drinfo_do_load_args {
12068+ struct au_drinfo **drinfop;
12069+ struct path *h_ppath;
12070+ char *whname;
12071+ int whnamelen;
12072+ struct dentry **info_dentry;
12073+};
12074+
12075+static void au_call_drinfo_do_load(void *args)
12076+{
12077+ struct au_drinfo_do_load_args *a = args;
12078+
12079+ *a->drinfop = au_drinfo_do_load(a->h_ppath, a->whname, a->whnamelen,
12080+ a->info_dentry);
12081+}
12082+
12083+struct au_drinfo_load {
12084+ struct path h_ppath;
12085+ struct qstr *qname;
12086+ unsigned char no_sio;
12087+
12088+ aufs_bindex_t ninfo;
12089+ struct au_drinfo **drinfo;
12090+};
12091+
12092+static int au_drinfo_load(struct au_drinfo_load *w, aufs_bindex_t bindex,
12093+ struct au_branch *br)
12094+{
12095+ int err, wkq_err, whnamelen, e;
12096+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ]
12097+ = AUFS_WH_DR_INFO_PFX;
12098+ struct au_drinfo *drinfo;
12099+ struct qstr oldname;
12100+ struct inode *h_dir, *delegated;
12101+ struct dentry *info_dentry;
12102+ struct path infopath;
12103+
12104+ whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1;
12105+ whnamelen += au_drinfo_name(br, whname + whnamelen,
12106+ sizeof(whname) - whnamelen);
12107+ if (w->no_sio)
12108+ drinfo = au_drinfo_do_load(&w->h_ppath, whname, whnamelen,
12109+ &info_dentry);
12110+ else {
12111+ struct au_drinfo_do_load_args args = {
12112+ .drinfop = &drinfo,
12113+ .h_ppath = &w->h_ppath,
12114+ .whname = whname,
12115+ .whnamelen = whnamelen,
12116+ .info_dentry = &info_dentry
12117+ };
12118+ wkq_err = au_wkq_wait(au_call_drinfo_do_load, &args);
12119+ if (unlikely(wkq_err))
12120+ drinfo = ERR_PTR(wkq_err);
12121+ }
12122+ err = PTR_ERR(drinfo);
12123+ if (IS_ERR_OR_NULL(drinfo))
12124+ goto out;
12125+
12126+ err = 0;
12127+ oldname.len = drinfo->oldnamelen;
12128+ oldname.name = drinfo->oldname;
12129+ if (au_qstreq(w->qname, &oldname)) {
12130+ /* the name is renamed back */
12131+ kfree(drinfo);
12132+ drinfo = NULL;
12133+
12134+ infopath.dentry = info_dentry;
12135+ infopath.mnt = w->h_ppath.mnt;
12136+ h_dir = d_inode(w->h_ppath.dentry);
12137+ delegated = NULL;
12138+ inode_lock_nested(h_dir, AuLsc_I_PARENT);
12139+ e = vfsub_unlink(h_dir, &infopath, &delegated, !w->no_sio);
12140+ inode_unlock(h_dir);
12141+ if (unlikely(e))
12142+ AuIOErr("ignored %d, %pd2\n", e, &infopath.dentry);
12143+ if (unlikely(e == -EWOULDBLOCK))
12144+ iput(delegated);
12145+ }
12146+ kfree(w->drinfo[bindex]);
12147+ w->drinfo[bindex] = drinfo;
12148+ dput(info_dentry);
12149+
12150+out:
12151+ AuTraceErr(err);
12152+ return err;
12153+}
12154+
12155+/* ---------------------------------------------------------------------- */
12156+
12157+static void au_dr_lkup_free(struct au_drinfo **drinfo, int n)
12158+{
12159+ struct au_drinfo **p = drinfo;
12160+
12161+ while (n-- > 0)
12162+ kfree(*drinfo++);
12163+ kfree(p);
12164+}
12165+
12166+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
12167+ aufs_bindex_t btgt)
12168+{
12169+ int err, ninfo;
12170+ struct au_drinfo_load w;
12171+ aufs_bindex_t bindex, bbot;
12172+ struct au_branch *br;
12173+ struct inode *h_dir;
12174+ struct au_dr_hino *ent;
12175+ struct super_block *sb;
12176+
12177+ AuDbg("%.*s, name %.*s, whname %.*s, b%d\n",
12178+ AuLNPair(&dentry->d_name), AuLNPair(&lkup->dirren.dr_name),
12179+ AuLNPair(&lkup->whname), btgt);
12180+
12181+ sb = dentry->d_sb;
12182+ bbot = au_sbbot(sb);
12183+ w.ninfo = bbot + 1;
12184+ if (!lkup->dirren.drinfo) {
12185+ lkup->dirren.drinfo = kcalloc(w.ninfo,
12186+ sizeof(*lkup->dirren.drinfo),
12187+ GFP_NOFS);
12188+ if (unlikely(!lkup->dirren.drinfo)) {
12189+ err = -ENOMEM;
12190+ goto out;
12191+ }
12192+ lkup->dirren.ninfo = w.ninfo;
12193+ }
12194+ w.drinfo = lkup->dirren.drinfo;
12195+ w.no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID);
12196+ w.h_ppath.dentry = au_h_dptr(dentry, btgt);
12197+ AuDebugOn(!w.h_ppath.dentry);
12198+ w.h_ppath.mnt = au_sbr_mnt(sb, btgt);
12199+ w.qname = &dentry->d_name;
12200+
12201+ ninfo = 0;
12202+ for (bindex = btgt + 1; bindex <= bbot; bindex++) {
12203+ br = au_sbr(sb, bindex);
12204+ err = au_drinfo_load(&w, bindex, br);
12205+ if (unlikely(err))
12206+ goto out_free;
12207+ if (w.drinfo[bindex])
12208+ ninfo++;
12209+ }
12210+ if (!ninfo) {
12211+ br = au_sbr(sb, btgt);
12212+ h_dir = d_inode(w.h_ppath.dentry);
12213+ ent = au_dr_hino_find(&br->br_dirren, h_dir->i_ino);
12214+ AuDebugOn(!ent);
12215+ au_dr_hino_del(&br->br_dirren, ent);
12216+ kfree(ent);
12217+ }
12218+ goto out; /* success */
12219+
12220+out_free:
12221+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo);
12222+ lkup->dirren.ninfo = 0;
12223+ lkup->dirren.drinfo = NULL;
12224+out:
12225+ AuTraceErr(err);
12226+ return err;
12227+}
12228+
12229+void au_dr_lkup_fin(struct au_do_lookup_args *lkup)
12230+{
12231+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo);
12232+}
12233+
12234+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt)
12235+{
12236+ int err;
12237+ struct au_drinfo *drinfo;
12238+
12239+ err = 0;
12240+ if (!lkup->dirren.drinfo)
12241+ goto out;
12242+ AuDebugOn(lkup->dirren.ninfo < btgt + 1);
12243+ drinfo = lkup->dirren.drinfo[btgt + 1];
12244+ if (!drinfo)
12245+ goto out;
12246+
12247+ kfree(lkup->whname.name);
12248+ lkup->whname.name = NULL;
12249+ lkup->dirren.dr_name.len = drinfo->oldnamelen;
12250+ lkup->dirren.dr_name.name = drinfo->oldname;
12251+ lkup->name = &lkup->dirren.dr_name;
12252+ err = au_wh_name_alloc(&lkup->whname, lkup->name);
12253+ if (!err)
12254+ AuDbg("name %.*s, whname %.*s, b%d\n",
12255+ AuLNPair(lkup->name), AuLNPair(&lkup->whname),
12256+ btgt);
12257+
12258+out:
12259+ AuTraceErr(err);
12260+ return err;
12261+}
12262+
12263+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
12264+ ino_t h_ino)
12265+{
12266+ int match;
12267+ struct au_drinfo *drinfo;
12268+
12269+ match = 1;
12270+ if (!lkup->dirren.drinfo)
12271+ goto out;
12272+ AuDebugOn(lkup->dirren.ninfo < bindex + 1);
12273+ drinfo = lkup->dirren.drinfo[bindex + 1];
12274+ if (!drinfo)
12275+ goto out;
12276+
12277+ match = (drinfo->ino == h_ino);
12278+ AuDbg("match %d\n", match);
12279+
12280+out:
12281+ return match;
12282+}
12283+
12284+/* ---------------------------------------------------------------------- */
12285+
12286+int au_dr_opt_set(struct super_block *sb)
12287+{
12288+ int err;
12289+ aufs_bindex_t bindex, bbot;
12290+ struct au_branch *br;
12291+
12292+ err = 0;
12293+ bbot = au_sbbot(sb);
12294+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
12295+ br = au_sbr(sb, bindex);
12296+ err = au_dr_hino(sb, bindex, /*br*/NULL, &br->br_path);
12297+ }
12298+
12299+ return err;
12300+}
12301+
12302+int au_dr_opt_flush(struct super_block *sb)
12303+{
12304+ int err;
12305+ aufs_bindex_t bindex, bbot;
12306+ struct au_branch *br;
12307+
12308+ err = 0;
12309+ bbot = au_sbbot(sb);
12310+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
12311+ br = au_sbr(sb, bindex);
12312+ if (au_br_writable(br->br_perm))
12313+ err = au_dr_hino(sb, bindex, /*br*/NULL, /*path*/NULL);
12314+ }
12315+
12316+ return err;
12317+}
12318+
12319+int au_dr_opt_clr(struct super_block *sb, int no_flush)
12320+{
12321+ int err;
12322+ aufs_bindex_t bindex, bbot;
12323+ struct au_branch *br;
12324+
12325+ err = 0;
12326+ if (!no_flush) {
12327+ err = au_dr_opt_flush(sb);
12328+ if (unlikely(err))
12329+ goto out;
12330+ }
12331+
12332+ bbot = au_sbbot(sb);
12333+ for (bindex = 0; bindex <= bbot; bindex++) {
12334+ br = au_sbr(sb, bindex);
12335+ au_dr_hino_free(&br->br_dirren);
12336+ }
12337+
12338+out:
12339+ return err;
12340+}
12341diff -urN /usr/share/empty/fs/aufs/dirren.h linux/fs/aufs/dirren.h
12342--- /usr/share/empty/fs/aufs/dirren.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 12343+++ linux/fs/aufs/dirren.h 2018-08-12 23:43:05.453457863 +0200
062440b3
AM
12344@@ -0,0 +1,140 @@
12345+/* SPDX-License-Identifier: GPL-2.0 */
8b6a4947 12346+/*
b00004a5 12347+ * Copyright (C) 2017-2018 Junjiro R. Okajima
8b6a4947
AM
12348+ *
12349+ * This program, aufs is free software; you can redistribute it and/or modify
12350+ * it under the terms of the GNU General Public License as published by
12351+ * the Free Software Foundation; either version 2 of the License, or
12352+ * (at your option) any later version.
12353+ *
12354+ * This program is distributed in the hope that it will be useful,
12355+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12356+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12357+ * GNU General Public License for more details.
12358+ *
12359+ * You should have received a copy of the GNU General Public License
12360+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
12361+ */
12362+
12363+/*
12364+ * renamed dir info
12365+ */
12366+
12367+#ifndef __AUFS_DIRREN_H__
12368+#define __AUFS_DIRREN_H__
12369+
12370+#ifdef __KERNEL__
12371+
12372+#include <linux/dcache.h>
12373+#include <linux/statfs.h>
12374+#include <linux/uuid.h>
12375+#include "hbl.h"
12376+
12377+#define AuDirren_NHASH 100
12378+
12379+#ifdef CONFIG_AUFS_DIRREN
12380+enum au_brid_type {
12381+ AuBrid_Unset,
12382+ AuBrid_UUID,
12383+ AuBrid_FSID,
12384+ AuBrid_DEV
12385+};
12386+
12387+struct au_dr_brid {
12388+ enum au_brid_type type;
12389+ union {
12390+ uuid_t uuid; /* unimplemented yet */
12391+ fsid_t fsid;
12392+ dev_t dev;
12393+ };
12394+};
12395+
12396+/* 20 is the max digits length of ulong 64 */
12397+/* brid-type "_" uuid "_" inum */
12398+#define AUFS_DIRREN_FNAME_SZ (1 + 1 + UUID_STRING_LEN + 20)
12399+#define AUFS_DIRREN_ENV_VAL_SZ (AUFS_DIRREN_FNAME_SZ + 1 + 20)
12400+
12401+struct au_dr_hino {
12402+ struct hlist_bl_node dr_hnode;
12403+ ino_t dr_h_ino;
12404+};
12405+
12406+struct au_dr_br {
12407+ struct hlist_bl_head dr_h_ino[AuDirren_NHASH];
12408+ struct au_dr_brid dr_brid;
12409+};
12410+
12411+struct au_dr_lookup {
12412+ /* dr_name is pointed by struct au_do_lookup_args.name */
12413+ struct qstr dr_name; /* subset of dr_info */
12414+ aufs_bindex_t ninfo;
12415+ struct au_drinfo **drinfo;
12416+};
12417+#else
12418+struct au_dr_hino;
12419+/* empty */
12420+struct au_dr_br { };
12421+struct au_dr_lookup { };
12422+#endif
12423+
12424+/* ---------------------------------------------------------------------- */
12425+
12426+struct au_branch;
12427+struct au_do_lookup_args;
12428+struct au_hinode;
12429+#ifdef CONFIG_AUFS_DIRREN
12430+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t h_ino,
12431+ struct au_dr_hino *add_ent);
12432+void au_dr_hino_free(struct au_dr_br *dr);
12433+int au_dr_br_init(struct super_block *sb, struct au_branch *br,
12434+ const struct path *path);
12435+int au_dr_br_fin(struct super_block *sb, struct au_branch *br);
12436+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex,
12437+ struct qstr *dst_name, void *_rev);
12438+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *rev);
12439+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t bindex, void *rev);
12440+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry,
12441+ aufs_bindex_t bindex);
12442+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
12443+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex,
12444+ ino_t h_ino);
12445+void au_dr_lkup_fin(struct au_do_lookup_args *lkup);
12446+int au_dr_opt_set(struct super_block *sb);
12447+int au_dr_opt_flush(struct super_block *sb);
12448+int au_dr_opt_clr(struct super_block *sb, int no_flush);
12449+#else
12450+AuStubInt0(au_dr_hino_test_add, struct au_dr_br *dr, ino_t h_ino,
12451+ struct au_dr_hino *add_ent);
12452+AuStubVoid(au_dr_hino_free, struct au_dr_br *dr);
12453+AuStubInt0(au_dr_br_init, struct super_block *sb, struct au_branch *br,
12454+ const struct path *path);
12455+AuStubInt0(au_dr_br_fin, struct super_block *sb, struct au_branch *br);
12456+AuStubInt0(au_dr_rename, struct dentry *src, aufs_bindex_t bindex,
12457+ struct qstr *dst_name, void *_rev);
12458+AuStubVoid(au_dr_rename_fin, struct dentry *src, aufs_bindex_t btgt, void *rev);
12459+AuStubVoid(au_dr_rename_rev, struct dentry *src, aufs_bindex_t bindex,
12460+ void *rev);
12461+AuStubInt0(au_dr_lkup, struct au_do_lookup_args *lkup, struct dentry *dentry,
12462+ aufs_bindex_t bindex);
12463+AuStubInt0(au_dr_lkup_name, struct au_do_lookup_args *lkup, aufs_bindex_t btgt);
12464+AuStubInt0(au_dr_lkup_h_ino, struct au_do_lookup_args *lkup,
12465+ aufs_bindex_t bindex, ino_t h_ino);
12466+AuStubVoid(au_dr_lkup_fin, struct au_do_lookup_args *lkup);
12467+AuStubInt0(au_dr_opt_set, struct super_block *sb);
12468+AuStubInt0(au_dr_opt_flush, struct super_block *sb);
12469+AuStubInt0(au_dr_opt_clr, struct super_block *sb, int no_flush);
12470+#endif
12471+
12472+/* ---------------------------------------------------------------------- */
12473+
12474+#ifdef CONFIG_AUFS_DIRREN
12475+static inline int au_dr_ihash(ino_t h_ino)
12476+{
12477+ return h_ino % AuDirren_NHASH;
12478+}
12479+#else
12480+AuStubInt0(au_dr_ihash, ino_t h_ino);
12481+#endif
12482+
12483+#endif /* __KERNEL__ */
12484+#endif /* __AUFS_DIRREN_H__ */
7f207e10
AM
12485diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
12486--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 12487+++ linux/fs/aufs/dynop.c 2018-10-23 12:33:35.596042364 +0200
062440b3 12488@@ -0,0 +1,370 @@
cd7a4cd9 12489+// SPDX-License-Identifier: GPL-2.0
1facf9fc 12490+/*
b00004a5 12491+ * Copyright (C) 2010-2018 Junjiro R. Okajima
1facf9fc 12492+ *
12493+ * This program, aufs is free software; you can redistribute it and/or modify
12494+ * it under the terms of the GNU General Public License as published by
12495+ * the Free Software Foundation; either version 2 of the License, or
12496+ * (at your option) any later version.
dece6358
AM
12497+ *
12498+ * This program is distributed in the hope that it will be useful,
12499+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12500+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12501+ * GNU General Public License for more details.
12502+ *
12503+ * You should have received a copy of the GNU General Public License
523b37e3 12504+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 12505+ */
12506+
12507+/*
4a4d8108 12508+ * dynamically customizable operations for regular files
1facf9fc 12509+ */
12510+
1facf9fc 12511+#include "aufs.h"
12512+
4a4d8108 12513+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 12514+
4a4d8108
AM
12515+/*
12516+ * How large will these lists be?
12517+ * Usually just a few elements, 20-30 at most for each, I guess.
12518+ */
8b6a4947 12519+static struct hlist_bl_head dynop[AuDyLast];
4a4d8108 12520+
8b6a4947
AM
12521+static struct au_dykey *dy_gfind_get(struct hlist_bl_head *hbl,
12522+ const void *h_op)
1facf9fc 12523+{
4a4d8108 12524+ struct au_dykey *key, *tmp;
8b6a4947 12525+ struct hlist_bl_node *pos;
1facf9fc 12526+
4a4d8108 12527+ key = NULL;
8b6a4947
AM
12528+ hlist_bl_lock(hbl);
12529+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode)
4a4d8108
AM
12530+ if (tmp->dk_op.dy_hop == h_op) {
12531+ key = tmp;
12532+ kref_get(&key->dk_kref);
12533+ break;
12534+ }
8b6a4947 12535+ hlist_bl_unlock(hbl);
4a4d8108
AM
12536+
12537+ return key;
1facf9fc 12538+}
12539+
4a4d8108 12540+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 12541+{
4a4d8108
AM
12542+ struct au_dykey **k, *found;
12543+ const void *h_op = key->dk_op.dy_hop;
12544+ int i;
1facf9fc 12545+
4a4d8108
AM
12546+ found = NULL;
12547+ k = br->br_dykey;
12548+ for (i = 0; i < AuBrDynOp; i++)
12549+ if (k[i]) {
12550+ if (k[i]->dk_op.dy_hop == h_op) {
12551+ found = k[i];
12552+ break;
12553+ }
12554+ } else
12555+ break;
12556+ if (!found) {
12557+ spin_lock(&br->br_dykey_lock);
12558+ for (; i < AuBrDynOp; i++)
12559+ if (k[i]) {
12560+ if (k[i]->dk_op.dy_hop == h_op) {
12561+ found = k[i];
12562+ break;
12563+ }
12564+ } else {
12565+ k[i] = key;
12566+ break;
12567+ }
12568+ spin_unlock(&br->br_dykey_lock);
12569+ BUG_ON(i == AuBrDynOp); /* expand the array */
12570+ }
12571+
12572+ return found;
1facf9fc 12573+}
12574+
4a4d8108 12575+/* kref_get() if @key is already added */
8b6a4947 12576+static struct au_dykey *dy_gadd(struct hlist_bl_head *hbl, struct au_dykey *key)
4a4d8108
AM
12577+{
12578+ struct au_dykey *tmp, *found;
8b6a4947 12579+ struct hlist_bl_node *pos;
4a4d8108 12580+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 12581+
4a4d8108 12582+ found = NULL;
8b6a4947
AM
12583+ hlist_bl_lock(hbl);
12584+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode)
4a4d8108
AM
12585+ if (tmp->dk_op.dy_hop == h_op) {
12586+ kref_get(&tmp->dk_kref);
12587+ found = tmp;
12588+ break;
12589+ }
12590+ if (!found)
8b6a4947
AM
12591+ hlist_bl_add_head(&key->dk_hnode, hbl);
12592+ hlist_bl_unlock(hbl);
1facf9fc 12593+
4a4d8108
AM
12594+ if (!found)
12595+ DyPrSym(key);
12596+ return found;
12597+}
12598+
12599+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 12600+{
4a4d8108
AM
12601+ struct au_dykey *key;
12602+
12603+ key = container_of(rcu, struct au_dykey, dk_rcu);
12604+ DyPrSym(key);
1c60b727 12605+ kfree(key);
1facf9fc 12606+}
12607+
4a4d8108
AM
12608+static void dy_free(struct kref *kref)
12609+{
12610+ struct au_dykey *key;
8b6a4947 12611+ struct hlist_bl_head *hbl;
1facf9fc 12612+
4a4d8108 12613+ key = container_of(kref, struct au_dykey, dk_kref);
8b6a4947
AM
12614+ hbl = dynop + key->dk_op.dy_type;
12615+ au_hbl_del(&key->dk_hnode, hbl);
4a4d8108
AM
12616+ call_rcu(&key->dk_rcu, dy_free_rcu);
12617+}
12618+
12619+void au_dy_put(struct au_dykey *key)
1facf9fc 12620+{
4a4d8108
AM
12621+ kref_put(&key->dk_kref, dy_free);
12622+}
1facf9fc 12623+
4a4d8108
AM
12624+/* ---------------------------------------------------------------------- */
12625+
12626+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
12627+
12628+#ifdef CONFIG_AUFS_DEBUG
12629+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 12630+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
12631+#else
12632+#define DyDbgDeclare(cnt) do {} while (0)
12633+#define DyDbgInc(cnt) do {} while (0)
12634+#endif
12635+
12636+#define DySet(func, dst, src, h_op, h_sb) do { \
12637+ DyDbgInc(cnt); \
12638+ if (h_op->func) { \
12639+ if (src.func) \
12640+ dst.func = src.func; \
12641+ else \
12642+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
12643+ } \
12644+} while (0)
12645+
12646+#define DySetForce(func, dst, src) do { \
12647+ AuDebugOn(!src.func); \
12648+ DyDbgInc(cnt); \
12649+ dst.func = src.func; \
12650+} while (0)
12651+
12652+#define DySetAop(func) \
12653+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
12654+#define DySetAopForce(func) \
12655+ DySetForce(func, dyaop->da_op, aufs_aop)
12656+
12657+static void dy_aop(struct au_dykey *key, const void *h_op,
12658+ struct super_block *h_sb __maybe_unused)
12659+{
12660+ struct au_dyaop *dyaop = (void *)key;
12661+ const struct address_space_operations *h_aop = h_op;
12662+ DyDbgDeclare(cnt);
12663+
12664+ AuDbg("%s\n", au_sbtype(h_sb));
12665+
12666+ DySetAop(writepage);
12667+ DySetAopForce(readpage); /* force */
4a4d8108
AM
12668+ DySetAop(writepages);
12669+ DySetAop(set_page_dirty);
12670+ DySetAop(readpages);
12671+ DySetAop(write_begin);
12672+ DySetAop(write_end);
12673+ DySetAop(bmap);
12674+ DySetAop(invalidatepage);
12675+ DySetAop(releasepage);
027c5e7a 12676+ DySetAop(freepage);
7e9cd9fe 12677+ /* this one will be changed according to an aufs mount option */
4a4d8108 12678+ DySetAop(direct_IO);
4a4d8108 12679+ DySetAop(migratepage);
e2f27e51
AM
12680+ DySetAop(isolate_page);
12681+ DySetAop(putback_page);
4a4d8108
AM
12682+ DySetAop(launder_page);
12683+ DySetAop(is_partially_uptodate);
392086de 12684+ DySetAop(is_dirty_writeback);
4a4d8108 12685+ DySetAop(error_remove_page);
b4510431
AM
12686+ DySetAop(swap_activate);
12687+ DySetAop(swap_deactivate);
4a4d8108
AM
12688+
12689+ DyDbgSize(cnt, *h_aop);
4a4d8108
AM
12690+}
12691+
4a4d8108
AM
12692+/* ---------------------------------------------------------------------- */
12693+
12694+static void dy_bug(struct kref *kref)
12695+{
12696+ BUG();
12697+}
12698+
12699+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
12700+{
12701+ struct au_dykey *key, *old;
8b6a4947 12702+ struct hlist_bl_head *hbl;
b752ccd1 12703+ struct op {
4a4d8108 12704+ unsigned int sz;
b752ccd1
AM
12705+ void (*set)(struct au_dykey *key, const void *h_op,
12706+ struct super_block *h_sb __maybe_unused);
12707+ };
12708+ static const struct op a[] = {
4a4d8108
AM
12709+ [AuDy_AOP] = {
12710+ .sz = sizeof(struct au_dyaop),
b752ccd1 12711+ .set = dy_aop
4a4d8108 12712+ }
b752ccd1
AM
12713+ };
12714+ const struct op *p;
4a4d8108 12715+
8b6a4947
AM
12716+ hbl = dynop + op->dy_type;
12717+ key = dy_gfind_get(hbl, op->dy_hop);
4a4d8108
AM
12718+ if (key)
12719+ goto out_add; /* success */
12720+
12721+ p = a + op->dy_type;
12722+ key = kzalloc(p->sz, GFP_NOFS);
12723+ if (unlikely(!key)) {
12724+ key = ERR_PTR(-ENOMEM);
12725+ goto out;
12726+ }
12727+
12728+ key->dk_op.dy_hop = op->dy_hop;
12729+ kref_init(&key->dk_kref);
86dc4139 12730+ p->set(key, op->dy_hop, au_br_sb(br));
8b6a4947 12731+ old = dy_gadd(hbl, key);
4a4d8108 12732+ if (old) {
1c60b727 12733+ kfree(key);
4a4d8108
AM
12734+ key = old;
12735+ }
12736+
12737+out_add:
12738+ old = dy_bradd(br, key);
12739+ if (old)
12740+ /* its ref-count should never be zero here */
12741+ kref_put(&key->dk_kref, dy_bug);
12742+out:
12743+ return key;
12744+}
12745+
12746+/* ---------------------------------------------------------------------- */
12747+/*
acd2b654 12748+ * Aufs prohibits O_DIRECT by default even if the branch supports it.
c1595e42 12749+ * This behaviour is necessary to return an error from open(O_DIRECT) instead
4a4d8108
AM
12750+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
12751+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
12752+ * See the aufs manual in detail.
4a4d8108
AM
12753+ */
12754+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
12755+{
7e9cd9fe 12756+ if (!do_dx)
4a4d8108 12757+ dyaop->da_op.direct_IO = NULL;
7e9cd9fe 12758+ else
4a4d8108 12759+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
4a4d8108
AM
12760+}
12761+
12762+static struct au_dyaop *dy_aget(struct au_branch *br,
12763+ const struct address_space_operations *h_aop,
12764+ int do_dx)
12765+{
12766+ struct au_dyaop *dyaop;
12767+ struct au_dynop op;
12768+
12769+ op.dy_type = AuDy_AOP;
12770+ op.dy_haop = h_aop;
12771+ dyaop = (void *)dy_get(&op, br);
12772+ if (IS_ERR(dyaop))
12773+ goto out;
12774+ dy_adx(dyaop, do_dx);
12775+
12776+out:
12777+ return dyaop;
12778+}
12779+
12780+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
12781+ struct inode *h_inode)
12782+{
12783+ int err, do_dx;
12784+ struct super_block *sb;
12785+ struct au_branch *br;
12786+ struct au_dyaop *dyaop;
12787+
12788+ AuDebugOn(!S_ISREG(h_inode->i_mode));
12789+ IiMustWriteLock(inode);
12790+
12791+ sb = inode->i_sb;
12792+ br = au_sbr(sb, bindex);
12793+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
12794+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
12795+ err = PTR_ERR(dyaop);
12796+ if (IS_ERR(dyaop))
12797+ /* unnecessary to call dy_fput() */
12798+ goto out;
12799+
12800+ err = 0;
12801+ inode->i_mapping->a_ops = &dyaop->da_op;
12802+
12803+out:
12804+ return err;
12805+}
12806+
b752ccd1
AM
12807+/*
12808+ * Is it safe to replace a_ops during the inode/file is in operation?
12809+ * Yes, I hope so.
12810+ */
12811+int au_dy_irefresh(struct inode *inode)
12812+{
12813+ int err;
5afbbe0d 12814+ aufs_bindex_t btop;
b752ccd1
AM
12815+ struct inode *h_inode;
12816+
12817+ err = 0;
12818+ if (S_ISREG(inode->i_mode)) {
5afbbe0d
AM
12819+ btop = au_ibtop(inode);
12820+ h_inode = au_h_iptr(inode, btop);
12821+ err = au_dy_iaop(inode, btop, h_inode);
b752ccd1
AM
12822+ }
12823+ return err;
12824+}
12825+
4a4d8108
AM
12826+void au_dy_arefresh(int do_dx)
12827+{
8b6a4947
AM
12828+ struct hlist_bl_head *hbl;
12829+ struct hlist_bl_node *pos;
4a4d8108
AM
12830+ struct au_dykey *key;
12831+
8b6a4947
AM
12832+ hbl = dynop + AuDy_AOP;
12833+ hlist_bl_lock(hbl);
12834+ hlist_bl_for_each_entry(key, pos, hbl, dk_hnode)
4a4d8108 12835+ dy_adx((void *)key, do_dx);
8b6a4947 12836+ hlist_bl_unlock(hbl);
4a4d8108
AM
12837+}
12838+
4a4d8108
AM
12839+/* ---------------------------------------------------------------------- */
12840+
12841+void __init au_dy_init(void)
12842+{
12843+ int i;
12844+
12845+ /* make sure that 'struct au_dykey *' can be any type */
12846+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
12847+
12848+ for (i = 0; i < AuDyLast; i++)
8b6a4947 12849+ INIT_HLIST_BL_HEAD(dynop + i);
4a4d8108
AM
12850+}
12851+
12852+void au_dy_fin(void)
12853+{
12854+ int i;
12855+
12856+ for (i = 0; i < AuDyLast; i++)
8b6a4947 12857+ WARN_ON(!hlist_bl_empty(dynop + i));
4a4d8108 12858+}
7f207e10
AM
12859diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
12860--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 12861+++ linux/fs/aufs/dynop.h 2018-08-12 23:43:05.456791299 +0200
062440b3
AM
12862@@ -0,0 +1,75 @@
12863+/* SPDX-License-Identifier: GPL-2.0 */
4a4d8108 12864+/*
b00004a5 12865+ * Copyright (C) 2010-2018 Junjiro R. Okajima
4a4d8108
AM
12866+ *
12867+ * This program, aufs is free software; you can redistribute it and/or modify
12868+ * it under the terms of the GNU General Public License as published by
12869+ * the Free Software Foundation; either version 2 of the License, or
12870+ * (at your option) any later version.
12871+ *
12872+ * This program is distributed in the hope that it will be useful,
12873+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12874+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12875+ * GNU General Public License for more details.
12876+ *
12877+ * You should have received a copy of the GNU General Public License
523b37e3 12878+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
12879+ */
12880+
12881+/*
12882+ * dynamically customizable operations (for regular files only)
12883+ */
12884+
12885+#ifndef __AUFS_DYNOP_H__
12886+#define __AUFS_DYNOP_H__
12887+
12888+#ifdef __KERNEL__
12889+
7e9cd9fe
AM
12890+#include <linux/fs.h>
12891+#include <linux/kref.h>
4a4d8108 12892+
2cbb1c4b 12893+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
12894+
12895+struct au_dynop {
12896+ int dy_type;
12897+ union {
12898+ const void *dy_hop;
12899+ const struct address_space_operations *dy_haop;
4a4d8108
AM
12900+ };
12901+};
12902+
12903+struct au_dykey {
12904+ union {
8b6a4947 12905+ struct hlist_bl_node dk_hnode;
4a4d8108
AM
12906+ struct rcu_head dk_rcu;
12907+ };
12908+ struct au_dynop dk_op;
12909+
12910+ /*
12911+ * during I am in the branch local array, kref is gotten. when the
12912+ * branch is removed, kref is put.
12913+ */
12914+ struct kref dk_kref;
12915+};
12916+
12917+/* stop unioning since their sizes are very different from each other */
12918+struct au_dyaop {
12919+ struct au_dykey da_key;
12920+ struct address_space_operations da_op; /* not const */
4a4d8108
AM
12921+};
12922+
4a4d8108
AM
12923+/* ---------------------------------------------------------------------- */
12924+
12925+/* dynop.c */
12926+struct au_branch;
12927+void au_dy_put(struct au_dykey *key);
12928+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
12929+ struct inode *h_inode);
b752ccd1 12930+int au_dy_irefresh(struct inode *inode);
4a4d8108 12931+void au_dy_arefresh(int do_dio);
4a4d8108
AM
12932+
12933+void __init au_dy_init(void);
12934+void au_dy_fin(void);
12935+
4a4d8108
AM
12936+#endif /* __KERNEL__ */
12937+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
12938diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
12939--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 12940+++ linux/fs/aufs/export.c 2018-10-23 12:33:35.596042364 +0200
062440b3 12941@@ -0,0 +1,838 @@
cd7a4cd9 12942+// SPDX-License-Identifier: GPL-2.0
4a4d8108 12943+/*
b00004a5 12944+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
12945+ *
12946+ * This program, aufs is free software; you can redistribute it and/or modify
12947+ * it under the terms of the GNU General Public License as published by
12948+ * the Free Software Foundation; either version 2 of the License, or
12949+ * (at your option) any later version.
12950+ *
12951+ * This program is distributed in the hope that it will be useful,
12952+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12953+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12954+ * GNU General Public License for more details.
12955+ *
12956+ * You should have received a copy of the GNU General Public License
523b37e3 12957+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
12958+ */
12959+
12960+/*
12961+ * export via nfs
12962+ */
12963+
12964+#include <linux/exportfs.h>
7eafdf33 12965+#include <linux/fs_struct.h>
4a4d8108
AM
12966+#include <linux/namei.h>
12967+#include <linux/nsproxy.h>
12968+#include <linux/random.h>
12969+#include <linux/writeback.h>
12970+#include "aufs.h"
12971+
12972+union conv {
12973+#ifdef CONFIG_AUFS_INO_T_64
12974+ __u32 a[2];
12975+#else
12976+ __u32 a[1];
12977+#endif
12978+ ino_t ino;
12979+};
12980+
12981+static ino_t decode_ino(__u32 *a)
12982+{
12983+ union conv u;
12984+
12985+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
12986+ u.a[0] = a[0];
12987+#ifdef CONFIG_AUFS_INO_T_64
12988+ u.a[1] = a[1];
12989+#endif
12990+ return u.ino;
12991+}
12992+
12993+static void encode_ino(__u32 *a, ino_t ino)
12994+{
12995+ union conv u;
12996+
12997+ u.ino = ino;
12998+ a[0] = u.a[0];
12999+#ifdef CONFIG_AUFS_INO_T_64
13000+ a[1] = u.a[1];
13001+#endif
13002+}
13003+
13004+/* NFS file handle */
13005+enum {
13006+ Fh_br_id,
13007+ Fh_sigen,
13008+#ifdef CONFIG_AUFS_INO_T_64
13009+ /* support 64bit inode number */
13010+ Fh_ino1,
13011+ Fh_ino2,
13012+ Fh_dir_ino1,
13013+ Fh_dir_ino2,
13014+#else
13015+ Fh_ino1,
13016+ Fh_dir_ino1,
13017+#endif
13018+ Fh_igen,
13019+ Fh_h_type,
13020+ Fh_tail,
13021+
13022+ Fh_ino = Fh_ino1,
13023+ Fh_dir_ino = Fh_dir_ino1
13024+};
13025+
13026+static int au_test_anon(struct dentry *dentry)
13027+{
027c5e7a 13028+ /* note: read d_flags without d_lock */
4a4d8108
AM
13029+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
13030+}
13031+
a2a7ad62
AM
13032+int au_test_nfsd(void)
13033+{
13034+ int ret;
13035+ struct task_struct *tsk = current;
13036+ char comm[sizeof(tsk->comm)];
13037+
13038+ ret = 0;
13039+ if (tsk->flags & PF_KTHREAD) {
13040+ get_task_comm(comm, tsk);
13041+ ret = !strcmp(comm, "nfsd");
13042+ }
13043+
13044+ return ret;
13045+}
13046+
4a4d8108
AM
13047+/* ---------------------------------------------------------------------- */
13048+/* inode generation external table */
13049+
b752ccd1 13050+void au_xigen_inc(struct inode *inode)
4a4d8108 13051+{
4a4d8108
AM
13052+ loff_t pos;
13053+ ssize_t sz;
13054+ __u32 igen;
13055+ struct super_block *sb;
13056+ struct au_sbinfo *sbinfo;
13057+
4a4d8108 13058+ sb = inode->i_sb;
b752ccd1 13059+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 13060+
b752ccd1 13061+ sbinfo = au_sbi(sb);
1facf9fc 13062+ pos = inode->i_ino;
13063+ pos *= sizeof(igen);
13064+ igen = inode->i_generation + 1;
1facf9fc 13065+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
13066+ sizeof(igen), &pos);
13067+ if (sz == sizeof(igen))
b752ccd1 13068+ return; /* success */
1facf9fc 13069+
b752ccd1 13070+ if (unlikely(sz >= 0))
1facf9fc 13071+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 13072+}
13073+
13074+int au_xigen_new(struct inode *inode)
13075+{
13076+ int err;
13077+ loff_t pos;
13078+ ssize_t sz;
13079+ struct super_block *sb;
13080+ struct au_sbinfo *sbinfo;
13081+ struct file *file;
13082+
13083+ err = 0;
13084+ /* todo: dirty, at mount time */
13085+ if (inode->i_ino == AUFS_ROOT_INO)
13086+ goto out;
13087+ sb = inode->i_sb;
dece6358 13088+ SiMustAnyLock(sb);
1facf9fc 13089+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
13090+ goto out;
13091+
13092+ err = -EFBIG;
13093+ pos = inode->i_ino;
13094+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
13095+ AuIOErr1("too large i%lld\n", pos);
13096+ goto out;
13097+ }
13098+ pos *= sizeof(inode->i_generation);
13099+
13100+ err = 0;
13101+ sbinfo = au_sbi(sb);
13102+ file = sbinfo->si_xigen;
13103+ BUG_ON(!file);
13104+
c06a8ce3 13105+ if (vfsub_f_size_read(file)
1facf9fc 13106+ < pos + sizeof(inode->i_generation)) {
13107+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
13108+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
13109+ sizeof(inode->i_generation), &pos);
13110+ } else
13111+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
13112+ sizeof(inode->i_generation), &pos);
13113+ if (sz == sizeof(inode->i_generation))
13114+ goto out; /* success */
13115+
13116+ err = sz;
13117+ if (unlikely(sz >= 0)) {
13118+ err = -EIO;
13119+ AuIOErr("xigen error (%zd)\n", sz);
13120+ }
13121+
4f0767ce 13122+out:
1facf9fc 13123+ return err;
13124+}
13125+
062440b3 13126+int au_xigen_set(struct super_block *sb, struct path *path)
1facf9fc 13127+{
13128+ int err;
13129+ struct au_sbinfo *sbinfo;
13130+ struct file *file;
13131+
dece6358
AM
13132+ SiMustWriteLock(sb);
13133+
1facf9fc 13134+ sbinfo = au_sbi(sb);
062440b3 13135+ file = au_xino_create2(sb, path, sbinfo->si_xigen);
1facf9fc 13136+ err = PTR_ERR(file);
13137+ if (IS_ERR(file))
13138+ goto out;
13139+ err = 0;
13140+ if (sbinfo->si_xigen)
13141+ fput(sbinfo->si_xigen);
13142+ sbinfo->si_xigen = file;
13143+
4f0767ce 13144+out:
062440b3 13145+ AuTraceErr(err);
1facf9fc 13146+ return err;
13147+}
13148+
13149+void au_xigen_clr(struct super_block *sb)
13150+{
13151+ struct au_sbinfo *sbinfo;
13152+
dece6358
AM
13153+ SiMustWriteLock(sb);
13154+
1facf9fc 13155+ sbinfo = au_sbi(sb);
13156+ if (sbinfo->si_xigen) {
13157+ fput(sbinfo->si_xigen);
13158+ sbinfo->si_xigen = NULL;
13159+ }
13160+}
13161+
13162+/* ---------------------------------------------------------------------- */
13163+
13164+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
13165+ ino_t dir_ino)
13166+{
13167+ struct dentry *dentry, *d;
13168+ struct inode *inode;
13169+ unsigned int sigen;
13170+
13171+ dentry = NULL;
13172+ inode = ilookup(sb, ino);
13173+ if (!inode)
13174+ goto out;
13175+
13176+ dentry = ERR_PTR(-ESTALE);
13177+ sigen = au_sigen(sb);
5afbbe0d 13178+ if (unlikely(au_is_bad_inode(inode)
1facf9fc 13179+ || IS_DEADDIR(inode)
537831f9 13180+ || sigen != au_iigen(inode, NULL)))
1facf9fc 13181+ goto out_iput;
13182+
13183+ dentry = NULL;
13184+ if (!dir_ino || S_ISDIR(inode->i_mode))
13185+ dentry = d_find_alias(inode);
13186+ else {
027c5e7a 13187+ spin_lock(&inode->i_lock);
c1595e42 13188+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 13189+ spin_lock(&d->d_lock);
1facf9fc 13190+ if (!au_test_anon(d)
5527c038 13191+ && d_inode(d->d_parent)->i_ino == dir_ino) {
027c5e7a
AM
13192+ dentry = dget_dlock(d);
13193+ spin_unlock(&d->d_lock);
1facf9fc 13194+ break;
13195+ }
027c5e7a
AM
13196+ spin_unlock(&d->d_lock);
13197+ }
13198+ spin_unlock(&inode->i_lock);
1facf9fc 13199+ }
027c5e7a 13200+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 13201+ /* need to refresh */
1facf9fc 13202+ dput(dentry);
2cbb1c4b 13203+ dentry = NULL;
1facf9fc 13204+ }
13205+
4f0767ce 13206+out_iput:
1facf9fc 13207+ iput(inode);
4f0767ce 13208+out:
2cbb1c4b 13209+ AuTraceErrPtr(dentry);
1facf9fc 13210+ return dentry;
13211+}
13212+
13213+/* ---------------------------------------------------------------------- */
13214+
13215+/* todo: dirty? */
13216+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
13217+
13218+struct au_compare_mnt_args {
13219+ /* input */
13220+ struct super_block *sb;
13221+
13222+ /* output */
13223+ struct vfsmount *mnt;
13224+};
13225+
13226+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
13227+{
13228+ struct au_compare_mnt_args *a = arg;
13229+
13230+ if (mnt->mnt_sb != a->sb)
13231+ return 0;
13232+ a->mnt = mntget(mnt);
13233+ return 1;
13234+}
13235+
1facf9fc 13236+static struct vfsmount *au_mnt_get(struct super_block *sb)
13237+{
4a4d8108 13238+ int err;
7eafdf33 13239+ struct path root;
4a4d8108
AM
13240+ struct au_compare_mnt_args args = {
13241+ .sb = sb
13242+ };
1facf9fc 13243+
7eafdf33 13244+ get_fs_root(current->fs, &root);
523b37e3 13245+ rcu_read_lock();
7eafdf33 13246+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 13247+ rcu_read_unlock();
7eafdf33 13248+ path_put(&root);
4a4d8108
AM
13249+ AuDebugOn(!err);
13250+ AuDebugOn(!args.mnt);
13251+ return args.mnt;
1facf9fc 13252+}
13253+
13254+struct au_nfsd_si_lock {
4a4d8108 13255+ unsigned int sigen;
027c5e7a 13256+ aufs_bindex_t bindex, br_id;
1facf9fc 13257+ unsigned char force_lock;
13258+};
13259+
027c5e7a
AM
13260+static int si_nfsd_read_lock(struct super_block *sb,
13261+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 13262+{
027c5e7a 13263+ int err;
1facf9fc 13264+ aufs_bindex_t bindex;
13265+
13266+ si_read_lock(sb, AuLock_FLUSH);
13267+
13268+ /* branch id may be wrapped around */
027c5e7a 13269+ err = 0;
1facf9fc 13270+ bindex = au_br_index(sb, nsi_lock->br_id);
13271+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
13272+ goto out; /* success */
13273+
027c5e7a
AM
13274+ err = -ESTALE;
13275+ bindex = -1;
1facf9fc 13276+ if (!nsi_lock->force_lock)
13277+ si_read_unlock(sb);
1facf9fc 13278+
4f0767ce 13279+out:
027c5e7a
AM
13280+ nsi_lock->bindex = bindex;
13281+ return err;
1facf9fc 13282+}
13283+
13284+struct find_name_by_ino {
392086de 13285+ struct dir_context ctx;
1facf9fc 13286+ int called, found;
13287+ ino_t ino;
13288+ char *name;
13289+ int namelen;
13290+};
13291+
13292+static int
392086de
AM
13293+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
13294+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 13295+{
392086de
AM
13296+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
13297+ ctx);
1facf9fc 13298+
13299+ a->called++;
13300+ if (a->ino != ino)
13301+ return 0;
13302+
13303+ memcpy(a->name, name, namelen);
13304+ a->namelen = namelen;
13305+ a->found = 1;
13306+ return 1;
13307+}
13308+
13309+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
13310+ struct au_nfsd_si_lock *nsi_lock)
13311+{
13312+ struct dentry *dentry, *parent;
13313+ struct file *file;
13314+ struct inode *dir;
392086de
AM
13315+ struct find_name_by_ino arg = {
13316+ .ctx = {
2000de60 13317+ .actor = find_name_by_ino
392086de
AM
13318+ }
13319+ };
1facf9fc 13320+ int err;
13321+
13322+ parent = path->dentry;
13323+ if (nsi_lock)
13324+ si_read_unlock(parent->d_sb);
4a4d8108 13325+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 13326+ dentry = (void *)file;
13327+ if (IS_ERR(file))
13328+ goto out;
13329+
13330+ dentry = ERR_PTR(-ENOMEM);
537831f9 13331+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 13332+ if (unlikely(!arg.name))
13333+ goto out_file;
13334+ arg.ino = ino;
13335+ arg.found = 0;
13336+ do {
13337+ arg.called = 0;
13338+ /* smp_mb(); */
392086de 13339+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 13340+ } while (!err && !arg.found && arg.called);
13341+ dentry = ERR_PTR(err);
13342+ if (unlikely(err))
13343+ goto out_name;
1716fcea
AM
13344+ /* instead of ENOENT */
13345+ dentry = ERR_PTR(-ESTALE);
1facf9fc 13346+ if (!arg.found)
13347+ goto out_name;
13348+
b4510431 13349+ /* do not call vfsub_lkup_one() */
5527c038 13350+ dir = d_inode(parent);
febd17d6 13351+ dentry = vfsub_lookup_one_len_unlocked(arg.name, parent, arg.namelen);
1facf9fc 13352+ AuTraceErrPtr(dentry);
13353+ if (IS_ERR(dentry))
13354+ goto out_name;
13355+ AuDebugOn(au_test_anon(dentry));
5527c038 13356+ if (unlikely(d_really_is_negative(dentry))) {
1facf9fc 13357+ dput(dentry);
13358+ dentry = ERR_PTR(-ENOENT);
13359+ }
13360+
4f0767ce 13361+out_name:
1c60b727 13362+ free_page((unsigned long)arg.name);
4f0767ce 13363+out_file:
1facf9fc 13364+ fput(file);
4f0767ce 13365+out:
1facf9fc 13366+ if (unlikely(nsi_lock
13367+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
13368+ if (!IS_ERR(dentry)) {
13369+ dput(dentry);
13370+ dentry = ERR_PTR(-ESTALE);
13371+ }
13372+ AuTraceErrPtr(dentry);
13373+ return dentry;
13374+}
13375+
13376+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
13377+ ino_t dir_ino,
13378+ struct au_nfsd_si_lock *nsi_lock)
13379+{
13380+ struct dentry *dentry;
13381+ struct path path;
13382+
13383+ if (dir_ino != AUFS_ROOT_INO) {
13384+ path.dentry = decode_by_ino(sb, dir_ino, 0);
13385+ dentry = path.dentry;
13386+ if (!path.dentry || IS_ERR(path.dentry))
13387+ goto out;
13388+ AuDebugOn(au_test_anon(path.dentry));
13389+ } else
13390+ path.dentry = dget(sb->s_root);
13391+
13392+ path.mnt = au_mnt_get(sb);
13393+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
13394+ path_put(&path);
13395+
4f0767ce 13396+out:
1facf9fc 13397+ AuTraceErrPtr(dentry);
13398+ return dentry;
13399+}
13400+
13401+/* ---------------------------------------------------------------------- */
13402+
13403+static int h_acceptable(void *expv, struct dentry *dentry)
13404+{
13405+ return 1;
13406+}
13407+
13408+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
13409+ char *buf, int len, struct super_block *sb)
13410+{
13411+ char *p;
13412+ int n;
13413+ struct path path;
13414+
13415+ p = d_path(h_rootpath, buf, len);
13416+ if (IS_ERR(p))
13417+ goto out;
13418+ n = strlen(p);
13419+
13420+ path.mnt = h_rootpath->mnt;
13421+ path.dentry = h_parent;
13422+ p = d_path(&path, buf, len);
13423+ if (IS_ERR(p))
13424+ goto out;
13425+ if (n != 1)
13426+ p += n;
13427+
13428+ path.mnt = au_mnt_get(sb);
13429+ path.dentry = sb->s_root;
13430+ p = d_path(&path, buf, len - strlen(p));
13431+ mntput(path.mnt);
13432+ if (IS_ERR(p))
13433+ goto out;
13434+ if (n != 1)
13435+ p[strlen(p)] = '/';
13436+
4f0767ce 13437+out:
1facf9fc 13438+ AuTraceErrPtr(p);
13439+ return p;
13440+}
13441+
13442+static
027c5e7a
AM
13443+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
13444+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 13445+{
13446+ struct dentry *dentry, *h_parent, *root;
13447+ struct super_block *h_sb;
13448+ char *pathname, *p;
13449+ struct vfsmount *h_mnt;
13450+ struct au_branch *br;
13451+ int err;
13452+ struct path path;
13453+
027c5e7a 13454+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 13455+ h_mnt = au_br_mnt(br);
1facf9fc 13456+ h_sb = h_mnt->mnt_sb;
13457+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
5afbbe0d 13458+ lockdep_off();
1facf9fc 13459+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
13460+ fh_len - Fh_tail, fh[Fh_h_type],
13461+ h_acceptable, /*context*/NULL);
5afbbe0d 13462+ lockdep_on();
1facf9fc 13463+ dentry = h_parent;
13464+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
13465+ AuWarn1("%s decode_fh failed, %ld\n",
13466+ au_sbtype(h_sb), PTR_ERR(h_parent));
13467+ goto out;
13468+ }
13469+ dentry = NULL;
13470+ if (unlikely(au_test_anon(h_parent))) {
13471+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
13472+ au_sbtype(h_sb));
13473+ goto out_h_parent;
13474+ }
13475+
13476+ dentry = ERR_PTR(-ENOMEM);
13477+ pathname = (void *)__get_free_page(GFP_NOFS);
13478+ if (unlikely(!pathname))
13479+ goto out_h_parent;
13480+
13481+ root = sb->s_root;
13482+ path.mnt = h_mnt;
13483+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 13484+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 13485+ di_read_unlock(root, !AuLock_IR);
13486+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
13487+ dentry = (void *)p;
13488+ if (IS_ERR(p))
13489+ goto out_pathname;
13490+
13491+ si_read_unlock(sb);
13492+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
13493+ dentry = ERR_PTR(err);
13494+ if (unlikely(err))
13495+ goto out_relock;
13496+
13497+ dentry = ERR_PTR(-ENOENT);
13498+ AuDebugOn(au_test_anon(path.dentry));
5527c038 13499+ if (unlikely(d_really_is_negative(path.dentry)))
1facf9fc 13500+ goto out_path;
13501+
5527c038 13502+ if (ino != d_inode(path.dentry)->i_ino)
1facf9fc 13503+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
13504+ else
13505+ dentry = dget(path.dentry);
13506+
4f0767ce 13507+out_path:
1facf9fc 13508+ path_put(&path);
4f0767ce 13509+out_relock:
1facf9fc 13510+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
13511+ if (!IS_ERR(dentry)) {
13512+ dput(dentry);
13513+ dentry = ERR_PTR(-ESTALE);
13514+ }
4f0767ce 13515+out_pathname:
1c60b727 13516+ free_page((unsigned long)pathname);
4f0767ce 13517+out_h_parent:
1facf9fc 13518+ dput(h_parent);
4f0767ce 13519+out:
1facf9fc 13520+ AuTraceErrPtr(dentry);
13521+ return dentry;
13522+}
13523+
13524+/* ---------------------------------------------------------------------- */
13525+
13526+static struct dentry *
13527+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
13528+ int fh_type)
13529+{
13530+ struct dentry *dentry;
13531+ __u32 *fh = fid->raw;
027c5e7a 13532+ struct au_branch *br;
1facf9fc 13533+ ino_t ino, dir_ino;
1facf9fc 13534+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 13535+ .force_lock = 0
13536+ };
13537+
1facf9fc 13538+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
13539+ /* it should never happen, but the file handle is unreliable */
13540+ if (unlikely(fh_len < Fh_tail))
13541+ goto out;
13542+ nsi_lock.sigen = fh[Fh_sigen];
13543+ nsi_lock.br_id = fh[Fh_br_id];
13544+
1facf9fc 13545+ /* branch id may be wrapped around */
027c5e7a
AM
13546+ br = NULL;
13547+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 13548+ goto out;
13549+ nsi_lock.force_lock = 1;
13550+
13551+ /* is this inode still cached? */
13552+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
13553+ /* it should never happen */
13554+ if (unlikely(ino == AUFS_ROOT_INO))
8cdd5066 13555+ goto out_unlock;
4a4d8108 13556+
1facf9fc 13557+ dir_ino = decode_ino(fh + Fh_dir_ino);
13558+ dentry = decode_by_ino(sb, ino, dir_ino);
13559+ if (IS_ERR(dentry))
13560+ goto out_unlock;
13561+ if (dentry)
13562+ goto accept;
13563+
13564+ /* is the parent dir cached? */
027c5e7a 13565+ br = au_sbr(sb, nsi_lock.bindex);
acd2b654 13566+ au_lcnt_inc(&br->br_nfiles);
1facf9fc 13567+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
13568+ if (IS_ERR(dentry))
13569+ goto out_unlock;
13570+ if (dentry)
13571+ goto accept;
13572+
13573+ /* lookup path */
027c5e7a 13574+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 13575+ if (IS_ERR(dentry))
13576+ goto out_unlock;
13577+ if (unlikely(!dentry))
13578+ /* todo?: make it ESTALE */
13579+ goto out_unlock;
13580+
4f0767ce 13581+accept:
027c5e7a 13582+ if (!au_digen_test(dentry, au_sigen(sb))
5527c038 13583+ && d_inode(dentry)->i_generation == fh[Fh_igen])
1facf9fc 13584+ goto out_unlock; /* success */
13585+
13586+ dput(dentry);
13587+ dentry = ERR_PTR(-ESTALE);
4f0767ce 13588+out_unlock:
027c5e7a 13589+ if (br)
acd2b654 13590+ au_lcnt_dec(&br->br_nfiles);
1facf9fc 13591+ si_read_unlock(sb);
4f0767ce 13592+out:
1facf9fc 13593+ AuTraceErrPtr(dentry);
13594+ return dentry;
13595+}
13596+
13597+#if 0 /* reserved for future use */
13598+/* support subtreecheck option */
13599+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
13600+ int fh_len, int fh_type)
13601+{
13602+ struct dentry *parent;
13603+ __u32 *fh = fid->raw;
13604+ ino_t dir_ino;
13605+
13606+ dir_ino = decode_ino(fh + Fh_dir_ino);
13607+ parent = decode_by_ino(sb, dir_ino, 0);
13608+ if (IS_ERR(parent))
13609+ goto out;
13610+ if (!parent)
13611+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
13612+ dir_ino, fh, fh_len);
13613+
4f0767ce 13614+out:
1facf9fc 13615+ AuTraceErrPtr(parent);
13616+ return parent;
13617+}
13618+#endif
13619+
13620+/* ---------------------------------------------------------------------- */
13621+
0c3ec466
AM
13622+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
13623+ struct inode *dir)
1facf9fc 13624+{
13625+ int err;
0c3ec466 13626+ aufs_bindex_t bindex;
1facf9fc 13627+ struct super_block *sb, *h_sb;
0c3ec466
AM
13628+ struct dentry *dentry, *parent, *h_parent;
13629+ struct inode *h_dir;
1facf9fc 13630+ struct au_branch *br;
13631+
1facf9fc 13632+ err = -ENOSPC;
13633+ if (unlikely(*max_len <= Fh_tail)) {
13634+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
13635+ goto out;
13636+ }
13637+
13638+ err = FILEID_ROOT;
0c3ec466
AM
13639+ if (inode->i_ino == AUFS_ROOT_INO) {
13640+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 13641+ goto out;
13642+ }
13643+
1facf9fc 13644+ h_parent = NULL;
0c3ec466
AM
13645+ sb = inode->i_sb;
13646+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
13647+ if (unlikely(err))
13648+ goto out;
13649+
1facf9fc 13650+#ifdef CONFIG_AUFS_DEBUG
13651+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
13652+ AuWarn1("NFS-exporting requires xino\n");
13653+#endif
027c5e7a 13654+ err = -EIO;
0c3ec466
AM
13655+ parent = NULL;
13656+ ii_read_lock_child(inode);
5afbbe0d 13657+ bindex = au_ibtop(inode);
0c3ec466 13658+ if (!dir) {
c1595e42 13659+ dentry = d_find_any_alias(inode);
0c3ec466
AM
13660+ if (unlikely(!dentry))
13661+ goto out_unlock;
13662+ AuDebugOn(au_test_anon(dentry));
13663+ parent = dget_parent(dentry);
13664+ dput(dentry);
13665+ if (unlikely(!parent))
13666+ goto out_unlock;
5527c038
JR
13667+ if (d_really_is_positive(parent))
13668+ dir = d_inode(parent);
1facf9fc 13669+ }
0c3ec466
AM
13670+
13671+ ii_read_lock_parent(dir);
13672+ h_dir = au_h_iptr(dir, bindex);
13673+ ii_read_unlock(dir);
13674+ if (unlikely(!h_dir))
13675+ goto out_parent;
c1595e42 13676+ h_parent = d_find_any_alias(h_dir);
1facf9fc 13677+ if (unlikely(!h_parent))
0c3ec466 13678+ goto out_hparent;
1facf9fc 13679+
13680+ err = -EPERM;
13681+ br = au_sbr(sb, bindex);
86dc4139 13682+ h_sb = au_br_sb(br);
1facf9fc 13683+ if (unlikely(!h_sb->s_export_op)) {
13684+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 13685+ goto out_hparent;
1facf9fc 13686+ }
13687+
13688+ fh[Fh_br_id] = br->br_id;
13689+ fh[Fh_sigen] = au_sigen(sb);
13690+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 13691+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 13692+ fh[Fh_igen] = inode->i_generation;
13693+
13694+ *max_len -= Fh_tail;
13695+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
13696+ max_len,
13697+ /*connectable or subtreecheck*/0);
13698+ err = fh[Fh_h_type];
13699+ *max_len += Fh_tail;
13700+ /* todo: macros? */
1716fcea 13701+ if (err != FILEID_INVALID)
1facf9fc 13702+ err = 99;
13703+ else
13704+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
13705+
0c3ec466 13706+out_hparent:
1facf9fc 13707+ dput(h_parent);
0c3ec466 13708+out_parent:
1facf9fc 13709+ dput(parent);
0c3ec466
AM
13710+out_unlock:
13711+ ii_read_unlock(inode);
13712+ si_read_unlock(sb);
4f0767ce 13713+out:
1facf9fc 13714+ if (unlikely(err < 0))
1716fcea 13715+ err = FILEID_INVALID;
1facf9fc 13716+ return err;
13717+}
13718+
13719+/* ---------------------------------------------------------------------- */
13720+
4a4d8108
AM
13721+static int aufs_commit_metadata(struct inode *inode)
13722+{
13723+ int err;
13724+ aufs_bindex_t bindex;
13725+ struct super_block *sb;
13726+ struct inode *h_inode;
13727+ int (*f)(struct inode *inode);
13728+
13729+ sb = inode->i_sb;
e49829fe 13730+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 13731+ ii_write_lock_child(inode);
5afbbe0d 13732+ bindex = au_ibtop(inode);
4a4d8108
AM
13733+ AuDebugOn(bindex < 0);
13734+ h_inode = au_h_iptr(inode, bindex);
13735+
13736+ f = h_inode->i_sb->s_export_op->commit_metadata;
13737+ if (f)
13738+ err = f(h_inode);
13739+ else {
13740+ struct writeback_control wbc = {
13741+ .sync_mode = WB_SYNC_ALL,
13742+ .nr_to_write = 0 /* metadata only */
13743+ };
13744+
13745+ err = sync_inode(h_inode, &wbc);
13746+ }
13747+
13748+ au_cpup_attr_timesizes(inode);
13749+ ii_write_unlock(inode);
13750+ si_read_unlock(sb);
13751+ return err;
13752+}
13753+
13754+/* ---------------------------------------------------------------------- */
13755+
1facf9fc 13756+static struct export_operations aufs_export_op = {
4a4d8108 13757+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 13758+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
13759+ .encode_fh = aufs_encode_fh,
13760+ .commit_metadata = aufs_commit_metadata
1facf9fc 13761+};
13762+
13763+void au_export_init(struct super_block *sb)
13764+{
13765+ struct au_sbinfo *sbinfo;
13766+ __u32 u;
13767+
5afbbe0d
AM
13768+ BUILD_BUG_ON_MSG(IS_BUILTIN(CONFIG_AUFS_FS)
13769+ && IS_MODULE(CONFIG_EXPORTFS),
13770+ AUFS_NAME ": unsupported configuration "
13771+ "CONFIG_EXPORTFS=m and CONFIG_AUFS_FS=y");
13772+
1facf9fc 13773+ sb->s_export_op = &aufs_export_op;
13774+ sbinfo = au_sbi(sb);
13775+ sbinfo->si_xigen = NULL;
13776+ get_random_bytes(&u, sizeof(u));
13777+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
13778+ atomic_set(&sbinfo->si_xigen_next, u);
13779+}
076b876e
AM
13780diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
13781--- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 13782+++ linux/fs/aufs/fhsm.c 2018-10-23 12:33:35.596042364 +0200
062440b3 13783@@ -0,0 +1,427 @@
cd7a4cd9 13784+// SPDX-License-Identifier: GPL-2.0
076b876e 13785+/*
b00004a5 13786+ * Copyright (C) 2011-2018 Junjiro R. Okajima
076b876e
AM
13787+ *
13788+ * This program, aufs is free software; you can redistribute it and/or modify
13789+ * it under the terms of the GNU General Public License as published by
13790+ * the Free Software Foundation; either version 2 of the License, or
13791+ * (at your option) any later version.
13792+ *
13793+ * This program is distributed in the hope that it will be useful,
13794+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13795+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13796+ * GNU General Public License for more details.
13797+ *
13798+ * You should have received a copy of the GNU General Public License
13799+ * along with this program; if not, write to the Free Software
13800+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
13801+ */
13802+
13803+/*
13804+ * File-based Hierarchy Storage Management
13805+ */
13806+
13807+#include <linux/anon_inodes.h>
13808+#include <linux/poll.h>
13809+#include <linux/seq_file.h>
13810+#include <linux/statfs.h>
13811+#include "aufs.h"
13812+
c1595e42
JR
13813+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb)
13814+{
13815+ struct au_sbinfo *sbinfo;
13816+ struct au_fhsm *fhsm;
13817+
13818+ SiMustAnyLock(sb);
13819+
13820+ sbinfo = au_sbi(sb);
13821+ fhsm = &sbinfo->si_fhsm;
13822+ AuDebugOn(!fhsm);
13823+ return fhsm->fhsm_bottom;
13824+}
13825+
13826+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex)
13827+{
13828+ struct au_sbinfo *sbinfo;
13829+ struct au_fhsm *fhsm;
13830+
13831+ SiMustWriteLock(sb);
13832+
13833+ sbinfo = au_sbi(sb);
13834+ fhsm = &sbinfo->si_fhsm;
13835+ AuDebugOn(!fhsm);
13836+ fhsm->fhsm_bottom = bindex;
13837+}
13838+
13839+/* ---------------------------------------------------------------------- */
13840+
076b876e
AM
13841+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
13842+{
13843+ struct au_br_fhsm *bf;
13844+
13845+ bf = br->br_fhsm;
13846+ MtxMustLock(&bf->bf_lock);
13847+
13848+ return !bf->bf_readable
13849+ || time_after(jiffies,
13850+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
13851+}
13852+
13853+/* ---------------------------------------------------------------------- */
13854+
13855+static void au_fhsm_notify(struct super_block *sb, int val)
13856+{
13857+ struct au_sbinfo *sbinfo;
13858+ struct au_fhsm *fhsm;
13859+
13860+ SiMustAnyLock(sb);
13861+
13862+ sbinfo = au_sbi(sb);
13863+ fhsm = &sbinfo->si_fhsm;
13864+ if (au_fhsm_pid(fhsm)
13865+ && atomic_read(&fhsm->fhsm_readable) != -1) {
13866+ atomic_set(&fhsm->fhsm_readable, val);
13867+ if (val)
13868+ wake_up(&fhsm->fhsm_wqh);
13869+ }
13870+}
13871+
13872+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
13873+ struct aufs_stfs *rstfs, int do_lock, int do_notify)
13874+{
13875+ int err;
13876+ struct au_branch *br;
13877+ struct au_br_fhsm *bf;
13878+
13879+ br = au_sbr(sb, bindex);
13880+ AuDebugOn(au_br_rdonly(br));
13881+ bf = br->br_fhsm;
13882+ AuDebugOn(!bf);
13883+
13884+ if (do_lock)
13885+ mutex_lock(&bf->bf_lock);
13886+ else
13887+ MtxMustLock(&bf->bf_lock);
13888+
13889+ /* sb->s_root for NFS is unreliable */
13890+ err = au_br_stfs(br, &bf->bf_stfs);
13891+ if (unlikely(err)) {
13892+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
13893+ goto out;
13894+ }
13895+
13896+ bf->bf_jiffy = jiffies;
13897+ bf->bf_readable = 1;
13898+ if (do_notify)
13899+ au_fhsm_notify(sb, /*val*/1);
13900+ if (rstfs)
13901+ *rstfs = bf->bf_stfs;
13902+
13903+out:
13904+ if (do_lock)
13905+ mutex_unlock(&bf->bf_lock);
13906+ au_fhsm_notify(sb, /*val*/1);
13907+
13908+ return err;
13909+}
13910+
13911+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
13912+{
13913+ int err;
076b876e
AM
13914+ struct au_sbinfo *sbinfo;
13915+ struct au_fhsm *fhsm;
13916+ struct au_branch *br;
13917+ struct au_br_fhsm *bf;
13918+
13919+ AuDbg("b%d, force %d\n", bindex, force);
13920+ SiMustAnyLock(sb);
13921+
13922+ sbinfo = au_sbi(sb);
13923+ fhsm = &sbinfo->si_fhsm;
c1595e42
JR
13924+ if (!au_ftest_si(sbinfo, FHSM)
13925+ || fhsm->fhsm_bottom == bindex)
076b876e
AM
13926+ return;
13927+
13928+ br = au_sbr(sb, bindex);
13929+ bf = br->br_fhsm;
13930+ AuDebugOn(!bf);
13931+ mutex_lock(&bf->bf_lock);
13932+ if (force
13933+ || au_fhsm_pid(fhsm)
13934+ || au_fhsm_test_jiffy(sbinfo, br))
13935+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
13936+ /*do_notify*/1);
13937+ mutex_unlock(&bf->bf_lock);
13938+}
13939+
13940+void au_fhsm_wrote_all(struct super_block *sb, int force)
13941+{
5afbbe0d 13942+ aufs_bindex_t bindex, bbot;
076b876e
AM
13943+ struct au_branch *br;
13944+
13945+ /* exclude the bottom */
5afbbe0d
AM
13946+ bbot = au_fhsm_bottom(sb);
13947+ for (bindex = 0; bindex < bbot; bindex++) {
076b876e
AM
13948+ br = au_sbr(sb, bindex);
13949+ if (au_br_fhsm(br->br_perm))
13950+ au_fhsm_wrote(sb, bindex, force);
13951+ }
13952+}
13953+
13954+/* ---------------------------------------------------------------------- */
13955+
be118d29 13956+static __poll_t au_fhsm_poll(struct file *file, struct poll_table_struct *wait)
076b876e 13957+{
be118d29 13958+ __poll_t mask;
076b876e
AM
13959+ struct au_sbinfo *sbinfo;
13960+ struct au_fhsm *fhsm;
13961+
13962+ mask = 0;
13963+ sbinfo = file->private_data;
13964+ fhsm = &sbinfo->si_fhsm;
13965+ poll_wait(file, &fhsm->fhsm_wqh, wait);
13966+ if (atomic_read(&fhsm->fhsm_readable))
be118d29 13967+ mask = EPOLLIN /* | EPOLLRDNORM */;
076b876e 13968+
b00004a5
AM
13969+ if (!mask)
13970+ AuDbg("mask 0x%x\n", mask);
076b876e
AM
13971+ return mask;
13972+}
13973+
13974+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
13975+ struct aufs_stfs *stfs, __s16 brid)
13976+{
13977+ int err;
13978+
13979+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
13980+ if (!err)
13981+ err = __put_user(brid, &stbr->brid);
13982+ if (unlikely(err))
13983+ err = -EFAULT;
13984+
13985+ return err;
13986+}
13987+
13988+static ssize_t au_fhsm_do_read(struct super_block *sb,
13989+ struct aufs_stbr __user *stbr, size_t count)
13990+{
13991+ ssize_t err;
13992+ int nstbr;
5afbbe0d 13993+ aufs_bindex_t bindex, bbot;
076b876e
AM
13994+ struct au_branch *br;
13995+ struct au_br_fhsm *bf;
13996+
13997+ /* except the bottom branch */
13998+ err = 0;
13999+ nstbr = 0;
5afbbe0d
AM
14000+ bbot = au_fhsm_bottom(sb);
14001+ for (bindex = 0; !err && bindex < bbot; bindex++) {
076b876e
AM
14002+ br = au_sbr(sb, bindex);
14003+ if (!au_br_fhsm(br->br_perm))
14004+ continue;
14005+
14006+ bf = br->br_fhsm;
14007+ mutex_lock(&bf->bf_lock);
14008+ if (bf->bf_readable) {
14009+ err = -EFAULT;
14010+ if (count >= sizeof(*stbr))
14011+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
14012+ br->br_id);
14013+ if (!err) {
14014+ bf->bf_readable = 0;
14015+ count -= sizeof(*stbr);
14016+ nstbr++;
14017+ }
14018+ }
14019+ mutex_unlock(&bf->bf_lock);
14020+ }
14021+ if (!err)
14022+ err = sizeof(*stbr) * nstbr;
14023+
14024+ return err;
14025+}
14026+
14027+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
14028+ loff_t *pos)
14029+{
14030+ ssize_t err;
14031+ int readable;
5afbbe0d 14032+ aufs_bindex_t nfhsm, bindex, bbot;
076b876e
AM
14033+ struct au_sbinfo *sbinfo;
14034+ struct au_fhsm *fhsm;
14035+ struct au_branch *br;
14036+ struct super_block *sb;
14037+
14038+ err = 0;
14039+ sbinfo = file->private_data;
14040+ fhsm = &sbinfo->si_fhsm;
14041+need_data:
14042+ spin_lock_irq(&fhsm->fhsm_wqh.lock);
14043+ if (!atomic_read(&fhsm->fhsm_readable)) {
14044+ if (vfsub_file_flags(file) & O_NONBLOCK)
14045+ err = -EAGAIN;
14046+ else
14047+ err = wait_event_interruptible_locked_irq
14048+ (fhsm->fhsm_wqh,
14049+ atomic_read(&fhsm->fhsm_readable));
14050+ }
14051+ spin_unlock_irq(&fhsm->fhsm_wqh.lock);
14052+ if (unlikely(err))
14053+ goto out;
14054+
14055+ /* sb may already be dead */
14056+ au_rw_read_lock(&sbinfo->si_rwsem);
14057+ readable = atomic_read(&fhsm->fhsm_readable);
14058+ if (readable > 0) {
14059+ sb = sbinfo->si_sb;
14060+ AuDebugOn(!sb);
14061+ /* exclude the bottom branch */
14062+ nfhsm = 0;
5afbbe0d
AM
14063+ bbot = au_fhsm_bottom(sb);
14064+ for (bindex = 0; bindex < bbot; bindex++) {
076b876e
AM
14065+ br = au_sbr(sb, bindex);
14066+ if (au_br_fhsm(br->br_perm))
14067+ nfhsm++;
14068+ }
14069+ err = -EMSGSIZE;
14070+ if (nfhsm * sizeof(struct aufs_stbr) <= count) {
14071+ atomic_set(&fhsm->fhsm_readable, 0);
14072+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
14073+ count);
14074+ }
14075+ }
14076+ au_rw_read_unlock(&sbinfo->si_rwsem);
14077+ if (!readable)
14078+ goto need_data;
14079+
14080+out:
14081+ return err;
14082+}
14083+
14084+static int au_fhsm_release(struct inode *inode, struct file *file)
14085+{
14086+ struct au_sbinfo *sbinfo;
14087+ struct au_fhsm *fhsm;
14088+
14089+ /* sb may already be dead */
14090+ sbinfo = file->private_data;
14091+ fhsm = &sbinfo->si_fhsm;
14092+ spin_lock(&fhsm->fhsm_spin);
14093+ fhsm->fhsm_pid = 0;
14094+ spin_unlock(&fhsm->fhsm_spin);
14095+ kobject_put(&sbinfo->si_kobj);
14096+
14097+ return 0;
14098+}
14099+
14100+static const struct file_operations au_fhsm_fops = {
14101+ .owner = THIS_MODULE,
14102+ .llseek = noop_llseek,
14103+ .read = au_fhsm_read,
14104+ .poll = au_fhsm_poll,
14105+ .release = au_fhsm_release
14106+};
14107+
14108+int au_fhsm_fd(struct super_block *sb, int oflags)
14109+{
14110+ int err, fd;
14111+ struct au_sbinfo *sbinfo;
14112+ struct au_fhsm *fhsm;
14113+
14114+ err = -EPERM;
14115+ if (unlikely(!capable(CAP_SYS_ADMIN)))
14116+ goto out;
14117+
14118+ err = -EINVAL;
14119+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
14120+ goto out;
14121+
14122+ err = 0;
14123+ sbinfo = au_sbi(sb);
14124+ fhsm = &sbinfo->si_fhsm;
14125+ spin_lock(&fhsm->fhsm_spin);
14126+ if (!fhsm->fhsm_pid)
14127+ fhsm->fhsm_pid = current->pid;
14128+ else
14129+ err = -EBUSY;
14130+ spin_unlock(&fhsm->fhsm_spin);
14131+ if (unlikely(err))
14132+ goto out;
14133+
14134+ oflags |= O_RDONLY;
14135+ /* oflags |= FMODE_NONOTIFY; */
14136+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
14137+ err = fd;
14138+ if (unlikely(fd < 0))
14139+ goto out_pid;
14140+
acd2b654 14141+ /* succeed regardless 'fhsm' status */
076b876e
AM
14142+ kobject_get(&sbinfo->si_kobj);
14143+ si_noflush_read_lock(sb);
14144+ if (au_ftest_si(sbinfo, FHSM))
14145+ au_fhsm_wrote_all(sb, /*force*/0);
14146+ si_read_unlock(sb);
14147+ goto out; /* success */
14148+
14149+out_pid:
14150+ spin_lock(&fhsm->fhsm_spin);
14151+ fhsm->fhsm_pid = 0;
14152+ spin_unlock(&fhsm->fhsm_spin);
14153+out:
14154+ AuTraceErr(err);
14155+ return err;
14156+}
14157+
14158+/* ---------------------------------------------------------------------- */
14159+
14160+int au_fhsm_br_alloc(struct au_branch *br)
14161+{
14162+ int err;
14163+
14164+ err = 0;
14165+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
14166+ if (br->br_fhsm)
14167+ au_br_fhsm_init(br->br_fhsm);
14168+ else
14169+ err = -ENOMEM;
14170+
14171+ return err;
14172+}
14173+
14174+/* ---------------------------------------------------------------------- */
14175+
14176+void au_fhsm_fin(struct super_block *sb)
14177+{
14178+ au_fhsm_notify(sb, /*val*/-1);
14179+}
14180+
14181+void au_fhsm_init(struct au_sbinfo *sbinfo)
14182+{
14183+ struct au_fhsm *fhsm;
14184+
14185+ fhsm = &sbinfo->si_fhsm;
14186+ spin_lock_init(&fhsm->fhsm_spin);
14187+ init_waitqueue_head(&fhsm->fhsm_wqh);
14188+ atomic_set(&fhsm->fhsm_readable, 0);
14189+ fhsm->fhsm_expire
14190+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
c1595e42 14191+ fhsm->fhsm_bottom = -1;
076b876e
AM
14192+}
14193+
14194+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
14195+{
14196+ sbinfo->si_fhsm.fhsm_expire
14197+ = msecs_to_jiffies(sec * MSEC_PER_SEC);
14198+}
14199+
14200+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
14201+{
14202+ unsigned int u;
14203+
14204+ if (!au_ftest_si(sbinfo, FHSM))
14205+ return;
14206+
14207+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
14208+ if (u != AUFS_FHSM_CACHE_DEF_SEC)
14209+ seq_printf(seq, ",fhsm_sec=%u", u);
14210+}
7f207e10
AM
14211diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
14212--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
14213+++ linux/fs/aufs/file.c 2018-10-23 12:33:35.596042364 +0200
14214@@ -0,0 +1,863 @@
cd7a4cd9 14215+// SPDX-License-Identifier: GPL-2.0
1facf9fc 14216+/*
b00004a5 14217+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 14218+ *
14219+ * This program, aufs is free software; you can redistribute it and/or modify
14220+ * it under the terms of the GNU General Public License as published by
14221+ * the Free Software Foundation; either version 2 of the License, or
14222+ * (at your option) any later version.
dece6358
AM
14223+ *
14224+ * This program is distributed in the hope that it will be useful,
14225+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14226+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14227+ * GNU General Public License for more details.
14228+ *
14229+ * You should have received a copy of the GNU General Public License
523b37e3 14230+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 14231+ */
14232+
14233+/*
4a4d8108 14234+ * handling file/dir, and address_space operation
1facf9fc 14235+ */
14236+
7eafdf33
AM
14237+#ifdef CONFIG_AUFS_DEBUG
14238+#include <linux/migrate.h>
14239+#endif
4a4d8108 14240+#include <linux/pagemap.h>
1facf9fc 14241+#include "aufs.h"
14242+
4a4d8108
AM
14243+/* drop flags for writing */
14244+unsigned int au_file_roflags(unsigned int flags)
14245+{
14246+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
14247+ flags |= O_RDONLY | O_NOATIME;
14248+ return flags;
14249+}
14250+
14251+/* common functions to regular file and dir */
14252+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 14253+ struct file *file, int force_wr)
1facf9fc 14254+{
1308ab2a 14255+ struct file *h_file;
4a4d8108
AM
14256+ struct dentry *h_dentry;
14257+ struct inode *h_inode;
14258+ struct super_block *sb;
14259+ struct au_branch *br;
14260+ struct path h_path;
b912730e 14261+ int err;
1facf9fc 14262+
4a4d8108
AM
14263+ /* a race condition can happen between open and unlink/rmdir */
14264+ h_file = ERR_PTR(-ENOENT);
14265+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 14266+ if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry)))
4a4d8108 14267+ goto out;
5527c038 14268+ h_inode = d_inode(h_dentry);
027c5e7a
AM
14269+ spin_lock(&h_dentry->d_lock);
14270+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
5527c038 14271+ /* || !d_inode(dentry)->i_nlink */
027c5e7a
AM
14272+ ;
14273+ spin_unlock(&h_dentry->d_lock);
14274+ if (unlikely(err))
4a4d8108 14275+ goto out;
1facf9fc 14276+
4a4d8108
AM
14277+ sb = dentry->d_sb;
14278+ br = au_sbr(sb, bindex);
b912730e
AM
14279+ err = au_br_test_oflag(flags, br);
14280+ h_file = ERR_PTR(err);
14281+ if (unlikely(err))
027c5e7a 14282+ goto out;
1facf9fc 14283+
4a4d8108 14284+ /* drop flags for writing */
5527c038 14285+ if (au_test_ro(sb, bindex, d_inode(dentry))) {
392086de
AM
14286+ if (force_wr && !(flags & O_WRONLY))
14287+ force_wr = 0;
4a4d8108 14288+ flags = au_file_roflags(flags);
392086de
AM
14289+ if (force_wr) {
14290+ h_file = ERR_PTR(-EROFS);
14291+ flags = au_file_roflags(flags);
14292+ if (unlikely(vfsub_native_ro(h_inode)
14293+ || IS_APPEND(h_inode)))
14294+ goto out;
14295+ flags &= ~O_ACCMODE;
14296+ flags |= O_WRONLY;
14297+ }
14298+ }
4a4d8108 14299+ flags &= ~O_CREAT;
acd2b654 14300+ au_lcnt_inc(&br->br_nfiles);
4a4d8108 14301+ h_path.dentry = h_dentry;
86dc4139 14302+ h_path.mnt = au_br_mnt(br);
38d290e6 14303+ h_file = vfsub_dentry_open(&h_path, flags);
4a4d8108
AM
14304+ if (IS_ERR(h_file))
14305+ goto out_br;
dece6358 14306+
b912730e 14307+ if (flags & __FMODE_EXEC) {
4a4d8108
AM
14308+ err = deny_write_access(h_file);
14309+ if (unlikely(err)) {
14310+ fput(h_file);
14311+ h_file = ERR_PTR(err);
14312+ goto out_br;
14313+ }
14314+ }
953406b4 14315+ fsnotify_open(h_file);
4a4d8108 14316+ goto out; /* success */
1facf9fc 14317+
4f0767ce 14318+out_br:
acd2b654 14319+ au_lcnt_dec(&br->br_nfiles);
4f0767ce 14320+out:
4a4d8108
AM
14321+ return h_file;
14322+}
1308ab2a 14323+
076b876e
AM
14324+static int au_cmoo(struct dentry *dentry)
14325+{
8b6a4947 14326+ int err, cmoo, matched;
076b876e
AM
14327+ unsigned int udba;
14328+ struct path h_path;
14329+ struct au_pin pin;
14330+ struct au_cp_generic cpg = {
14331+ .dentry = dentry,
14332+ .bdst = -1,
14333+ .bsrc = -1,
14334+ .len = -1,
14335+ .pin = &pin,
14336+ .flags = AuCpup_DTIME | AuCpup_HOPEN
14337+ };
7e9cd9fe 14338+ struct inode *delegated;
076b876e
AM
14339+ struct super_block *sb;
14340+ struct au_sbinfo *sbinfo;
14341+ struct au_fhsm *fhsm;
14342+ pid_t pid;
14343+ struct au_branch *br;
14344+ struct dentry *parent;
14345+ struct au_hinode *hdir;
14346+
14347+ DiMustWriteLock(dentry);
5527c038 14348+ IiMustWriteLock(d_inode(dentry));
076b876e
AM
14349+
14350+ err = 0;
14351+ if (IS_ROOT(dentry))
14352+ goto out;
5afbbe0d 14353+ cpg.bsrc = au_dbtop(dentry);
076b876e
AM
14354+ if (!cpg.bsrc)
14355+ goto out;
14356+
14357+ sb = dentry->d_sb;
14358+ sbinfo = au_sbi(sb);
14359+ fhsm = &sbinfo->si_fhsm;
14360+ pid = au_fhsm_pid(fhsm);
8b6a4947
AM
14361+ rcu_read_lock();
14362+ matched = (pid
14363+ && (current->pid == pid
14364+ || rcu_dereference(current->real_parent)->pid == pid));
14365+ rcu_read_unlock();
14366+ if (matched)
076b876e
AM
14367+ goto out;
14368+
14369+ br = au_sbr(sb, cpg.bsrc);
14370+ cmoo = au_br_cmoo(br->br_perm);
14371+ if (!cmoo)
14372+ goto out;
7e9cd9fe 14373+ if (!d_is_reg(dentry))
076b876e
AM
14374+ cmoo &= AuBrAttr_COO_ALL;
14375+ if (!cmoo)
14376+ goto out;
14377+
14378+ parent = dget_parent(dentry);
14379+ di_write_lock_parent(parent);
14380+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
14381+ cpg.bdst = err;
14382+ if (unlikely(err < 0)) {
14383+ err = 0; /* there is no upper writable branch */
14384+ goto out_dgrade;
14385+ }
14386+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
14387+
14388+ /* do not respect the coo attrib for the target branch */
14389+ err = au_cpup_dirs(dentry, cpg.bdst);
14390+ if (unlikely(err))
14391+ goto out_dgrade;
14392+
14393+ di_downgrade_lock(parent, AuLock_IR);
14394+ udba = au_opt_udba(sb);
14395+ err = au_pin(&pin, dentry, cpg.bdst, udba,
14396+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14397+ if (unlikely(err))
14398+ goto out_parent;
14399+
14400+ err = au_sio_cpup_simple(&cpg);
14401+ au_unpin(&pin);
14402+ if (unlikely(err))
14403+ goto out_parent;
14404+ if (!(cmoo & AuBrWAttr_MOO))
14405+ goto out_parent; /* success */
14406+
14407+ err = au_pin(&pin, dentry, cpg.bsrc, udba,
14408+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14409+ if (unlikely(err))
14410+ goto out_parent;
14411+
14412+ h_path.mnt = au_br_mnt(br);
14413+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
5527c038 14414+ hdir = au_hi(d_inode(parent), cpg.bsrc);
076b876e
AM
14415+ delegated = NULL;
14416+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
14417+ au_unpin(&pin);
14418+ /* todo: keep h_dentry or not? */
14419+ if (unlikely(err == -EWOULDBLOCK)) {
14420+ pr_warn("cannot retry for NFSv4 delegation"
14421+ " for an internal unlink\n");
14422+ iput(delegated);
14423+ }
14424+ if (unlikely(err)) {
14425+ pr_err("unlink %pd after coo failed (%d), ignored\n",
14426+ dentry, err);
14427+ err = 0;
14428+ }
14429+ goto out_parent; /* success */
14430+
14431+out_dgrade:
14432+ di_downgrade_lock(parent, AuLock_IR);
14433+out_parent:
14434+ di_read_unlock(parent, AuLock_IR);
14435+ dput(parent);
14436+out:
14437+ AuTraceErr(err);
14438+ return err;
14439+}
14440+
b912730e 14441+int au_do_open(struct file *file, struct au_do_open_args *args)
1facf9fc 14442+{
8b6a4947 14443+ int err, aopen = args->aopen;
1facf9fc 14444+ struct dentry *dentry;
076b876e 14445+ struct au_finfo *finfo;
1308ab2a 14446+
8b6a4947 14447+ if (!aopen)
b912730e
AM
14448+ err = au_finfo_init(file, args->fidir);
14449+ else {
14450+ lockdep_off();
14451+ err = au_finfo_init(file, args->fidir);
14452+ lockdep_on();
14453+ }
4a4d8108
AM
14454+ if (unlikely(err))
14455+ goto out;
1facf9fc 14456+
2000de60 14457+ dentry = file->f_path.dentry;
b912730e 14458+ AuDebugOn(IS_ERR_OR_NULL(dentry));
8b6a4947
AM
14459+ di_write_lock_child(dentry);
14460+ err = au_cmoo(dentry);
14461+ di_downgrade_lock(dentry, AuLock_IR);
14462+ if (!err) {
14463+ if (!aopen)
b912730e 14464+ err = args->open(file, vfsub_file_flags(file), NULL);
8b6a4947
AM
14465+ else {
14466+ lockdep_off();
acd2b654
AM
14467+ err = args->open(file, vfsub_file_flags(file),
14468+ args->h_file);
8b6a4947
AM
14469+ lockdep_on();
14470+ }
b912730e 14471+ }
8b6a4947 14472+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 14473+
076b876e
AM
14474+ finfo = au_fi(file);
14475+ if (!err) {
14476+ finfo->fi_file = file;
8b6a4947
AM
14477+ au_hbl_add(&finfo->fi_hlist,
14478+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
076b876e 14479+ }
8b6a4947 14480+ if (!aopen)
b912730e
AM
14481+ fi_write_unlock(file);
14482+ else {
14483+ lockdep_off();
14484+ fi_write_unlock(file);
14485+ lockdep_on();
14486+ }
4a4d8108 14487+ if (unlikely(err)) {
076b876e 14488+ finfo->fi_hdir = NULL;
1c60b727 14489+ au_finfo_fin(file);
1308ab2a 14490+ }
4a4d8108 14491+
4f0767ce 14492+out:
8b6a4947 14493+ AuTraceErr(err);
1308ab2a 14494+ return err;
14495+}
dece6358 14496+
4a4d8108 14497+int au_reopen_nondir(struct file *file)
1308ab2a 14498+{
4a4d8108 14499+ int err;
5afbbe0d 14500+ aufs_bindex_t btop;
4a4d8108 14501+ struct dentry *dentry;
acd2b654 14502+ struct au_branch *br;
4a4d8108 14503+ struct file *h_file, *h_file_tmp;
1308ab2a 14504+
2000de60 14505+ dentry = file->f_path.dentry;
5afbbe0d 14506+ btop = au_dbtop(dentry);
acd2b654 14507+ br = au_sbr(dentry->d_sb, btop);
4a4d8108 14508+ h_file_tmp = NULL;
5afbbe0d 14509+ if (au_fbtop(file) == btop) {
4a4d8108
AM
14510+ h_file = au_hf_top(file);
14511+ if (file->f_mode == h_file->f_mode)
14512+ return 0; /* success */
14513+ h_file_tmp = h_file;
14514+ get_file(h_file_tmp);
acd2b654 14515+ au_lcnt_inc(&br->br_nfiles);
5afbbe0d 14516+ au_set_h_fptr(file, btop, NULL);
4a4d8108
AM
14517+ }
14518+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
14519+ /*
14520+ * it can happen
14521+ * file exists on both of rw and ro
5afbbe0d 14522+ * open --> dbtop and fbtop are both 0
86dc4139
AM
14523+ * prepend a branch as rw, "rw" become ro
14524+ * remove rw/file
14525+ * delete the top branch, "rw" becomes rw again
5afbbe0d
AM
14526+ * --> dbtop is 1, fbtop is still 0
14527+ * write --> fbtop is 0 but dbtop is 1
86dc4139 14528+ */
5afbbe0d 14529+ /* AuDebugOn(au_fbtop(file) < btop); */
1308ab2a 14530+
5afbbe0d 14531+ h_file = au_h_open(dentry, btop, vfsub_file_flags(file) & ~O_TRUNC,
392086de 14532+ file, /*force_wr*/0);
4a4d8108 14533+ err = PTR_ERR(h_file);
86dc4139
AM
14534+ if (IS_ERR(h_file)) {
14535+ if (h_file_tmp) {
acd2b654 14536+ /* revert */
5afbbe0d 14537+ au_set_h_fptr(file, btop, h_file_tmp);
86dc4139
AM
14538+ h_file_tmp = NULL;
14539+ }
4a4d8108 14540+ goto out; /* todo: close all? */
86dc4139 14541+ }
4a4d8108
AM
14542+
14543+ err = 0;
5afbbe0d
AM
14544+ au_set_fbtop(file, btop);
14545+ au_set_h_fptr(file, btop, h_file);
4a4d8108
AM
14546+ au_update_figen(file);
14547+ /* todo: necessary? */
14548+ /* file->f_ra = h_file->f_ra; */
14549+
4f0767ce 14550+out:
acd2b654 14551+ if (h_file_tmp) {
4a4d8108 14552+ fput(h_file_tmp);
acd2b654
AM
14553+ au_lcnt_dec(&br->br_nfiles);
14554+ }
4a4d8108 14555+ return err;
1facf9fc 14556+}
14557+
1308ab2a 14558+/* ---------------------------------------------------------------------- */
14559+
4a4d8108
AM
14560+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
14561+ struct dentry *hi_wh)
1facf9fc 14562+{
4a4d8108 14563+ int err;
5afbbe0d 14564+ aufs_bindex_t btop;
4a4d8108
AM
14565+ struct au_dinfo *dinfo;
14566+ struct dentry *h_dentry;
14567+ struct au_hdentry *hdp;
1facf9fc 14568+
2000de60 14569+ dinfo = au_di(file->f_path.dentry);
4a4d8108 14570+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 14571+
5afbbe0d
AM
14572+ btop = dinfo->di_btop;
14573+ dinfo->di_btop = btgt;
14574+ hdp = au_hdentry(dinfo, btgt);
14575+ h_dentry = hdp->hd_dentry;
14576+ hdp->hd_dentry = hi_wh;
4a4d8108 14577+ err = au_reopen_nondir(file);
5afbbe0d
AM
14578+ hdp->hd_dentry = h_dentry;
14579+ dinfo->di_btop = btop;
1facf9fc 14580+
1facf9fc 14581+ return err;
14582+}
14583+
4a4d8108 14584+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 14585+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 14586+{
4a4d8108 14587+ int err;
027c5e7a 14588+ struct inode *inode, *h_inode;
c2b27bf2
AM
14589+ struct dentry *h_dentry, *hi_wh;
14590+ struct au_cp_generic cpg = {
2000de60 14591+ .dentry = file->f_path.dentry,
c2b27bf2
AM
14592+ .bdst = bcpup,
14593+ .bsrc = -1,
14594+ .len = len,
14595+ .pin = pin
14596+ };
1facf9fc 14597+
5afbbe0d 14598+ au_update_dbtop(cpg.dentry);
5527c038 14599+ inode = d_inode(cpg.dentry);
027c5e7a 14600+ h_inode = NULL;
5afbbe0d
AM
14601+ if (au_dbtop(cpg.dentry) <= bcpup
14602+ && au_dbbot(cpg.dentry) >= bcpup) {
c2b27bf2 14603+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
5527c038
JR
14604+ if (h_dentry && d_is_positive(h_dentry))
14605+ h_inode = d_inode(h_dentry);
027c5e7a 14606+ }
4a4d8108 14607+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 14608+ if (!hi_wh && !h_inode)
c2b27bf2 14609+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
14610+ else
14611+ /* already copied-up after unlink */
14612+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 14613+
4a4d8108 14614+ if (!err
38d290e6
JR
14615+ && (inode->i_nlink > 1
14616+ || (inode->i_state & I_LINKABLE))
c2b27bf2
AM
14617+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
14618+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 14619+
dece6358 14620+ return err;
1facf9fc 14621+}
14622+
4a4d8108
AM
14623+/*
14624+ * prepare the @file for writing.
14625+ */
14626+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 14627+{
4a4d8108 14628+ int err;
5afbbe0d 14629+ aufs_bindex_t dbtop;
c1595e42 14630+ struct dentry *parent;
86dc4139 14631+ struct inode *inode;
1facf9fc 14632+ struct super_block *sb;
4a4d8108 14633+ struct file *h_file;
c2b27bf2 14634+ struct au_cp_generic cpg = {
2000de60 14635+ .dentry = file->f_path.dentry,
c2b27bf2
AM
14636+ .bdst = -1,
14637+ .bsrc = -1,
14638+ .len = len,
14639+ .pin = pin,
14640+ .flags = AuCpup_DTIME
14641+ };
1facf9fc 14642+
c2b27bf2 14643+ sb = cpg.dentry->d_sb;
5527c038 14644+ inode = d_inode(cpg.dentry);
5afbbe0d 14645+ cpg.bsrc = au_fbtop(file);
c2b27bf2 14646+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 14647+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
14648+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
14649+ /*flags*/0);
1facf9fc 14650+ goto out;
4a4d8108 14651+ }
1facf9fc 14652+
027c5e7a 14653+ /* need to cpup or reopen */
c2b27bf2 14654+ parent = dget_parent(cpg.dentry);
4a4d8108 14655+ di_write_lock_parent(parent);
c2b27bf2
AM
14656+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
14657+ cpg.bdst = err;
4a4d8108
AM
14658+ if (unlikely(err < 0))
14659+ goto out_dgrade;
14660+ err = 0;
14661+
c2b27bf2
AM
14662+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
14663+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 14664+ if (unlikely(err))
4a4d8108
AM
14665+ goto out_dgrade;
14666+ }
14667+
c2b27bf2 14668+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
14669+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
14670+ if (unlikely(err))
14671+ goto out_dgrade;
14672+
5afbbe0d
AM
14673+ dbtop = au_dbtop(cpg.dentry);
14674+ if (dbtop <= cpg.bdst)
c2b27bf2 14675+ cpg.bsrc = cpg.bdst;
027c5e7a 14676+
5afbbe0d 14677+ if (dbtop <= cpg.bdst /* just reopen */
c2b27bf2 14678+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 14679+ ) {
392086de 14680+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 14681+ if (IS_ERR(h_file))
027c5e7a 14682+ err = PTR_ERR(h_file);
86dc4139 14683+ else {
027c5e7a 14684+ di_downgrade_lock(parent, AuLock_IR);
5afbbe0d 14685+ if (dbtop > cpg.bdst)
c2b27bf2 14686+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
14687+ if (!err)
14688+ err = au_reopen_nondir(file);
c2b27bf2 14689+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 14690+ }
027c5e7a
AM
14691+ } else { /* copyup as wh and reopen */
14692+ /*
14693+ * since writable hfsplus branch is not supported,
14694+ * h_open_pre/post() are unnecessary.
14695+ */
c2b27bf2 14696+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 14697+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 14698+ }
4a4d8108
AM
14699+
14700+ if (!err) {
14701+ au_pin_set_parent_lflag(pin, /*lflag*/0);
14702+ goto out_dput; /* success */
14703+ }
14704+ au_unpin(pin);
14705+ goto out_unlock;
1facf9fc 14706+
4f0767ce 14707+out_dgrade:
4a4d8108 14708+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 14709+out_unlock:
4a4d8108 14710+ di_read_unlock(parent, AuLock_IR);
4f0767ce 14711+out_dput:
4a4d8108 14712+ dput(parent);
4f0767ce 14713+out:
1facf9fc 14714+ return err;
14715+}
14716+
4a4d8108
AM
14717+/* ---------------------------------------------------------------------- */
14718+
14719+int au_do_flush(struct file *file, fl_owner_t id,
14720+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 14721+{
4a4d8108 14722+ int err;
1facf9fc 14723+ struct super_block *sb;
4a4d8108 14724+ struct inode *inode;
1facf9fc 14725+
c06a8ce3
AM
14726+ inode = file_inode(file);
14727+ sb = inode->i_sb;
4a4d8108
AM
14728+ si_noflush_read_lock(sb);
14729+ fi_read_lock(file);
b752ccd1 14730+ ii_read_lock_child(inode);
1facf9fc 14731+
4a4d8108
AM
14732+ err = flush(file, id);
14733+ au_cpup_attr_timesizes(inode);
1facf9fc 14734+
b752ccd1 14735+ ii_read_unlock(inode);
4a4d8108 14736+ fi_read_unlock(file);
1308ab2a 14737+ si_read_unlock(sb);
dece6358 14738+ return err;
1facf9fc 14739+}
14740+
4a4d8108
AM
14741+/* ---------------------------------------------------------------------- */
14742+
14743+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 14744+{
4a4d8108 14745+ int err;
4a4d8108
AM
14746+ struct au_pin pin;
14747+ struct au_finfo *finfo;
c2b27bf2 14748+ struct dentry *parent, *hi_wh;
4a4d8108 14749+ struct inode *inode;
1facf9fc 14750+ struct super_block *sb;
c2b27bf2 14751+ struct au_cp_generic cpg = {
2000de60 14752+ .dentry = file->f_path.dentry,
c2b27bf2
AM
14753+ .bdst = -1,
14754+ .bsrc = -1,
14755+ .len = -1,
14756+ .pin = &pin,
14757+ .flags = AuCpup_DTIME
14758+ };
1facf9fc 14759+
4a4d8108
AM
14760+ FiMustWriteLock(file);
14761+
14762+ err = 0;
14763+ finfo = au_fi(file);
c2b27bf2 14764+ sb = cpg.dentry->d_sb;
5527c038 14765+ inode = d_inode(cpg.dentry);
5afbbe0d 14766+ cpg.bdst = au_ibtop(inode);
c2b27bf2 14767+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 14768+ goto out;
dece6358 14769+
c2b27bf2
AM
14770+ parent = dget_parent(cpg.dentry);
14771+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 14772+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
14773+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
14774+ cpg.bdst = err;
4a4d8108
AM
14775+ di_read_unlock(parent, !AuLock_IR);
14776+ if (unlikely(err < 0))
14777+ goto out_parent;
14778+ err = 0;
1facf9fc 14779+ }
1facf9fc 14780+
4a4d8108 14781+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 14782+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
14783+ if (!S_ISDIR(inode->i_mode)
14784+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 14785+ && au_plink_test(inode)
c2b27bf2 14786+ && !d_unhashed(cpg.dentry)
5afbbe0d 14787+ && cpg.bdst < au_dbtop(cpg.dentry)) {
c2b27bf2 14788+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
14789+ if (unlikely(err))
14790+ goto out_unlock;
14791+
14792+ /* always superio. */
c2b27bf2 14793+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 14794+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 14795+ if (!err) {
c2b27bf2 14796+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
14797+ au_unpin(&pin);
14798+ }
4a4d8108
AM
14799+ } else if (hi_wh) {
14800+ /* already copied-up after unlink */
c2b27bf2 14801+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
14802+ *need_reopen = 0;
14803+ }
1facf9fc 14804+
4f0767ce 14805+out_unlock:
4a4d8108 14806+ di_read_unlock(parent, AuLock_IR);
4f0767ce 14807+out_parent:
4a4d8108 14808+ dput(parent);
4f0767ce 14809+out:
1308ab2a 14810+ return err;
dece6358 14811+}
1facf9fc 14812+
4a4d8108 14813+static void au_do_refresh_dir(struct file *file)
dece6358 14814+{
5afbbe0d 14815+ aufs_bindex_t bindex, bbot, new_bindex, brid;
4a4d8108
AM
14816+ struct au_hfile *p, tmp, *q;
14817+ struct au_finfo *finfo;
1308ab2a 14818+ struct super_block *sb;
4a4d8108 14819+ struct au_fidir *fidir;
1facf9fc 14820+
4a4d8108 14821+ FiMustWriteLock(file);
1facf9fc 14822+
2000de60 14823+ sb = file->f_path.dentry->d_sb;
4a4d8108
AM
14824+ finfo = au_fi(file);
14825+ fidir = finfo->fi_hdir;
14826+ AuDebugOn(!fidir);
14827+ p = fidir->fd_hfile + finfo->fi_btop;
14828+ brid = p->hf_br->br_id;
5afbbe0d
AM
14829+ bbot = fidir->fd_bbot;
14830+ for (bindex = finfo->fi_btop; bindex <= bbot; bindex++, p++) {
4a4d8108
AM
14831+ if (!p->hf_file)
14832+ continue;
1308ab2a 14833+
4a4d8108
AM
14834+ new_bindex = au_br_index(sb, p->hf_br->br_id);
14835+ if (new_bindex == bindex)
14836+ continue;
14837+ if (new_bindex < 0) {
14838+ au_set_h_fptr(file, bindex, NULL);
14839+ continue;
14840+ }
1308ab2a 14841+
4a4d8108
AM
14842+ /* swap two lower inode, and loop again */
14843+ q = fidir->fd_hfile + new_bindex;
14844+ tmp = *q;
14845+ *q = *p;
14846+ *p = tmp;
14847+ if (tmp.hf_file) {
14848+ bindex--;
14849+ p--;
14850+ }
14851+ }
1308ab2a 14852+
4a4d8108 14853+ p = fidir->fd_hfile;
2000de60 14854+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) {
5afbbe0d
AM
14855+ bbot = au_sbbot(sb);
14856+ for (finfo->fi_btop = 0; finfo->fi_btop <= bbot;
4a4d8108
AM
14857+ finfo->fi_btop++, p++)
14858+ if (p->hf_file) {
c06a8ce3 14859+ if (file_inode(p->hf_file))
4a4d8108 14860+ break;
1c60b727 14861+ au_hfput(p, /*execed*/0);
4a4d8108
AM
14862+ }
14863+ } else {
5afbbe0d
AM
14864+ bbot = au_br_index(sb, brid);
14865+ for (finfo->fi_btop = 0; finfo->fi_btop < bbot;
4a4d8108
AM
14866+ finfo->fi_btop++, p++)
14867+ if (p->hf_file)
1c60b727 14868+ au_hfput(p, /*execed*/0);
5afbbe0d 14869+ bbot = au_sbbot(sb);
4a4d8108 14870+ }
1308ab2a 14871+
5afbbe0d
AM
14872+ p = fidir->fd_hfile + bbot;
14873+ for (fidir->fd_bbot = bbot; fidir->fd_bbot >= finfo->fi_btop;
4a4d8108
AM
14874+ fidir->fd_bbot--, p--)
14875+ if (p->hf_file) {
c06a8ce3 14876+ if (file_inode(p->hf_file))
4a4d8108 14877+ break;
1c60b727 14878+ au_hfput(p, /*execed*/0);
4a4d8108
AM
14879+ }
14880+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 14881+}
14882+
4a4d8108
AM
14883+/*
14884+ * after branch manipulating, refresh the file.
14885+ */
14886+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 14887+{
e2f27e51 14888+ int err, need_reopen, nbr;
5afbbe0d 14889+ aufs_bindex_t bbot, bindex;
4a4d8108 14890+ struct dentry *dentry;
e2f27e51 14891+ struct super_block *sb;
1308ab2a 14892+ struct au_finfo *finfo;
4a4d8108 14893+ struct au_hfile *hfile;
1facf9fc 14894+
2000de60 14895+ dentry = file->f_path.dentry;
e2f27e51
AM
14896+ sb = dentry->d_sb;
14897+ nbr = au_sbbot(sb) + 1;
1308ab2a 14898+ finfo = au_fi(file);
4a4d8108
AM
14899+ if (!finfo->fi_hdir) {
14900+ hfile = &finfo->fi_htop;
14901+ AuDebugOn(!hfile->hf_file);
e2f27e51 14902+ bindex = au_br_index(sb, hfile->hf_br->br_id);
4a4d8108
AM
14903+ AuDebugOn(bindex < 0);
14904+ if (bindex != finfo->fi_btop)
5afbbe0d 14905+ au_set_fbtop(file, bindex);
4a4d8108 14906+ } else {
e2f27e51 14907+ err = au_fidir_realloc(finfo, nbr, /*may_shrink*/0);
4a4d8108
AM
14908+ if (unlikely(err))
14909+ goto out;
14910+ au_do_refresh_dir(file);
14911+ }
1facf9fc 14912+
4a4d8108
AM
14913+ err = 0;
14914+ need_reopen = 1;
14915+ if (!au_test_mmapped(file))
14916+ err = au_file_refresh_by_inode(file, &need_reopen);
e2f27e51
AM
14917+ if (finfo->fi_hdir)
14918+ /* harmless if err */
14919+ au_fidir_realloc(finfo, nbr, /*may_shrink*/1);
027c5e7a 14920+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
14921+ err = reopen(file);
14922+ if (!err) {
14923+ au_update_figen(file);
14924+ goto out; /* success */
14925+ }
14926+
14927+ /* error, close all lower files */
14928+ if (finfo->fi_hdir) {
5afbbe0d
AM
14929+ bbot = au_fbbot_dir(file);
14930+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++)
4a4d8108
AM
14931+ au_set_h_fptr(file, bindex, NULL);
14932+ }
1facf9fc 14933+
4f0767ce 14934+out:
1facf9fc 14935+ return err;
14936+}
14937+
4a4d8108
AM
14938+/* common function to regular file and dir */
14939+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
521ced18 14940+ int wlock, unsigned int fi_lsc)
dece6358 14941+{
1308ab2a 14942+ int err;
4a4d8108 14943+ unsigned int sigen, figen;
5afbbe0d 14944+ aufs_bindex_t btop;
4a4d8108
AM
14945+ unsigned char pseudo_link;
14946+ struct dentry *dentry;
14947+ struct inode *inode;
1facf9fc 14948+
4a4d8108 14949+ err = 0;
2000de60 14950+ dentry = file->f_path.dentry;
5527c038 14951+ inode = d_inode(dentry);
4a4d8108 14952+ sigen = au_sigen(dentry->d_sb);
521ced18 14953+ fi_write_lock_nested(file, fi_lsc);
4a4d8108 14954+ figen = au_figen(file);
521ced18
JR
14955+ if (!fi_lsc)
14956+ di_write_lock_child(dentry);
14957+ else
14958+ di_write_lock_child2(dentry);
5afbbe0d
AM
14959+ btop = au_dbtop(dentry);
14960+ pseudo_link = (btop != au_ibtop(inode));
14961+ if (sigen == figen && !pseudo_link && au_fbtop(file) == btop) {
4a4d8108
AM
14962+ if (!wlock) {
14963+ di_downgrade_lock(dentry, AuLock_IR);
14964+ fi_downgrade_lock(file);
14965+ }
14966+ goto out; /* success */
14967+ }
dece6358 14968+
4a4d8108 14969+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 14970+ if (au_digen_test(dentry, sigen)) {
4a4d8108 14971+ err = au_reval_dpath(dentry, sigen);
027c5e7a 14972+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 14973+ }
dece6358 14974+
027c5e7a
AM
14975+ if (!err)
14976+ err = refresh_file(file, reopen);
4a4d8108
AM
14977+ if (!err) {
14978+ if (!wlock) {
14979+ di_downgrade_lock(dentry, AuLock_IR);
14980+ fi_downgrade_lock(file);
14981+ }
14982+ } else {
14983+ di_write_unlock(dentry);
14984+ fi_write_unlock(file);
14985+ }
1facf9fc 14986+
4f0767ce 14987+out:
1308ab2a 14988+ return err;
14989+}
1facf9fc 14990+
4a4d8108
AM
14991+/* ---------------------------------------------------------------------- */
14992+
14993+/* cf. aufs_nopage() */
14994+/* for madvise(2) */
14995+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 14996+{
4a4d8108
AM
14997+ unlock_page(page);
14998+ return 0;
14999+}
1facf9fc 15000+
4a4d8108 15001+/* it will never be called, but necessary to support O_DIRECT */
5afbbe0d 15002+static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
4a4d8108 15003+{ BUG(); return 0; }
1facf9fc 15004+
4a4d8108
AM
15005+/* they will never be called. */
15006+#ifdef CONFIG_AUFS_DEBUG
15007+static int aufs_write_begin(struct file *file, struct address_space *mapping,
15008+ loff_t pos, unsigned len, unsigned flags,
15009+ struct page **pagep, void **fsdata)
15010+{ AuUnsupport(); return 0; }
15011+static int aufs_write_end(struct file *file, struct address_space *mapping,
15012+ loff_t pos, unsigned len, unsigned copied,
15013+ struct page *page, void *fsdata)
15014+{ AuUnsupport(); return 0; }
15015+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
15016+{ AuUnsupport(); return 0; }
1308ab2a 15017+
4a4d8108
AM
15018+static int aufs_set_page_dirty(struct page *page)
15019+{ AuUnsupport(); return 0; }
392086de
AM
15020+static void aufs_invalidatepage(struct page *page, unsigned int offset,
15021+ unsigned int length)
4a4d8108
AM
15022+{ AuUnsupport(); }
15023+static int aufs_releasepage(struct page *page, gfp_t gfp)
15024+{ AuUnsupport(); return 0; }
79b8bda9 15025+#if 0 /* called by memory compaction regardless file */
4a4d8108 15026+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 15027+ struct page *page, enum migrate_mode mode)
4a4d8108 15028+{ AuUnsupport(); return 0; }
79b8bda9 15029+#endif
e2f27e51
AM
15030+static bool aufs_isolate_page(struct page *page, isolate_mode_t mode)
15031+{ AuUnsupport(); return true; }
15032+static void aufs_putback_page(struct page *page)
15033+{ AuUnsupport(); }
4a4d8108
AM
15034+static int aufs_launder_page(struct page *page)
15035+{ AuUnsupport(); return 0; }
15036+static int aufs_is_partially_uptodate(struct page *page,
38d290e6
JR
15037+ unsigned long from,
15038+ unsigned long count)
4a4d8108 15039+{ AuUnsupport(); return 0; }
392086de
AM
15040+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
15041+ bool *writeback)
15042+{ AuUnsupport(); }
4a4d8108
AM
15043+static int aufs_error_remove_page(struct address_space *mapping,
15044+ struct page *page)
15045+{ AuUnsupport(); return 0; }
b4510431
AM
15046+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
15047+ sector_t *span)
15048+{ AuUnsupport(); return 0; }
15049+static void aufs_swap_deactivate(struct file *file)
15050+{ AuUnsupport(); }
4a4d8108
AM
15051+#endif /* CONFIG_AUFS_DEBUG */
15052+
15053+const struct address_space_operations aufs_aop = {
15054+ .readpage = aufs_readpage,
15055+ .direct_IO = aufs_direct_IO,
4a4d8108
AM
15056+#ifdef CONFIG_AUFS_DEBUG
15057+ .writepage = aufs_writepage,
4a4d8108
AM
15058+ /* no writepages, because of writepage */
15059+ .set_page_dirty = aufs_set_page_dirty,
15060+ /* no readpages, because of readpage */
15061+ .write_begin = aufs_write_begin,
15062+ .write_end = aufs_write_end,
15063+ /* no bmap, no block device */
15064+ .invalidatepage = aufs_invalidatepage,
15065+ .releasepage = aufs_releasepage,
79b8bda9
AM
15066+ /* is fallback_migrate_page ok? */
15067+ /* .migratepage = aufs_migratepage, */
e2f27e51
AM
15068+ .isolate_page = aufs_isolate_page,
15069+ .putback_page = aufs_putback_page,
4a4d8108
AM
15070+ .launder_page = aufs_launder_page,
15071+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 15072+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
15073+ .error_remove_page = aufs_error_remove_page,
15074+ .swap_activate = aufs_swap_activate,
15075+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 15076+#endif /* CONFIG_AUFS_DEBUG */
dece6358 15077+};
7f207e10
AM
15078diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
15079--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 15080+++ linux/fs/aufs/file.h 2018-08-12 23:43:05.456791299 +0200
062440b3
AM
15081@@ -0,0 +1,341 @@
15082+/* SPDX-License-Identifier: GPL-2.0 */
4a4d8108 15083+/*
b00004a5 15084+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
15085+ *
15086+ * This program, aufs is free software; you can redistribute it and/or modify
15087+ * it under the terms of the GNU General Public License as published by
15088+ * the Free Software Foundation; either version 2 of the License, or
15089+ * (at your option) any later version.
15090+ *
15091+ * This program is distributed in the hope that it will be useful,
15092+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15093+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15094+ * GNU General Public License for more details.
15095+ *
15096+ * You should have received a copy of the GNU General Public License
523b37e3 15097+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15098+ */
1facf9fc 15099+
4a4d8108
AM
15100+/*
15101+ * file operations
15102+ */
1facf9fc 15103+
4a4d8108
AM
15104+#ifndef __AUFS_FILE_H__
15105+#define __AUFS_FILE_H__
1facf9fc 15106+
4a4d8108 15107+#ifdef __KERNEL__
1facf9fc 15108+
2cbb1c4b 15109+#include <linux/file.h>
4a4d8108 15110+#include <linux/fs.h>
3c1bdaff 15111+#include <linux/mm_types.h>
4a4d8108 15112+#include <linux/poll.h>
4a4d8108 15113+#include "rwsem.h"
1facf9fc 15114+
4a4d8108
AM
15115+struct au_branch;
15116+struct au_hfile {
15117+ struct file *hf_file;
15118+ struct au_branch *hf_br;
15119+};
1facf9fc 15120+
4a4d8108
AM
15121+struct au_vdir;
15122+struct au_fidir {
15123+ aufs_bindex_t fd_bbot;
15124+ aufs_bindex_t fd_nent;
15125+ struct au_vdir *fd_vdir_cache;
15126+ struct au_hfile fd_hfile[];
15127+};
1facf9fc 15128+
4a4d8108 15129+static inline int au_fidir_sz(int nent)
dece6358 15130+{
4f0767ce
JR
15131+ AuDebugOn(nent < 0);
15132+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 15133+}
1facf9fc 15134+
4a4d8108
AM
15135+struct au_finfo {
15136+ atomic_t fi_generation;
dece6358 15137+
4a4d8108
AM
15138+ struct au_rwsem fi_rwsem;
15139+ aufs_bindex_t fi_btop;
15140+
15141+ /* do not union them */
15142+ struct { /* for non-dir */
15143+ struct au_hfile fi_htop;
2cbb1c4b 15144+ atomic_t fi_mmapped;
4a4d8108
AM
15145+ };
15146+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3 15147+
8b6a4947 15148+ struct hlist_bl_node fi_hlist;
1c60b727 15149+ struct file *fi_file; /* very ugly */
4a4d8108 15150+} ____cacheline_aligned_in_smp;
1facf9fc 15151+
4a4d8108 15152+/* ---------------------------------------------------------------------- */
1facf9fc 15153+
4a4d8108
AM
15154+/* file.c */
15155+extern const struct address_space_operations aufs_aop;
15156+unsigned int au_file_roflags(unsigned int flags);
15157+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 15158+ struct file *file, int force_wr);
b912730e 15159+struct au_do_open_args {
8b6a4947 15160+ int aopen;
b912730e
AM
15161+ int (*open)(struct file *file, int flags,
15162+ struct file *h_file);
15163+ struct au_fidir *fidir;
15164+ struct file *h_file;
15165+};
15166+int au_do_open(struct file *file, struct au_do_open_args *args);
4a4d8108
AM
15167+int au_reopen_nondir(struct file *file);
15168+struct au_pin;
15169+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
15170+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
521ced18 15171+ int wlock, unsigned int fi_lsc);
4a4d8108
AM
15172+int au_do_flush(struct file *file, fl_owner_t id,
15173+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 15174+
4a4d8108
AM
15175+/* poll.c */
15176+#ifdef CONFIG_AUFS_POLL
cd7a4cd9 15177+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt);
4a4d8108 15178+#endif
1facf9fc 15179+
4a4d8108
AM
15180+#ifdef CONFIG_AUFS_BR_HFSPLUS
15181+/* hfsplus.c */
392086de
AM
15182+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
15183+ int force_wr);
4a4d8108
AM
15184+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
15185+ struct file *h_file);
15186+#else
c1595e42
JR
15187+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
15188+ aufs_bindex_t bindex, int force_wr)
4a4d8108
AM
15189+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
15190+ struct file *h_file);
15191+#endif
1facf9fc 15192+
4a4d8108
AM
15193+/* f_op.c */
15194+extern const struct file_operations aufs_file_fop;
b912730e 15195+int au_do_open_nondir(struct file *file, int flags, struct file *h_file);
4a4d8108 15196+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
521ced18 15197+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc);
4a4d8108 15198+
4a4d8108 15199+/* finfo.c */
f0c0a007 15200+void au_hfput(struct au_hfile *hf, int execed);
4a4d8108
AM
15201+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
15202+ struct file *h_file);
1facf9fc 15203+
4a4d8108 15204+void au_update_figen(struct file *file);
4a4d8108 15205+struct au_fidir *au_fidir_alloc(struct super_block *sb);
e2f27e51 15206+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink);
1facf9fc 15207+
4a4d8108 15208+void au_fi_init_once(void *_fi);
1c60b727 15209+void au_finfo_fin(struct file *file);
4a4d8108 15210+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 15211+
4a4d8108
AM
15212+/* ioctl.c */
15213+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
15214+#ifdef CONFIG_COMPAT
15215+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
15216+ unsigned long arg);
c2b27bf2
AM
15217+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
15218+ unsigned long arg);
b752ccd1 15219+#endif
1facf9fc 15220+
4a4d8108 15221+/* ---------------------------------------------------------------------- */
1facf9fc 15222+
4a4d8108
AM
15223+static inline struct au_finfo *au_fi(struct file *file)
15224+{
38d290e6 15225+ return file->private_data;
4a4d8108 15226+}
1facf9fc 15227+
4a4d8108 15228+/* ---------------------------------------------------------------------- */
1facf9fc 15229+
8b6a4947
AM
15230+#define fi_read_lock(f) au_rw_read_lock(&au_fi(f)->fi_rwsem)
15231+#define fi_write_lock(f) au_rw_write_lock(&au_fi(f)->fi_rwsem)
15232+#define fi_read_trylock(f) au_rw_read_trylock(&au_fi(f)->fi_rwsem)
15233+#define fi_write_trylock(f) au_rw_write_trylock(&au_fi(f)->fi_rwsem)
4a4d8108 15234+/*
8b6a4947
AM
15235+#define fi_read_trylock_nested(f) \
15236+ au_rw_read_trylock_nested(&au_fi(f)->fi_rwsem)
15237+#define fi_write_trylock_nested(f) \
15238+ au_rw_write_trylock_nested(&au_fi(f)->fi_rwsem)
15239+*/
15240+
15241+#define fi_read_unlock(f) au_rw_read_unlock(&au_fi(f)->fi_rwsem)
15242+#define fi_write_unlock(f) au_rw_write_unlock(&au_fi(f)->fi_rwsem)
15243+#define fi_downgrade_lock(f) au_rw_dgrade_lock(&au_fi(f)->fi_rwsem)
1308ab2a 15244+
521ced18
JR
15245+/* lock subclass for finfo */
15246+enum {
15247+ AuLsc_FI_1,
15248+ AuLsc_FI_2
15249+};
15250+
15251+static inline void fi_read_lock_nested(struct file *f, unsigned int lsc)
15252+{
15253+ au_rw_read_lock_nested(&au_fi(f)->fi_rwsem, lsc);
15254+}
15255+
15256+static inline void fi_write_lock_nested(struct file *f, unsigned int lsc)
15257+{
15258+ au_rw_write_lock_nested(&au_fi(f)->fi_rwsem, lsc);
15259+}
15260+
15261+/*
15262+ * fi_read_lock_1, fi_write_lock_1,
15263+ * fi_read_lock_2, fi_write_lock_2
15264+ */
15265+#define AuReadLockFunc(name) \
15266+static inline void fi_read_lock_##name(struct file *f) \
15267+{ fi_read_lock_nested(f, AuLsc_FI_##name); }
15268+
15269+#define AuWriteLockFunc(name) \
15270+static inline void fi_write_lock_##name(struct file *f) \
15271+{ fi_write_lock_nested(f, AuLsc_FI_##name); }
15272+
15273+#define AuRWLockFuncs(name) \
15274+ AuReadLockFunc(name) \
15275+ AuWriteLockFunc(name)
15276+
15277+AuRWLockFuncs(1);
15278+AuRWLockFuncs(2);
15279+
15280+#undef AuReadLockFunc
15281+#undef AuWriteLockFunc
15282+#undef AuRWLockFuncs
15283+
4a4d8108
AM
15284+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
15285+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
15286+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 15287+
1308ab2a 15288+/* ---------------------------------------------------------------------- */
15289+
4a4d8108 15290+/* todo: hard/soft set? */
5afbbe0d 15291+static inline aufs_bindex_t au_fbtop(struct file *file)
dece6358 15292+{
4a4d8108
AM
15293+ FiMustAnyLock(file);
15294+ return au_fi(file)->fi_btop;
15295+}
dece6358 15296+
5afbbe0d 15297+static inline aufs_bindex_t au_fbbot_dir(struct file *file)
4a4d8108
AM
15298+{
15299+ FiMustAnyLock(file);
15300+ AuDebugOn(!au_fi(file)->fi_hdir);
15301+ return au_fi(file)->fi_hdir->fd_bbot;
15302+}
1facf9fc 15303+
4a4d8108
AM
15304+static inline struct au_vdir *au_fvdir_cache(struct file *file)
15305+{
15306+ FiMustAnyLock(file);
15307+ AuDebugOn(!au_fi(file)->fi_hdir);
15308+ return au_fi(file)->fi_hdir->fd_vdir_cache;
15309+}
1facf9fc 15310+
5afbbe0d 15311+static inline void au_set_fbtop(struct file *file, aufs_bindex_t bindex)
4a4d8108
AM
15312+{
15313+ FiMustWriteLock(file);
15314+ au_fi(file)->fi_btop = bindex;
15315+}
1facf9fc 15316+
5afbbe0d 15317+static inline void au_set_fbbot_dir(struct file *file, aufs_bindex_t bindex)
4a4d8108
AM
15318+{
15319+ FiMustWriteLock(file);
15320+ AuDebugOn(!au_fi(file)->fi_hdir);
15321+ au_fi(file)->fi_hdir->fd_bbot = bindex;
15322+}
1308ab2a 15323+
4a4d8108
AM
15324+static inline void au_set_fvdir_cache(struct file *file,
15325+ struct au_vdir *vdir_cache)
15326+{
15327+ FiMustWriteLock(file);
15328+ AuDebugOn(!au_fi(file)->fi_hdir);
15329+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
15330+}
dece6358 15331+
4a4d8108
AM
15332+static inline struct file *au_hf_top(struct file *file)
15333+{
15334+ FiMustAnyLock(file);
15335+ AuDebugOn(au_fi(file)->fi_hdir);
15336+ return au_fi(file)->fi_htop.hf_file;
15337+}
1facf9fc 15338+
4a4d8108
AM
15339+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
15340+{
15341+ FiMustAnyLock(file);
15342+ AuDebugOn(!au_fi(file)->fi_hdir);
15343+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
15344+}
15345+
4a4d8108
AM
15346+/* todo: memory barrier? */
15347+static inline unsigned int au_figen(struct file *f)
dece6358 15348+{
4a4d8108
AM
15349+ return atomic_read(&au_fi(f)->fi_generation);
15350+}
dece6358 15351+
2cbb1c4b
JR
15352+static inline void au_set_mmapped(struct file *f)
15353+{
15354+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
15355+ return;
0c3ec466 15356+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
15357+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
15358+ ;
15359+}
15360+
15361+static inline void au_unset_mmapped(struct file *f)
15362+{
15363+ atomic_dec(&au_fi(f)->fi_mmapped);
15364+}
15365+
4a4d8108
AM
15366+static inline int au_test_mmapped(struct file *f)
15367+{
2cbb1c4b
JR
15368+ return atomic_read(&au_fi(f)->fi_mmapped);
15369+}
15370+
15371+/* customize vma->vm_file */
15372+
15373+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
15374+ struct file *file)
15375+{
53392da6
AM
15376+ struct file *f;
15377+
15378+ f = vma->vm_file;
2cbb1c4b
JR
15379+ get_file(file);
15380+ vma->vm_file = file;
53392da6 15381+ fput(f);
2cbb1c4b
JR
15382+}
15383+
15384+#ifdef CONFIG_MMU
15385+#define AuDbgVmRegion(file, vma) do {} while (0)
15386+
15387+static inline void au_vm_file_reset(struct vm_area_struct *vma,
15388+ struct file *file)
15389+{
15390+ au_do_vm_file_reset(vma, file);
15391+}
15392+#else
15393+#define AuDbgVmRegion(file, vma) \
15394+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
15395+
15396+static inline void au_vm_file_reset(struct vm_area_struct *vma,
15397+ struct file *file)
15398+{
53392da6
AM
15399+ struct file *f;
15400+
2cbb1c4b 15401+ au_do_vm_file_reset(vma, file);
53392da6 15402+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
15403+ get_file(file);
15404+ vma->vm_region->vm_file = file;
53392da6 15405+ fput(f);
2cbb1c4b
JR
15406+}
15407+#endif /* CONFIG_MMU */
15408+
15409+/* handle vma->vm_prfile */
fb47a38f 15410+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
15411+ struct file *file)
15412+{
2cbb1c4b
JR
15413+ get_file(file);
15414+ vma->vm_prfile = file;
15415+#ifndef CONFIG_MMU
15416+ get_file(file);
15417+ vma->vm_region->vm_prfile = file;
15418+#endif
fb47a38f 15419+}
1308ab2a 15420+
4a4d8108
AM
15421+#endif /* __KERNEL__ */
15422+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
15423diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
15424--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 15425+++ linux/fs/aufs/finfo.c 2018-10-23 12:33:35.596042364 +0200
062440b3 15426@@ -0,0 +1,149 @@
cd7a4cd9 15427+// SPDX-License-Identifier: GPL-2.0
4a4d8108 15428+/*
b00004a5 15429+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
15430+ *
15431+ * This program, aufs is free software; you can redistribute it and/or modify
15432+ * it under the terms of the GNU General Public License as published by
15433+ * the Free Software Foundation; either version 2 of the License, or
15434+ * (at your option) any later version.
15435+ *
15436+ * This program is distributed in the hope that it will be useful,
15437+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15438+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15439+ * GNU General Public License for more details.
15440+ *
15441+ * You should have received a copy of the GNU General Public License
523b37e3 15442+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15443+ */
1308ab2a 15444+
4a4d8108
AM
15445+/*
15446+ * file private data
15447+ */
1facf9fc 15448+
4a4d8108 15449+#include "aufs.h"
1facf9fc 15450+
f0c0a007 15451+void au_hfput(struct au_hfile *hf, int execed)
4a4d8108 15452+{
f0c0a007 15453+ if (execed)
4a4d8108
AM
15454+ allow_write_access(hf->hf_file);
15455+ fput(hf->hf_file);
15456+ hf->hf_file = NULL;
acd2b654 15457+ au_lcnt_dec(&hf->hf_br->br_nfiles);
4a4d8108
AM
15458+ hf->hf_br = NULL;
15459+}
1facf9fc 15460+
4a4d8108
AM
15461+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
15462+{
15463+ struct au_finfo *finfo = au_fi(file);
15464+ struct au_hfile *hf;
15465+ struct au_fidir *fidir;
15466+
15467+ fidir = finfo->fi_hdir;
15468+ if (!fidir) {
15469+ AuDebugOn(finfo->fi_btop != bindex);
15470+ hf = &finfo->fi_htop;
15471+ } else
15472+ hf = fidir->fd_hfile + bindex;
15473+
15474+ if (hf && hf->hf_file)
f0c0a007 15475+ au_hfput(hf, vfsub_file_execed(file));
4a4d8108
AM
15476+ if (val) {
15477+ FiMustWriteLock(file);
b912730e 15478+ AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry));
4a4d8108 15479+ hf->hf_file = val;
2000de60 15480+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex);
1308ab2a 15481+ }
4a4d8108 15482+}
1facf9fc 15483+
4a4d8108
AM
15484+void au_update_figen(struct file *file)
15485+{
2000de60 15486+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry));
4a4d8108 15487+ /* smp_mb(); */ /* atomic_set */
1facf9fc 15488+}
15489+
4a4d8108
AM
15490+/* ---------------------------------------------------------------------- */
15491+
4a4d8108
AM
15492+struct au_fidir *au_fidir_alloc(struct super_block *sb)
15493+{
15494+ struct au_fidir *fidir;
15495+ int nbr;
15496+
5afbbe0d 15497+ nbr = au_sbbot(sb) + 1;
4a4d8108
AM
15498+ if (nbr < 2)
15499+ nbr = 2; /* initial allocate for 2 branches */
15500+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
15501+ if (fidir) {
15502+ fidir->fd_bbot = -1;
15503+ fidir->fd_nent = nbr;
4a4d8108
AM
15504+ }
15505+
15506+ return fidir;
15507+}
15508+
e2f27e51 15509+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink)
4a4d8108
AM
15510+{
15511+ int err;
15512+ struct au_fidir *fidir, *p;
15513+
15514+ AuRwMustWriteLock(&finfo->fi_rwsem);
15515+ fidir = finfo->fi_hdir;
15516+ AuDebugOn(!fidir);
15517+
15518+ err = -ENOMEM;
15519+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
e2f27e51 15520+ GFP_NOFS, may_shrink);
4a4d8108
AM
15521+ if (p) {
15522+ p->fd_nent = nbr;
15523+ finfo->fi_hdir = p;
15524+ err = 0;
15525+ }
1facf9fc 15526+
dece6358 15527+ return err;
1facf9fc 15528+}
1308ab2a 15529+
15530+/* ---------------------------------------------------------------------- */
15531+
1c60b727 15532+void au_finfo_fin(struct file *file)
1308ab2a 15533+{
4a4d8108
AM
15534+ struct au_finfo *finfo;
15535+
acd2b654 15536+ au_lcnt_dec(&au_sbi(file->f_path.dentry->d_sb)->si_nfiles);
7f207e10 15537+
4a4d8108
AM
15538+ finfo = au_fi(file);
15539+ AuDebugOn(finfo->fi_hdir);
15540+ AuRwDestroy(&finfo->fi_rwsem);
1c60b727 15541+ au_cache_free_finfo(finfo);
1308ab2a 15542+}
1308ab2a 15543+
e49829fe 15544+void au_fi_init_once(void *_finfo)
4a4d8108 15545+{
e49829fe 15546+ struct au_finfo *finfo = _finfo;
1308ab2a 15547+
e49829fe 15548+ au_rw_init(&finfo->fi_rwsem);
4a4d8108 15549+}
1308ab2a 15550+
4a4d8108
AM
15551+int au_finfo_init(struct file *file, struct au_fidir *fidir)
15552+{
1716fcea 15553+ int err;
4a4d8108
AM
15554+ struct au_finfo *finfo;
15555+ struct dentry *dentry;
15556+
15557+ err = -ENOMEM;
2000de60 15558+ dentry = file->f_path.dentry;
4a4d8108
AM
15559+ finfo = au_cache_alloc_finfo();
15560+ if (unlikely(!finfo))
15561+ goto out;
15562+
15563+ err = 0;
acd2b654 15564+ au_lcnt_inc(&au_sbi(dentry->d_sb)->si_nfiles);
4a4d8108
AM
15565+ au_rw_write_lock(&finfo->fi_rwsem);
15566+ finfo->fi_btop = -1;
15567+ finfo->fi_hdir = fidir;
15568+ atomic_set(&finfo->fi_generation, au_digen(dentry));
15569+ /* smp_mb(); */ /* atomic_set */
15570+
15571+ file->private_data = finfo;
15572+
15573+out:
15574+ return err;
15575+}
7f207e10
AM
15576diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
15577--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
15578+++ linux/fs/aufs/f_op.c 2018-10-23 12:33:35.596042364 +0200
15579@@ -0,0 +1,819 @@
cd7a4cd9 15580+// SPDX-License-Identifier: GPL-2.0
dece6358 15581+/*
b00004a5 15582+ * Copyright (C) 2005-2018 Junjiro R. Okajima
dece6358
AM
15583+ *
15584+ * This program, aufs is free software; you can redistribute it and/or modify
15585+ * it under the terms of the GNU General Public License as published by
15586+ * the Free Software Foundation; either version 2 of the License, or
15587+ * (at your option) any later version.
15588+ *
15589+ * This program is distributed in the hope that it will be useful,
15590+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15591+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15592+ * GNU General Public License for more details.
15593+ *
15594+ * You should have received a copy of the GNU General Public License
523b37e3 15595+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 15596+ */
1facf9fc 15597+
15598+/*
4a4d8108 15599+ * file and vm operations
1facf9fc 15600+ */
dece6358 15601+
86dc4139 15602+#include <linux/aio.h>
4a4d8108
AM
15603+#include <linux/fs_stack.h>
15604+#include <linux/mman.h>
4a4d8108 15605+#include <linux/security.h>
dece6358
AM
15606+#include "aufs.h"
15607+
b912730e 15608+int au_do_open_nondir(struct file *file, int flags, struct file *h_file)
1facf9fc 15609+{
4a4d8108
AM
15610+ int err;
15611+ aufs_bindex_t bindex;
8cdd5066 15612+ struct dentry *dentry, *h_dentry;
4a4d8108 15613+ struct au_finfo *finfo;
38d290e6 15614+ struct inode *h_inode;
4a4d8108
AM
15615+
15616+ FiMustWriteLock(file);
15617+
523b37e3 15618+ err = 0;
2000de60 15619+ dentry = file->f_path.dentry;
b912730e 15620+ AuDebugOn(IS_ERR_OR_NULL(dentry));
4a4d8108
AM
15621+ finfo = au_fi(file);
15622+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 15623+ atomic_set(&finfo->fi_mmapped, 0);
5afbbe0d 15624+ bindex = au_dbtop(dentry);
8cdd5066
JR
15625+ if (!h_file) {
15626+ h_dentry = au_h_dptr(dentry, bindex);
15627+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
15628+ if (unlikely(err))
15629+ goto out;
b912730e 15630+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
acd2b654
AM
15631+ if (IS_ERR(h_file)) {
15632+ err = PTR_ERR(h_file);
15633+ goto out;
15634+ }
8cdd5066
JR
15635+ } else {
15636+ h_dentry = h_file->f_path.dentry;
15637+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
15638+ if (unlikely(err))
15639+ goto out;
acd2b654 15640+ /* br ref is already inc-ed */
8cdd5066 15641+ }
acd2b654
AM
15642+
15643+ if ((flags & __O_TMPFILE)
15644+ && !(flags & O_EXCL)) {
15645+ h_inode = file_inode(h_file);
15646+ spin_lock(&h_inode->i_lock);
15647+ h_inode->i_state |= I_LINKABLE;
15648+ spin_unlock(&h_inode->i_lock);
4a4d8108 15649+ }
acd2b654
AM
15650+ au_set_fbtop(file, bindex);
15651+ au_set_h_fptr(file, bindex, h_file);
15652+ au_update_figen(file);
15653+ /* todo: necessary? */
15654+ /* file->f_ra = h_file->f_ra; */
027c5e7a 15655+
8cdd5066 15656+out:
4a4d8108 15657+ return err;
1facf9fc 15658+}
15659+
4a4d8108
AM
15660+static int aufs_open_nondir(struct inode *inode __maybe_unused,
15661+ struct file *file)
1facf9fc 15662+{
4a4d8108 15663+ int err;
1308ab2a 15664+ struct super_block *sb;
b912730e
AM
15665+ struct au_do_open_args args = {
15666+ .open = au_do_open_nondir
15667+ };
1facf9fc 15668+
523b37e3
AM
15669+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
15670+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 15671+
2000de60 15672+ sb = file->f_path.dentry->d_sb;
4a4d8108 15673+ si_read_lock(sb, AuLock_FLUSH);
b912730e 15674+ err = au_do_open(file, &args);
4a4d8108
AM
15675+ si_read_unlock(sb);
15676+ return err;
15677+}
1facf9fc 15678+
4a4d8108
AM
15679+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
15680+{
15681+ struct au_finfo *finfo;
15682+ aufs_bindex_t bindex;
1facf9fc 15683+
4a4d8108 15684+ finfo = au_fi(file);
8b6a4947
AM
15685+ au_hbl_del(&finfo->fi_hlist,
15686+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108 15687+ bindex = finfo->fi_btop;
b4510431 15688+ if (bindex >= 0)
4a4d8108 15689+ au_set_h_fptr(file, bindex, NULL);
7f207e10 15690+
1c60b727 15691+ au_finfo_fin(file);
4a4d8108 15692+ return 0;
1facf9fc 15693+}
15694+
4a4d8108
AM
15695+/* ---------------------------------------------------------------------- */
15696+
15697+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 15698+{
1308ab2a 15699+ int err;
4a4d8108
AM
15700+ struct file *h_file;
15701+
15702+ err = 0;
15703+ h_file = au_hf_top(file);
15704+ if (h_file)
15705+ err = vfsub_flush(h_file, id);
15706+ return err;
15707+}
15708+
15709+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
15710+{
15711+ return au_do_flush(file, id, au_do_flush_nondir);
15712+}
15713+
15714+/* ---------------------------------------------------------------------- */
9dbd164d
AM
15715+/*
15716+ * read and write functions acquire [fdi]_rwsem once, but release before
15717+ * mmap_sem. This is because to stop a race condition between mmap(2).
acd2b654 15718+ * Releasing these aufs-rwsem should be safe, no branch-management (by keeping
9dbd164d
AM
15719+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
15720+ * read functions after [fdi]_rwsem are released, but it should be harmless.
15721+ */
4a4d8108 15722+
b912730e 15723+/* Callers should call au_read_post() or fput() in the end */
521ced18 15724+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc)
4a4d8108 15725+{
4a4d8108 15726+ struct file *h_file;
b912730e 15727+ int err;
1facf9fc 15728+
521ced18 15729+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, lsc);
b912730e
AM
15730+ if (!err) {
15731+ di_read_unlock(file->f_path.dentry, AuLock_IR);
15732+ h_file = au_hf_top(file);
15733+ get_file(h_file);
15734+ if (!keep_fi)
15735+ fi_read_unlock(file);
15736+ } else
15737+ h_file = ERR_PTR(err);
15738+
15739+ return h_file;
15740+}
15741+
15742+static void au_read_post(struct inode *inode, struct file *h_file)
15743+{
15744+ /* update without lock, I don't think it a problem */
15745+ fsstack_copy_attr_atime(inode, file_inode(h_file));
15746+ fput(h_file);
15747+}
15748+
15749+struct au_write_pre {
521ced18
JR
15750+ /* input */
15751+ unsigned int lsc;
15752+
15753+ /* output */
b912730e 15754+ blkcnt_t blks;
5afbbe0d 15755+ aufs_bindex_t btop;
b912730e
AM
15756+};
15757+
15758+/*
15759+ * return with iinfo is write-locked
15760+ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the
15761+ * end
15762+ */
15763+static struct file *au_write_pre(struct file *file, int do_ready,
15764+ struct au_write_pre *wpre)
15765+{
15766+ struct file *h_file;
15767+ struct dentry *dentry;
15768+ int err;
521ced18 15769+ unsigned int lsc;
b912730e
AM
15770+ struct au_pin pin;
15771+
521ced18
JR
15772+ lsc = 0;
15773+ if (wpre)
15774+ lsc = wpre->lsc;
15775+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, lsc);
b912730e 15776+ h_file = ERR_PTR(err);
dece6358
AM
15777+ if (unlikely(err))
15778+ goto out;
1facf9fc 15779+
b912730e
AM
15780+ dentry = file->f_path.dentry;
15781+ if (do_ready) {
15782+ err = au_ready_to_write(file, -1, &pin);
15783+ if (unlikely(err)) {
15784+ h_file = ERR_PTR(err);
15785+ di_write_unlock(dentry);
15786+ goto out_fi;
15787+ }
15788+ }
15789+
15790+ di_downgrade_lock(dentry, /*flags*/0);
15791+ if (wpre)
5afbbe0d 15792+ wpre->btop = au_fbtop(file);
4a4d8108 15793+ h_file = au_hf_top(file);
9dbd164d 15794+ get_file(h_file);
b912730e
AM
15795+ if (wpre)
15796+ wpre->blks = file_inode(h_file)->i_blocks;
15797+ if (do_ready)
15798+ au_unpin(&pin);
15799+ di_read_unlock(dentry, /*flags*/0);
15800+
15801+out_fi:
15802+ fi_write_unlock(file);
15803+out:
15804+ return h_file;
15805+}
15806+
15807+static void au_write_post(struct inode *inode, struct file *h_file,
15808+ struct au_write_pre *wpre, ssize_t written)
15809+{
15810+ struct inode *h_inode;
15811+
15812+ au_cpup_attr_timesizes(inode);
5afbbe0d 15813+ AuDebugOn(au_ibtop(inode) != wpre->btop);
b912730e
AM
15814+ h_inode = file_inode(h_file);
15815+ inode->i_mode = h_inode->i_mode;
15816+ ii_write_unlock(inode);
b912730e
AM
15817+ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */
15818+ if (written > 0)
5afbbe0d 15819+ au_fhsm_wrote(inode->i_sb, wpre->btop,
b912730e 15820+ /*force*/h_inode->i_blocks > wpre->blks);
1c60b727 15821+ fput(h_file);
b912730e
AM
15822+}
15823+
15824+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
15825+ loff_t *ppos)
15826+{
15827+ ssize_t err;
15828+ struct inode *inode;
15829+ struct file *h_file;
15830+ struct super_block *sb;
15831+
15832+ inode = file_inode(file);
15833+ sb = inode->i_sb;
15834+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
15835+
521ced18 15836+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
15837+ err = PTR_ERR(h_file);
15838+ if (IS_ERR(h_file))
15839+ goto out;
9dbd164d
AM
15840+
15841+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
15842+ err = vfsub_read_u(h_file, buf, count, ppos);
15843+ /* todo: necessary? */
15844+ /* file->f_ra = h_file->f_ra; */
b912730e 15845+ au_read_post(inode, h_file);
1308ab2a 15846+
4f0767ce 15847+out:
dece6358
AM
15848+ si_read_unlock(sb);
15849+ return err;
15850+}
1facf9fc 15851+
e49829fe
JR
15852+/*
15853+ * todo: very ugly
15854+ * it locks both of i_mutex and si_rwsem for read in safe.
15855+ * if the plink maintenance mode continues forever (that is the problem),
15856+ * may loop forever.
15857+ */
15858+static void au_mtx_and_read_lock(struct inode *inode)
15859+{
15860+ int err;
15861+ struct super_block *sb = inode->i_sb;
15862+
15863+ while (1) {
febd17d6 15864+ inode_lock(inode);
e49829fe
JR
15865+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
15866+ if (!err)
15867+ break;
febd17d6 15868+ inode_unlock(inode);
e49829fe
JR
15869+ si_read_lock(sb, AuLock_NOPLMW);
15870+ si_read_unlock(sb);
15871+ }
15872+}
15873+
4a4d8108
AM
15874+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
15875+ size_t count, loff_t *ppos)
dece6358 15876+{
4a4d8108 15877+ ssize_t err;
b912730e
AM
15878+ struct au_write_pre wpre;
15879+ struct inode *inode;
4a4d8108
AM
15880+ struct file *h_file;
15881+ char __user *buf = (char __user *)ubuf;
1facf9fc 15882+
b912730e 15883+ inode = file_inode(file);
e49829fe 15884+ au_mtx_and_read_lock(inode);
1facf9fc 15885+
521ced18 15886+ wpre.lsc = 0;
b912730e
AM
15887+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15888+ err = PTR_ERR(h_file);
15889+ if (IS_ERR(h_file))
9dbd164d 15890+ goto out;
9dbd164d 15891+
4a4d8108 15892+ err = vfsub_write_u(h_file, buf, count, ppos);
b912730e 15893+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 15894+
4f0767ce 15895+out:
b912730e 15896+ si_read_unlock(inode->i_sb);
febd17d6 15897+ inode_unlock(inode);
dece6358
AM
15898+ return err;
15899+}
1facf9fc 15900+
076b876e
AM
15901+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
15902+ struct iov_iter *iov_iter)
dece6358 15903+{
4a4d8108
AM
15904+ ssize_t err;
15905+ struct file *file;
076b876e 15906+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
1facf9fc 15907+
4a4d8108
AM
15908+ err = security_file_permission(h_file, rw);
15909+ if (unlikely(err))
15910+ goto out;
1facf9fc 15911+
4a4d8108 15912+ err = -ENOSYS;
076b876e 15913+ iter = NULL;
5527c038 15914+ if (rw == MAY_READ)
076b876e 15915+ iter = h_file->f_op->read_iter;
5527c038 15916+ else if (rw == MAY_WRITE)
076b876e 15917+ iter = h_file->f_op->write_iter;
076b876e
AM
15918+
15919+ file = kio->ki_filp;
15920+ kio->ki_filp = h_file;
15921+ if (iter) {
2cbb1c4b 15922+ lockdep_off();
076b876e
AM
15923+ err = iter(kio, iov_iter);
15924+ lockdep_on();
4a4d8108
AM
15925+ } else
15926+ /* currently there is no such fs */
15927+ WARN_ON_ONCE(1);
076b876e 15928+ kio->ki_filp = file;
1facf9fc 15929+
4f0767ce 15930+out:
dece6358
AM
15931+ return err;
15932+}
1facf9fc 15933+
076b876e 15934+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1facf9fc 15935+{
4a4d8108
AM
15936+ ssize_t err;
15937+ struct file *file, *h_file;
b912730e 15938+ struct inode *inode;
dece6358 15939+ struct super_block *sb;
1facf9fc 15940+
4a4d8108 15941+ file = kio->ki_filp;
b912730e
AM
15942+ inode = file_inode(file);
15943+ sb = inode->i_sb;
e49829fe 15944+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 15945+
521ced18 15946+ h_file = au_read_pre(file, /*keep_fi*/1, /*lsc*/0);
b912730e
AM
15947+ err = PTR_ERR(h_file);
15948+ if (IS_ERR(h_file))
15949+ goto out;
9dbd164d 15950+
5afbbe0d
AM
15951+ if (au_test_loopback_kthread()) {
15952+ au_warn_loopback(h_file->f_path.dentry->d_sb);
15953+ if (file->f_mapping != h_file->f_mapping) {
15954+ file->f_mapping = h_file->f_mapping;
15955+ smp_mb(); /* unnecessary? */
15956+ }
15957+ }
15958+ fi_read_unlock(file);
15959+
076b876e 15960+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
4a4d8108
AM
15961+ /* todo: necessary? */
15962+ /* file->f_ra = h_file->f_ra; */
b912730e 15963+ au_read_post(inode, h_file);
1facf9fc 15964+
4f0767ce 15965+out:
4a4d8108 15966+ si_read_unlock(sb);
1308ab2a 15967+ return err;
15968+}
1facf9fc 15969+
076b876e 15970+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1308ab2a 15971+{
4a4d8108 15972+ ssize_t err;
b912730e
AM
15973+ struct au_write_pre wpre;
15974+ struct inode *inode;
4a4d8108 15975+ struct file *file, *h_file;
1308ab2a 15976+
4a4d8108 15977+ file = kio->ki_filp;
b912730e 15978+ inode = file_inode(file);
e49829fe
JR
15979+ au_mtx_and_read_lock(inode);
15980+
521ced18 15981+ wpre.lsc = 0;
b912730e
AM
15982+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
15983+ err = PTR_ERR(h_file);
15984+ if (IS_ERR(h_file))
9dbd164d 15985+ goto out;
9dbd164d 15986+
076b876e 15987+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
b912730e 15988+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 15989+
4f0767ce 15990+out:
b912730e 15991+ si_read_unlock(inode->i_sb);
febd17d6 15992+ inode_unlock(inode);
dece6358 15993+ return err;
1facf9fc 15994+}
15995+
4a4d8108
AM
15996+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
15997+ struct pipe_inode_info *pipe, size_t len,
15998+ unsigned int flags)
1facf9fc 15999+{
4a4d8108
AM
16000+ ssize_t err;
16001+ struct file *h_file;
b912730e 16002+ struct inode *inode;
dece6358 16003+ struct super_block *sb;
1facf9fc 16004+
b912730e
AM
16005+ inode = file_inode(file);
16006+ sb = inode->i_sb;
e49829fe 16007+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 16008+
521ced18 16009+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
16010+ err = PTR_ERR(h_file);
16011+ if (IS_ERR(h_file))
dece6358 16012+ goto out;
1facf9fc 16013+
4a4d8108 16014+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
acd2b654 16015+ /* todo: necessary? */
4a4d8108 16016+ /* file->f_ra = h_file->f_ra; */
b912730e 16017+ au_read_post(inode, h_file);
1facf9fc 16018+
4f0767ce 16019+out:
4a4d8108 16020+ si_read_unlock(sb);
dece6358 16021+ return err;
1facf9fc 16022+}
16023+
4a4d8108
AM
16024+static ssize_t
16025+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
16026+ size_t len, unsigned int flags)
1facf9fc 16027+{
4a4d8108 16028+ ssize_t err;
b912730e
AM
16029+ struct au_write_pre wpre;
16030+ struct inode *inode;
076b876e 16031+ struct file *h_file;
1facf9fc 16032+
b912730e 16033+ inode = file_inode(file);
e49829fe 16034+ au_mtx_and_read_lock(inode);
9dbd164d 16035+
521ced18 16036+ wpre.lsc = 0;
b912730e
AM
16037+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
16038+ err = PTR_ERR(h_file);
16039+ if (IS_ERR(h_file))
9dbd164d 16040+ goto out;
9dbd164d 16041+
4a4d8108 16042+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
b912730e 16043+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 16044+
4f0767ce 16045+out:
b912730e 16046+ si_read_unlock(inode->i_sb);
febd17d6 16047+ inode_unlock(inode);
4a4d8108
AM
16048+ return err;
16049+}
1facf9fc 16050+
38d290e6
JR
16051+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
16052+ loff_t len)
16053+{
16054+ long err;
b912730e 16055+ struct au_write_pre wpre;
38d290e6
JR
16056+ struct inode *inode;
16057+ struct file *h_file;
16058+
b912730e 16059+ inode = file_inode(file);
38d290e6
JR
16060+ au_mtx_and_read_lock(inode);
16061+
521ced18 16062+ wpre.lsc = 0;
b912730e
AM
16063+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
16064+ err = PTR_ERR(h_file);
16065+ if (IS_ERR(h_file))
38d290e6 16066+ goto out;
38d290e6
JR
16067+
16068+ lockdep_off();
03673fb0 16069+ err = vfs_fallocate(h_file, mode, offset, len);
38d290e6 16070+ lockdep_on();
b912730e 16071+ au_write_post(inode, h_file, &wpre, /*written*/1);
38d290e6
JR
16072+
16073+out:
b912730e 16074+ si_read_unlock(inode->i_sb);
febd17d6 16075+ inode_unlock(inode);
38d290e6
JR
16076+ return err;
16077+}
16078+
521ced18
JR
16079+static ssize_t aufs_copy_file_range(struct file *src, loff_t src_pos,
16080+ struct file *dst, loff_t dst_pos,
16081+ size_t len, unsigned int flags)
16082+{
16083+ ssize_t err;
16084+ struct au_write_pre wpre;
16085+ enum { SRC, DST };
16086+ struct {
16087+ struct inode *inode;
16088+ struct file *h_file;
16089+ struct super_block *h_sb;
16090+ } a[2];
16091+#define a_src a[SRC]
16092+#define a_dst a[DST]
16093+
16094+ err = -EINVAL;
16095+ a_src.inode = file_inode(src);
16096+ if (unlikely(!S_ISREG(a_src.inode->i_mode)))
16097+ goto out;
16098+ a_dst.inode = file_inode(dst);
16099+ if (unlikely(!S_ISREG(a_dst.inode->i_mode)))
16100+ goto out;
16101+
16102+ au_mtx_and_read_lock(a_dst.inode);
16103+ /*
16104+ * in order to match the order in di_write_lock2_{child,parent}(),
acd2b654 16105+ * use f_path.dentry for this comparison.
521ced18
JR
16106+ */
16107+ if (src->f_path.dentry < dst->f_path.dentry) {
16108+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_1);
16109+ err = PTR_ERR(a_src.h_file);
16110+ if (IS_ERR(a_src.h_file))
16111+ goto out_si;
16112+
16113+ wpre.lsc = AuLsc_FI_2;
16114+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre);
16115+ err = PTR_ERR(a_dst.h_file);
16116+ if (IS_ERR(a_dst.h_file)) {
16117+ au_read_post(a_src.inode, a_src.h_file);
16118+ goto out_si;
16119+ }
16120+ } else {
16121+ wpre.lsc = AuLsc_FI_1;
16122+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre);
16123+ err = PTR_ERR(a_dst.h_file);
16124+ if (IS_ERR(a_dst.h_file))
16125+ goto out_si;
16126+
16127+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_2);
16128+ err = PTR_ERR(a_src.h_file);
16129+ if (IS_ERR(a_src.h_file)) {
16130+ au_write_post(a_dst.inode, a_dst.h_file, &wpre,
16131+ /*written*/0);
16132+ goto out_si;
16133+ }
16134+ }
16135+
16136+ err = -EXDEV;
16137+ a_src.h_sb = file_inode(a_src.h_file)->i_sb;
16138+ a_dst.h_sb = file_inode(a_dst.h_file)->i_sb;
16139+ if (unlikely(a_src.h_sb != a_dst.h_sb)) {
16140+ AuDbgFile(src);
16141+ AuDbgFile(dst);
16142+ goto out_file;
16143+ }
16144+
16145+ err = vfsub_copy_file_range(a_src.h_file, src_pos, a_dst.h_file,
16146+ dst_pos, len, flags);
16147+
16148+out_file:
16149+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, err);
16150+ fi_read_unlock(src);
16151+ au_read_post(a_src.inode, a_src.h_file);
16152+out_si:
16153+ si_read_unlock(a_dst.inode->i_sb);
16154+ inode_unlock(a_dst.inode);
16155+out:
16156+ return err;
16157+#undef a_src
16158+#undef a_dst
16159+}
16160+
4a4d8108
AM
16161+/* ---------------------------------------------------------------------- */
16162+
9dbd164d
AM
16163+/*
16164+ * The locking order around current->mmap_sem.
16165+ * - in most and regular cases
16166+ * file I/O syscall -- aufs_read() or something
16167+ * -- si_rwsem for read -- mmap_sem
16168+ * (Note that [fdi]i_rwsem are released before mmap_sem).
16169+ * - in mmap case
16170+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
acd2b654
AM
16171+ * This AB-BA order is definitely bad, but is not a problem since "si_rwsem for
16172+ * read" allows multiple processes to acquire it and [fdi]i_rwsem are not held
16173+ * in file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
9dbd164d
AM
16174+ * It means that when aufs acquires si_rwsem for write, the process should never
16175+ * acquire mmap_sem.
16176+ *
392086de 16177+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
16178+ * problem either since any directory is not able to be mmap-ed.
16179+ * The similar scenario is applied to aufs_readlink() too.
16180+ */
16181+
38d290e6 16182+#if 0 /* stop calling security_file_mmap() */
2dfbb274
AM
16183+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
16184+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
16185+
16186+static unsigned long au_arch_prot_conv(unsigned long flags)
16187+{
16188+ /* currently ppc64 only */
16189+#ifdef CONFIG_PPC64
16190+ /* cf. linux/arch/powerpc/include/asm/mman.h */
16191+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
16192+ return AuConv_VM_PROT(flags, SAO);
16193+#else
16194+ AuDebugOn(arch_calc_vm_prot_bits(-1));
16195+ return 0;
16196+#endif
16197+}
16198+
16199+static unsigned long au_prot_conv(unsigned long flags)
16200+{
16201+ return AuConv_VM_PROT(flags, READ)
16202+ | AuConv_VM_PROT(flags, WRITE)
16203+ | AuConv_VM_PROT(flags, EXEC)
16204+ | au_arch_prot_conv(flags);
16205+}
16206+
16207+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
16208+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
16209+
16210+static unsigned long au_flag_conv(unsigned long flags)
16211+{
16212+ return AuConv_VM_MAP(flags, GROWSDOWN)
16213+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
16214+ | AuConv_VM_MAP(flags, LOCKED);
16215+}
38d290e6 16216+#endif
2dfbb274 16217+
9dbd164d 16218+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 16219+{
4a4d8108 16220+ int err;
4a4d8108 16221+ const unsigned char wlock
9dbd164d 16222+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108 16223+ struct super_block *sb;
9dbd164d 16224+ struct file *h_file;
b912730e 16225+ struct inode *inode;
9dbd164d
AM
16226+
16227+ AuDbgVmRegion(file, vma);
1308ab2a 16228+
b912730e
AM
16229+ inode = file_inode(file);
16230+ sb = inode->i_sb;
9dbd164d 16231+ lockdep_off();
e49829fe 16232+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108 16233+
b912730e 16234+ h_file = au_write_pre(file, wlock, /*wpre*/NULL);
9dbd164d 16235+ lockdep_on();
b912730e
AM
16236+ err = PTR_ERR(h_file);
16237+ if (IS_ERR(h_file))
16238+ goto out;
1308ab2a 16239+
b912730e
AM
16240+ err = 0;
16241+ au_set_mmapped(file);
9dbd164d 16242+ au_vm_file_reset(vma, h_file);
38d290e6
JR
16243+ /*
16244+ * we cannot call security_mmap_file() here since it may acquire
16245+ * mmap_sem or i_mutex.
16246+ *
16247+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
16248+ * au_flag_conv(vma->vm_flags));
16249+ */
9dbd164d 16250+ if (!err)
521ced18 16251+ err = call_mmap(h_file, vma);
b912730e
AM
16252+ if (!err) {
16253+ au_vm_prfile_set(vma, file);
16254+ fsstack_copy_attr_atime(inode, file_inode(h_file));
16255+ goto out_fput; /* success */
16256+ }
2cbb1c4b
JR
16257+ au_unset_mmapped(file);
16258+ au_vm_file_reset(vma, file);
b912730e 16259+
2cbb1c4b 16260+out_fput:
9dbd164d 16261+ lockdep_off();
b912730e
AM
16262+ ii_write_unlock(inode);
16263+ lockdep_on();
16264+ fput(h_file);
4f0767ce 16265+out:
b912730e 16266+ lockdep_off();
9dbd164d
AM
16267+ si_read_unlock(sb);
16268+ lockdep_on();
16269+ AuTraceErr(err);
4a4d8108
AM
16270+ return err;
16271+}
16272+
16273+/* ---------------------------------------------------------------------- */
16274+
1e00d052
AM
16275+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
16276+ int datasync)
4a4d8108
AM
16277+{
16278+ int err;
b912730e 16279+ struct au_write_pre wpre;
4a4d8108
AM
16280+ struct inode *inode;
16281+ struct file *h_file;
4a4d8108
AM
16282+
16283+ err = 0; /* -EBADF; */ /* posix? */
16284+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
b912730e 16285+ goto out;
4a4d8108 16286+
b912730e
AM
16287+ inode = file_inode(file);
16288+ au_mtx_and_read_lock(inode);
16289+
521ced18 16290+ wpre.lsc = 0;
b912730e
AM
16291+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
16292+ err = PTR_ERR(h_file);
16293+ if (IS_ERR(h_file))
4a4d8108 16294+ goto out_unlock;
4a4d8108 16295+
53392da6 16296+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
b912730e 16297+ au_write_post(inode, h_file, &wpre, /*written*/0);
4a4d8108 16298+
4f0767ce 16299+out_unlock:
b912730e 16300+ si_read_unlock(inode->i_sb);
febd17d6 16301+ inode_unlock(inode);
b912730e 16302+out:
4a4d8108 16303+ return err;
dece6358
AM
16304+}
16305+
4a4d8108 16306+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 16307+{
4a4d8108
AM
16308+ int err;
16309+ struct file *h_file;
4a4d8108 16310+ struct super_block *sb;
1308ab2a 16311+
b912730e 16312+ sb = file->f_path.dentry->d_sb;
e49829fe 16313+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 16314+
521ced18 16315+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
16316+ err = PTR_ERR(h_file);
16317+ if (IS_ERR(h_file))
4a4d8108
AM
16318+ goto out;
16319+
523b37e3 16320+ if (h_file->f_op->fasync)
4a4d8108 16321+ err = h_file->f_op->fasync(fd, h_file, flag);
b912730e 16322+ fput(h_file); /* instead of au_read_post() */
1308ab2a 16323+
4f0767ce 16324+out:
4a4d8108 16325+ si_read_unlock(sb);
1308ab2a 16326+ return err;
dece6358 16327+}
4a4d8108 16328+
febd17d6
JR
16329+static int aufs_setfl(struct file *file, unsigned long arg)
16330+{
16331+ int err;
16332+ struct file *h_file;
16333+ struct super_block *sb;
16334+
16335+ sb = file->f_path.dentry->d_sb;
16336+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
16337+
521ced18 16338+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
febd17d6
JR
16339+ err = PTR_ERR(h_file);
16340+ if (IS_ERR(h_file))
16341+ goto out;
16342+
1c60b727
AM
16343+ /* stop calling h_file->fasync */
16344+ arg |= vfsub_file_flags(file) & FASYNC;
febd17d6
JR
16345+ err = setfl(/*unused fd*/-1, h_file, arg);
16346+ fput(h_file); /* instead of au_read_post() */
16347+
16348+out:
16349+ si_read_unlock(sb);
16350+ return err;
16351+}
16352+
4a4d8108
AM
16353+/* ---------------------------------------------------------------------- */
16354+
16355+/* no one supports this operation, currently */
16356+#if 0
16357+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
2000de60 16358+ size_t len, loff_t *pos, int more)
4a4d8108
AM
16359+{
16360+}
16361+#endif
16362+
16363+/* ---------------------------------------------------------------------- */
16364+
16365+const struct file_operations aufs_file_fop = {
16366+ .owner = THIS_MODULE,
2cbb1c4b 16367+
027c5e7a 16368+ .llseek = default_llseek,
4a4d8108
AM
16369+
16370+ .read = aufs_read,
16371+ .write = aufs_write,
076b876e
AM
16372+ .read_iter = aufs_read_iter,
16373+ .write_iter = aufs_write_iter,
16374+
4a4d8108
AM
16375+#ifdef CONFIG_AUFS_POLL
16376+ .poll = aufs_poll,
16377+#endif
16378+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 16379+#ifdef CONFIG_COMPAT
c2b27bf2 16380+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 16381+#endif
4a4d8108
AM
16382+ .mmap = aufs_mmap,
16383+ .open = aufs_open_nondir,
16384+ .flush = aufs_flush_nondir,
16385+ .release = aufs_release_nondir,
16386+ .fsync = aufs_fsync_nondir,
4a4d8108
AM
16387+ .fasync = aufs_fasync,
16388+ /* .sendpage = aufs_sendpage, */
febd17d6 16389+ .setfl = aufs_setfl,
4a4d8108
AM
16390+ .splice_write = aufs_splice_write,
16391+ .splice_read = aufs_splice_read,
16392+#if 0
16393+ .aio_splice_write = aufs_aio_splice_write,
38d290e6 16394+ .aio_splice_read = aufs_aio_splice_read,
4a4d8108 16395+#endif
521ced18
JR
16396+ .fallocate = aufs_fallocate,
16397+ .copy_file_range = aufs_copy_file_range
4a4d8108 16398+};
7f207e10
AM
16399diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
16400--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 16401+++ linux/fs/aufs/fstype.h 2018-08-12 23:43:05.456791299 +0200
062440b3
AM
16402@@ -0,0 +1,401 @@
16403+/* SPDX-License-Identifier: GPL-2.0 */
4a4d8108 16404+/*
b00004a5 16405+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
16406+ *
16407+ * This program, aufs is free software; you can redistribute it and/or modify
16408+ * it under the terms of the GNU General Public License as published by
16409+ * the Free Software Foundation; either version 2 of the License, or
16410+ * (at your option) any later version.
16411+ *
16412+ * This program is distributed in the hope that it will be useful,
16413+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16415+ * GNU General Public License for more details.
16416+ *
16417+ * You should have received a copy of the GNU General Public License
523b37e3 16418+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16419+ */
16420+
16421+/*
16422+ * judging filesystem type
16423+ */
16424+
16425+#ifndef __AUFS_FSTYPE_H__
16426+#define __AUFS_FSTYPE_H__
16427+
16428+#ifdef __KERNEL__
16429+
16430+#include <linux/fs.h>
16431+#include <linux/magic.h>
b912730e 16432+#include <linux/nfs_fs.h>
b95c5147 16433+#include <linux/romfs_fs.h>
4a4d8108
AM
16434+
16435+static inline int au_test_aufs(struct super_block *sb)
16436+{
16437+ return sb->s_magic == AUFS_SUPER_MAGIC;
16438+}
16439+
16440+static inline const char *au_sbtype(struct super_block *sb)
16441+{
16442+ return sb->s_type->name;
16443+}
1308ab2a 16444+
16445+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
16446+{
f0c0a007 16447+#if IS_ENABLED(CONFIG_ISO9660_FS)
2000de60 16448+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
16449+#else
16450+ return 0;
16451+#endif
16452+}
16453+
1308ab2a 16454+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 16455+{
f0c0a007 16456+#if IS_ENABLED(CONFIG_ROMFS_FS)
2000de60 16457+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
16458+#else
16459+ return 0;
16460+#endif
16461+}
16462+
1308ab2a 16463+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 16464+{
f0c0a007 16465+#if IS_ENABLED(CONFIG_CRAMFS)
1308ab2a 16466+ return sb->s_magic == CRAMFS_MAGIC;
16467+#endif
16468+ return 0;
16469+}
16470+
16471+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
16472+{
f0c0a007 16473+#if IS_ENABLED(CONFIG_NFS_FS)
1308ab2a 16474+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
16475+#else
16476+ return 0;
16477+#endif
16478+}
16479+
1308ab2a 16480+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 16481+{
f0c0a007 16482+#if IS_ENABLED(CONFIG_FUSE_FS)
1308ab2a 16483+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
16484+#else
16485+ return 0;
16486+#endif
16487+}
16488+
1308ab2a 16489+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 16490+{
f0c0a007 16491+#if IS_ENABLED(CONFIG_XFS_FS)
1308ab2a 16492+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
16493+#else
16494+ return 0;
16495+#endif
16496+}
16497+
1308ab2a 16498+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 16499+{
1308ab2a 16500+#ifdef CONFIG_TMPFS
16501+ return sb->s_magic == TMPFS_MAGIC;
16502+#else
16503+ return 0;
dece6358 16504+#endif
dece6358
AM
16505+}
16506+
1308ab2a 16507+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 16508+{
f0c0a007 16509+#if IS_ENABLED(CONFIG_ECRYPT_FS)
1308ab2a 16510+ return !strcmp(au_sbtype(sb), "ecryptfs");
16511+#else
16512+ return 0;
16513+#endif
1facf9fc 16514+}
16515+
1308ab2a 16516+static inline int au_test_ramfs(struct super_block *sb)
16517+{
16518+ return sb->s_magic == RAMFS_MAGIC;
16519+}
16520+
16521+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
16522+{
f0c0a007 16523+#if IS_ENABLED(CONFIG_UBIFS_FS)
1308ab2a 16524+ return sb->s_magic == UBIFS_SUPER_MAGIC;
16525+#else
16526+ return 0;
16527+#endif
16528+}
16529+
16530+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
16531+{
16532+#ifdef CONFIG_PROC_FS
16533+ return sb->s_magic == PROC_SUPER_MAGIC;
16534+#else
16535+ return 0;
16536+#endif
16537+}
16538+
16539+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
16540+{
16541+#ifdef CONFIG_SYSFS
16542+ return sb->s_magic == SYSFS_MAGIC;
16543+#else
16544+ return 0;
16545+#endif
16546+}
16547+
16548+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
16549+{
f0c0a007 16550+#if IS_ENABLED(CONFIG_CONFIGFS_FS)
1308ab2a 16551+ return sb->s_magic == CONFIGFS_MAGIC;
16552+#else
16553+ return 0;
16554+#endif
16555+}
16556+
16557+static inline int au_test_minix(struct super_block *sb __maybe_unused)
16558+{
f0c0a007 16559+#if IS_ENABLED(CONFIG_MINIX_FS)
1308ab2a 16560+ return sb->s_magic == MINIX3_SUPER_MAGIC
16561+ || sb->s_magic == MINIX2_SUPER_MAGIC
16562+ || sb->s_magic == MINIX2_SUPER_MAGIC2
16563+ || sb->s_magic == MINIX_SUPER_MAGIC
16564+ || sb->s_magic == MINIX_SUPER_MAGIC2;
16565+#else
16566+ return 0;
16567+#endif
16568+}
16569+
1308ab2a 16570+static inline int au_test_fat(struct super_block *sb __maybe_unused)
16571+{
f0c0a007 16572+#if IS_ENABLED(CONFIG_FAT_FS)
1308ab2a 16573+ return sb->s_magic == MSDOS_SUPER_MAGIC;
16574+#else
16575+ return 0;
16576+#endif
16577+}
16578+
16579+static inline int au_test_msdos(struct super_block *sb)
16580+{
16581+ return au_test_fat(sb);
16582+}
16583+
16584+static inline int au_test_vfat(struct super_block *sb)
16585+{
16586+ return au_test_fat(sb);
16587+}
16588+
16589+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
16590+{
16591+#ifdef CONFIG_SECURITYFS
16592+ return sb->s_magic == SECURITYFS_MAGIC;
16593+#else
16594+ return 0;
16595+#endif
16596+}
16597+
16598+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
16599+{
f0c0a007 16600+#if IS_ENABLED(CONFIG_SQUASHFS)
1308ab2a 16601+ return sb->s_magic == SQUASHFS_MAGIC;
16602+#else
16603+ return 0;
16604+#endif
16605+}
16606+
16607+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
16608+{
f0c0a007 16609+#if IS_ENABLED(CONFIG_BTRFS_FS)
1308ab2a 16610+ return sb->s_magic == BTRFS_SUPER_MAGIC;
16611+#else
16612+ return 0;
16613+#endif
16614+}
16615+
16616+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
16617+{
f0c0a007 16618+#if IS_ENABLED(CONFIG_XENFS)
1308ab2a 16619+ return sb->s_magic == XENFS_SUPER_MAGIC;
16620+#else
16621+ return 0;
16622+#endif
16623+}
16624+
16625+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
16626+{
16627+#ifdef CONFIG_DEBUG_FS
16628+ return sb->s_magic == DEBUGFS_MAGIC;
16629+#else
16630+ return 0;
16631+#endif
16632+}
16633+
16634+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
16635+{
f0c0a007 16636+#if IS_ENABLED(CONFIG_NILFS)
1308ab2a 16637+ return sb->s_magic == NILFS_SUPER_MAGIC;
16638+#else
16639+ return 0;
16640+#endif
16641+}
16642+
4a4d8108
AM
16643+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
16644+{
f0c0a007 16645+#if IS_ENABLED(CONFIG_HFSPLUS_FS)
4a4d8108
AM
16646+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
16647+#else
16648+ return 0;
16649+#endif
16650+}
16651+
1308ab2a 16652+/* ---------------------------------------------------------------------- */
16653+/*
16654+ * they can't be an aufs branch.
16655+ */
16656+static inline int au_test_fs_unsuppoted(struct super_block *sb)
16657+{
16658+ return
16659+#ifndef CONFIG_AUFS_BR_RAMFS
16660+ au_test_ramfs(sb) ||
16661+#endif
16662+ au_test_procfs(sb)
16663+ || au_test_sysfs(sb)
16664+ || au_test_configfs(sb)
16665+ || au_test_debugfs(sb)
16666+ || au_test_securityfs(sb)
16667+ || au_test_xenfs(sb)
16668+ || au_test_ecryptfs(sb)
16669+ /* || !strcmp(au_sbtype(sb), "unionfs") */
16670+ || au_test_aufs(sb); /* will be supported in next version */
16671+}
16672+
1308ab2a 16673+static inline int au_test_fs_remote(struct super_block *sb)
16674+{
16675+ return !au_test_tmpfs(sb)
16676+#ifdef CONFIG_AUFS_BR_RAMFS
16677+ && !au_test_ramfs(sb)
16678+#endif
16679+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
16680+}
16681+
16682+/* ---------------------------------------------------------------------- */
16683+
16684+/*
16685+ * Note: these functions (below) are created after reading ->getattr() in all
16686+ * filesystems under linux/fs. it means we have to do so in every update...
16687+ */
16688+
16689+/*
16690+ * some filesystems require getattr to refresh the inode attributes before
16691+ * referencing.
16692+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
16693+ * and leave the work for d_revalidate()
16694+ */
16695+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
16696+{
16697+ return au_test_nfs(sb)
16698+ || au_test_fuse(sb)
1308ab2a 16699+ /* || au_test_btrfs(sb) */ /* untested */
1308ab2a 16700+ ;
16701+}
16702+
16703+/*
16704+ * filesystems which don't maintain i_size or i_blocks.
16705+ */
16706+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
16707+{
16708+ return au_test_xfs(sb)
4a4d8108
AM
16709+ || au_test_btrfs(sb)
16710+ || au_test_ubifs(sb)
16711+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 16712+ /* || au_test_minix(sb) */ /* untested */
16713+ ;
16714+}
16715+
16716+/*
16717+ * filesystems which don't store the correct value in some of their inode
16718+ * attributes.
16719+ */
16720+static inline int au_test_fs_bad_iattr(struct super_block *sb)
16721+{
16722+ return au_test_fs_bad_iattr_size(sb)
1308ab2a 16723+ || au_test_fat(sb)
16724+ || au_test_msdos(sb)
16725+ || au_test_vfat(sb);
1facf9fc 16726+}
16727+
16728+/* they don't check i_nlink in link(2) */
16729+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
16730+{
16731+ return au_test_tmpfs(sb)
16732+#ifdef CONFIG_AUFS_BR_RAMFS
16733+ || au_test_ramfs(sb)
16734+#endif
4a4d8108 16735+ || au_test_ubifs(sb)
4a4d8108 16736+ || au_test_hfsplus(sb);
1facf9fc 16737+}
16738+
16739+/*
16740+ * filesystems which sets S_NOATIME and S_NOCMTIME.
16741+ */
16742+static inline int au_test_fs_notime(struct super_block *sb)
16743+{
16744+ return au_test_nfs(sb)
16745+ || au_test_fuse(sb)
dece6358 16746+ || au_test_ubifs(sb)
1facf9fc 16747+ ;
16748+}
16749+
1facf9fc 16750+/* temporary support for i#1 in cramfs */
16751+static inline int au_test_fs_unique_ino(struct inode *inode)
16752+{
16753+ if (au_test_cramfs(inode->i_sb))
16754+ return inode->i_ino != 1;
16755+ return 1;
16756+}
16757+
16758+/* ---------------------------------------------------------------------- */
16759+
16760+/*
16761+ * the filesystem where the xino files placed must support i/o after unlink and
16762+ * maintain i_size and i_blocks.
16763+ */
16764+static inline int au_test_fs_bad_xino(struct super_block *sb)
16765+{
16766+ return au_test_fs_remote(sb)
16767+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 16768+ /* don't want unnecessary work for xino */
16769+ || au_test_aufs(sb)
1308ab2a 16770+ || au_test_ecryptfs(sb)
16771+ || au_test_nilfs(sb);
1facf9fc 16772+}
16773+
16774+static inline int au_test_fs_trunc_xino(struct super_block *sb)
16775+{
16776+ return au_test_tmpfs(sb)
16777+ || au_test_ramfs(sb);
16778+}
16779+
16780+/*
16781+ * test if the @sb is real-readonly.
16782+ */
16783+static inline int au_test_fs_rr(struct super_block *sb)
16784+{
16785+ return au_test_squashfs(sb)
16786+ || au_test_iso9660(sb)
16787+ || au_test_cramfs(sb)
16788+ || au_test_romfs(sb);
16789+}
16790+
b912730e
AM
16791+/*
16792+ * test if the @inode is nfs with 'noacl' option
2121bcd9 16793+ * NFS always sets SB_POSIXACL regardless its mount option 'noacl.'
b912730e
AM
16794+ */
16795+static inline int au_test_nfs_noacl(struct inode *inode)
16796+{
16797+ return au_test_nfs(inode->i_sb)
16798+ /* && IS_POSIXACL(inode) */
16799+ && !nfs_server_capable(inode, NFS_CAP_ACLS);
16800+}
16801+
1facf9fc 16802+#endif /* __KERNEL__ */
16803+#endif /* __AUFS_FSTYPE_H__ */
8b6a4947
AM
16804diff -urN /usr/share/empty/fs/aufs/hbl.h linux/fs/aufs/hbl.h
16805--- /usr/share/empty/fs/aufs/hbl.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 16806+++ linux/fs/aufs/hbl.h 2018-08-12 23:43:05.456791299 +0200
062440b3
AM
16807@@ -0,0 +1,65 @@
16808+/* SPDX-License-Identifier: GPL-2.0 */
8b6a4947 16809+/*
b00004a5 16810+ * Copyright (C) 2017-2018 Junjiro R. Okajima
8b6a4947
AM
16811+ *
16812+ * This program, aufs is free software; you can redistribute it and/or modify
16813+ * it under the terms of the GNU General Public License as published by
16814+ * the Free Software Foundation; either version 2 of the License, or
16815+ * (at your option) any later version.
16816+ *
16817+ * This program is distributed in the hope that it will be useful,
16818+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16819+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16820+ * GNU General Public License for more details.
16821+ *
16822+ * You should have received a copy of the GNU General Public License
16823+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16824+ */
16825+
16826+/*
16827+ * helpers for hlist_bl.h
16828+ */
16829+
16830+#ifndef __AUFS_HBL_H__
16831+#define __AUFS_HBL_H__
16832+
16833+#ifdef __KERNEL__
16834+
16835+#include <linux/list_bl.h>
16836+
16837+static inline void au_hbl_add(struct hlist_bl_node *node,
16838+ struct hlist_bl_head *hbl)
16839+{
16840+ hlist_bl_lock(hbl);
16841+ hlist_bl_add_head(node, hbl);
16842+ hlist_bl_unlock(hbl);
16843+}
16844+
16845+static inline void au_hbl_del(struct hlist_bl_node *node,
16846+ struct hlist_bl_head *hbl)
16847+{
16848+ hlist_bl_lock(hbl);
16849+ hlist_bl_del(node);
16850+ hlist_bl_unlock(hbl);
16851+}
16852+
16853+#define au_hbl_for_each(pos, head) \
16854+ for (pos = hlist_bl_first(head); \
16855+ pos; \
16856+ pos = pos->next)
16857+
16858+static inline unsigned long au_hbl_count(struct hlist_bl_head *hbl)
16859+{
16860+ unsigned long cnt;
16861+ struct hlist_bl_node *pos;
16862+
16863+ cnt = 0;
16864+ hlist_bl_lock(hbl);
16865+ au_hbl_for_each(pos, hbl)
16866+ cnt++;
16867+ hlist_bl_unlock(hbl);
16868+ return cnt;
16869+}
16870+
16871+#endif /* __KERNEL__ */
16872+#endif /* __AUFS_HBL_H__ */
7f207e10
AM
16873diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
16874--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
16875+++ linux/fs/aufs/hfsnotify.c 2018-10-23 12:33:35.596042364 +0200
16876@@ -0,0 +1,289 @@
cd7a4cd9 16877+// SPDX-License-Identifier: GPL-2.0
1facf9fc 16878+/*
b00004a5 16879+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 16880+ *
16881+ * This program, aufs is free software; you can redistribute it and/or modify
16882+ * it under the terms of the GNU General Public License as published by
16883+ * the Free Software Foundation; either version 2 of the License, or
16884+ * (at your option) any later version.
dece6358
AM
16885+ *
16886+ * This program is distributed in the hope that it will be useful,
16887+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16888+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16889+ * GNU General Public License for more details.
16890+ *
16891+ * You should have received a copy of the GNU General Public License
523b37e3 16892+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 16893+ */
16894+
16895+/*
4a4d8108 16896+ * fsnotify for the lower directories
1facf9fc 16897+ */
16898+
16899+#include "aufs.h"
16900+
4a4d8108
AM
16901+/* FS_IN_IGNORED is unnecessary */
16902+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
16903+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 16904+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 16905+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 16906+
0c5527e5 16907+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 16908+{
0c5527e5
AM
16909+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
16910+ hn_mark);
5afbbe0d 16911+ /* AuDbg("here\n"); */
1c60b727 16912+ au_cache_free_hnotify(hn);
8b6a4947 16913+ smp_mb__before_atomic(); /* for atomic64_dec */
1716fcea
AM
16914+ if (atomic64_dec_and_test(&au_hfsn_ifree))
16915+ wake_up(&au_hfsn_wq);
4a4d8108 16916+}
1facf9fc 16917+
027c5e7a 16918+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 16919+{
1716fcea 16920+ int err;
027c5e7a
AM
16921+ struct au_hnotify *hn;
16922+ struct super_block *sb;
16923+ struct au_branch *br;
0c5527e5 16924+ struct fsnotify_mark *mark;
027c5e7a 16925+ aufs_bindex_t bindex;
1facf9fc 16926+
027c5e7a
AM
16927+ hn = hinode->hi_notify;
16928+ sb = hn->hn_aufs_inode->i_sb;
16929+ bindex = au_br_index(sb, hinode->hi_id);
16930+ br = au_sbr(sb, bindex);
1716fcea
AM
16931+ AuDebugOn(!br->br_hfsn);
16932+
0c5527e5 16933+ mark = &hn->hn_mark;
ffa93bbd 16934+ fsnotify_init_mark(mark, br->br_hfsn->hfsn_group);
0c5527e5 16935+ mark->mask = AuHfsnMask;
7f207e10
AM
16936+ /*
16937+ * by udba rename or rmdir, aufs assign a new inode to the known
16938+ * h_inode, so specify 1 to allow dups.
16939+ */
c1595e42 16940+ lockdep_off();
acd2b654 16941+ err = fsnotify_add_inode_mark(mark, hinode->hi_inode, /*allow_dups*/1);
c1595e42 16942+ lockdep_on();
1716fcea
AM
16943+
16944+ return err;
1facf9fc 16945+}
16946+
7eafdf33 16947+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 16948+{
0c5527e5 16949+ struct fsnotify_mark *mark;
7eafdf33 16950+ unsigned long long ull;
1716fcea 16951+ struct fsnotify_group *group;
7eafdf33
AM
16952+
16953+ ull = atomic64_inc_return(&au_hfsn_ifree);
16954+ BUG_ON(!ull);
953406b4 16955+
0c5527e5 16956+ mark = &hn->hn_mark;
1716fcea
AM
16957+ spin_lock(&mark->lock);
16958+ group = mark->group;
16959+ fsnotify_get_group(group);
16960+ spin_unlock(&mark->lock);
c1595e42 16961+ lockdep_off();
1716fcea 16962+ fsnotify_destroy_mark(mark, group);
5afbbe0d 16963+ fsnotify_put_mark(mark);
1716fcea 16964+ fsnotify_put_group(group);
c1595e42 16965+ lockdep_on();
7f207e10 16966+
7eafdf33
AM
16967+ /* free hn by myself */
16968+ return 0;
1facf9fc 16969+}
16970+
16971+/* ---------------------------------------------------------------------- */
16972+
4a4d8108 16973+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 16974+{
0c5527e5 16975+ struct fsnotify_mark *mark;
1facf9fc 16976+
0c5527e5
AM
16977+ mark = &hinode->hi_notify->hn_mark;
16978+ spin_lock(&mark->lock);
1facf9fc 16979+ if (do_set) {
0c5527e5
AM
16980+ AuDebugOn(mark->mask & AuHfsnMask);
16981+ mark->mask |= AuHfsnMask;
1facf9fc 16982+ } else {
0c5527e5
AM
16983+ AuDebugOn(!(mark->mask & AuHfsnMask));
16984+ mark->mask &= ~AuHfsnMask;
1facf9fc 16985+ }
0c5527e5 16986+ spin_unlock(&mark->lock);
4a4d8108 16987+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 16988+}
16989+
4a4d8108 16990+/* ---------------------------------------------------------------------- */
1facf9fc 16991+
4a4d8108
AM
16992+/* #define AuDbgHnotify */
16993+#ifdef AuDbgHnotify
16994+static char *au_hfsn_name(u32 mask)
16995+{
16996+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
16997+#define test_ret(flag) \
16998+ do { \
16999+ if (mask & flag) \
17000+ return #flag; \
17001+ } while (0)
4a4d8108
AM
17002+ test_ret(FS_ACCESS);
17003+ test_ret(FS_MODIFY);
17004+ test_ret(FS_ATTRIB);
17005+ test_ret(FS_CLOSE_WRITE);
17006+ test_ret(FS_CLOSE_NOWRITE);
17007+ test_ret(FS_OPEN);
17008+ test_ret(FS_MOVED_FROM);
17009+ test_ret(FS_MOVED_TO);
17010+ test_ret(FS_CREATE);
17011+ test_ret(FS_DELETE);
17012+ test_ret(FS_DELETE_SELF);
17013+ test_ret(FS_MOVE_SELF);
17014+ test_ret(FS_UNMOUNT);
17015+ test_ret(FS_Q_OVERFLOW);
17016+ test_ret(FS_IN_IGNORED);
b912730e 17017+ test_ret(FS_ISDIR);
4a4d8108
AM
17018+ test_ret(FS_IN_ONESHOT);
17019+ test_ret(FS_EVENT_ON_CHILD);
17020+ return "";
17021+#undef test_ret
17022+#else
17023+ return "??";
17024+#endif
1facf9fc 17025+}
4a4d8108 17026+#endif
1facf9fc 17027+
17028+/* ---------------------------------------------------------------------- */
17029+
1716fcea
AM
17030+static void au_hfsn_free_group(struct fsnotify_group *group)
17031+{
17032+ struct au_br_hfsnotify *hfsn = group->private;
17033+
5afbbe0d 17034+ /* AuDbg("here\n"); */
1c60b727 17035+ kfree(hfsn);
1716fcea
AM
17036+}
17037+
4a4d8108 17038+static int au_hfsn_handle_event(struct fsnotify_group *group,
fb47a38f 17039+ struct inode *inode,
a2654f78 17040+ u32 mask, const void *data, int data_type,
ffa93bbd
AM
17041+ const unsigned char *file_name, u32 cookie,
17042+ struct fsnotify_iter_info *iter_info)
1facf9fc 17043+{
17044+ int err;
4a4d8108
AM
17045+ struct au_hnotify *hnotify;
17046+ struct inode *h_dir, *h_inode;
fb47a38f 17047+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
cd7a4cd9 17048+ struct fsnotify_mark *inode_mark;
4a4d8108 17049+
fb47a38f 17050+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 17051+
17052+ err = 0;
0c5527e5 17053+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108 17054+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 17055+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 17056+ goto out;
1facf9fc 17057+
fb47a38f
JR
17058+ h_dir = inode;
17059+ h_inode = NULL;
4a4d8108 17060+#ifdef AuDbgHnotify
392086de 17061+ au_debug_on();
4a4d8108
AM
17062+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
17063+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
17064+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
17065+ h_dir->i_ino, mask, au_hfsn_name(mask),
17066+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
17067+ /* WARN_ON(1); */
1facf9fc 17068+ }
392086de 17069+ au_debug_off();
1facf9fc 17070+#endif
4a4d8108 17071+
cd7a4cd9 17072+ inode_mark = fsnotify_iter_inode_mark(iter_info);
0c5527e5
AM
17073+ AuDebugOn(!inode_mark);
17074+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
17075+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 17076+
4a4d8108
AM
17077+out:
17078+ return err;
17079+}
1facf9fc 17080+
4a4d8108 17081+static struct fsnotify_ops au_hfsn_ops = {
1716fcea 17082+ .handle_event = au_hfsn_handle_event,
ffa93bbd
AM
17083+ .free_group_priv = au_hfsn_free_group,
17084+ .free_mark = au_hfsn_free_mark
4a4d8108
AM
17085+};
17086+
17087+/* ---------------------------------------------------------------------- */
17088+
027c5e7a
AM
17089+static void au_hfsn_fin_br(struct au_branch *br)
17090+{
1716fcea 17091+ struct au_br_hfsnotify *hfsn;
027c5e7a 17092+
1716fcea 17093+ hfsn = br->br_hfsn;
c1595e42
JR
17094+ if (hfsn) {
17095+ lockdep_off();
1716fcea 17096+ fsnotify_put_group(hfsn->hfsn_group);
c1595e42
JR
17097+ lockdep_on();
17098+ }
027c5e7a
AM
17099+}
17100+
1716fcea 17101+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
17102+{
17103+ int err;
1716fcea
AM
17104+ struct fsnotify_group *group;
17105+ struct au_br_hfsnotify *hfsn;
1facf9fc 17106+
4a4d8108 17107+ err = 0;
1716fcea
AM
17108+ br->br_hfsn = NULL;
17109+ if (!au_br_hnotifyable(perm))
027c5e7a 17110+ goto out;
027c5e7a 17111+
1716fcea
AM
17112+ err = -ENOMEM;
17113+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
17114+ if (unlikely(!hfsn))
027c5e7a
AM
17115+ goto out;
17116+
1716fcea
AM
17117+ err = 0;
17118+ group = fsnotify_alloc_group(&au_hfsn_ops);
17119+ if (IS_ERR(group)) {
17120+ err = PTR_ERR(group);
0c5527e5 17121+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 17122+ goto out_hfsn;
4a4d8108 17123+ }
1facf9fc 17124+
1716fcea
AM
17125+ group->private = hfsn;
17126+ hfsn->hfsn_group = group;
17127+ br->br_hfsn = hfsn;
17128+ goto out; /* success */
17129+
17130+out_hfsn:
1c60b727 17131+ kfree(hfsn);
027c5e7a 17132+out:
1716fcea
AM
17133+ return err;
17134+}
17135+
17136+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
17137+{
17138+ int err;
17139+
17140+ err = 0;
17141+ if (!br->br_hfsn)
17142+ err = au_hfsn_init_br(br, perm);
17143+
1facf9fc 17144+ return err;
17145+}
17146+
7eafdf33
AM
17147+/* ---------------------------------------------------------------------- */
17148+
17149+static void au_hfsn_fin(void)
17150+{
17151+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
17152+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
17153+}
17154+
4a4d8108
AM
17155+const struct au_hnotify_op au_hnotify_op = {
17156+ .ctl = au_hfsn_ctl,
17157+ .alloc = au_hfsn_alloc,
17158+ .free = au_hfsn_free,
1facf9fc 17159+
7eafdf33
AM
17160+ .fin = au_hfsn_fin,
17161+
027c5e7a
AM
17162+ .reset_br = au_hfsn_reset_br,
17163+ .fin_br = au_hfsn_fin_br,
17164+ .init_br = au_hfsn_init_br
4a4d8108 17165+};
7f207e10
AM
17166diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
17167--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
17168+++ linux/fs/aufs/hfsplus.c 2018-10-23 12:33:35.596042364 +0200
17169@@ -0,0 +1,60 @@
cd7a4cd9 17170+// SPDX-License-Identifier: GPL-2.0
4a4d8108 17171+/*
b00004a5 17172+ * Copyright (C) 2010-2018 Junjiro R. Okajima
4a4d8108
AM
17173+ *
17174+ * This program, aufs is free software; you can redistribute it and/or modify
17175+ * it under the terms of the GNU General Public License as published by
17176+ * the Free Software Foundation; either version 2 of the License, or
17177+ * (at your option) any later version.
17178+ *
17179+ * This program is distributed in the hope that it will be useful,
17180+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17181+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17182+ * GNU General Public License for more details.
17183+ *
17184+ * You should have received a copy of the GNU General Public License
523b37e3 17185+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 17186+ */
1facf9fc 17187+
4a4d8108 17188+/*
acd2b654 17189+ * special support for filesystems which acquires an inode mutex
4a4d8108
AM
17190+ * at final closing a file, eg, hfsplus.
17191+ *
17192+ * This trick is very simple and stupid, just to open the file before really
acd2b654 17193+ * necessary open to tell hfsplus that this is not the final closing.
4a4d8108
AM
17194+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
17195+ * and au_h_open_post() after releasing it.
17196+ */
1facf9fc 17197+
4a4d8108 17198+#include "aufs.h"
1facf9fc 17199+
392086de
AM
17200+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
17201+ int force_wr)
4a4d8108
AM
17202+{
17203+ struct file *h_file;
17204+ struct dentry *h_dentry;
1facf9fc 17205+
4a4d8108
AM
17206+ h_dentry = au_h_dptr(dentry, bindex);
17207+ AuDebugOn(!h_dentry);
5527c038 17208+ AuDebugOn(d_is_negative(h_dentry));
4a4d8108
AM
17209+
17210+ h_file = NULL;
17211+ if (au_test_hfsplus(h_dentry->d_sb)
7e9cd9fe 17212+ && d_is_reg(h_dentry))
4a4d8108
AM
17213+ h_file = au_h_open(dentry, bindex,
17214+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 17215+ /*file*/NULL, force_wr);
4a4d8108 17216+ return h_file;
1facf9fc 17217+}
17218+
4a4d8108
AM
17219+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
17220+ struct file *h_file)
17221+{
acd2b654
AM
17222+ struct au_branch *br;
17223+
4a4d8108
AM
17224+ if (h_file) {
17225+ fput(h_file);
acd2b654
AM
17226+ br = au_sbr(dentry->d_sb, bindex);
17227+ au_lcnt_dec(&br->br_nfiles);
4a4d8108
AM
17228+ }
17229+}
7f207e10
AM
17230diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
17231--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 17232+++ linux/fs/aufs/hnotify.c 2018-10-23 12:33:35.596042364 +0200
062440b3 17233@@ -0,0 +1,720 @@
cd7a4cd9 17234+// SPDX-License-Identifier: GPL-2.0
e49829fe 17235+/*
b00004a5 17236+ * Copyright (C) 2005-2018 Junjiro R. Okajima
e49829fe
JR
17237+ *
17238+ * This program, aufs is free software; you can redistribute it and/or modify
17239+ * it under the terms of the GNU General Public License as published by
17240+ * the Free Software Foundation; either version 2 of the License, or
17241+ * (at your option) any later version.
17242+ *
17243+ * This program is distributed in the hope that it will be useful,
17244+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17245+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17246+ * GNU General Public License for more details.
17247+ *
17248+ * You should have received a copy of the GNU General Public License
523b37e3 17249+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
17250+ */
17251+
17252+/*
7f207e10 17253+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
17254+ */
17255+
17256+#include "aufs.h"
17257+
027c5e7a 17258+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
17259+{
17260+ int err;
7f207e10 17261+ struct au_hnotify *hn;
1facf9fc 17262+
4a4d8108
AM
17263+ err = -ENOMEM;
17264+ hn = au_cache_alloc_hnotify();
17265+ if (hn) {
17266+ hn->hn_aufs_inode = inode;
027c5e7a
AM
17267+ hinode->hi_notify = hn;
17268+ err = au_hnotify_op.alloc(hinode);
17269+ AuTraceErr(err);
17270+ if (unlikely(err)) {
17271+ hinode->hi_notify = NULL;
1c60b727 17272+ au_cache_free_hnotify(hn);
4a4d8108
AM
17273+ /*
17274+ * The upper dir was removed by udba, but the same named
acd2b654 17275+ * dir left. In this case, aufs assigns a new inode
4a4d8108 17276+ * number and set the monitor again.
acd2b654 17277+ * For the lower dir, the old monitor is still left.
4a4d8108
AM
17278+ */
17279+ if (err == -EEXIST)
17280+ err = 0;
17281+ }
1308ab2a 17282+ }
1308ab2a 17283+
027c5e7a 17284+ AuTraceErr(err);
1308ab2a 17285+ return err;
dece6358 17286+}
1facf9fc 17287+
4a4d8108 17288+void au_hn_free(struct au_hinode *hinode)
dece6358 17289+{
4a4d8108 17290+ struct au_hnotify *hn;
1facf9fc 17291+
4a4d8108
AM
17292+ hn = hinode->hi_notify;
17293+ if (hn) {
4a4d8108 17294+ hinode->hi_notify = NULL;
7eafdf33 17295+ if (au_hnotify_op.free(hinode, hn))
1c60b727 17296+ au_cache_free_hnotify(hn);
4a4d8108
AM
17297+ }
17298+}
dece6358 17299+
4a4d8108 17300+/* ---------------------------------------------------------------------- */
dece6358 17301+
4a4d8108
AM
17302+void au_hn_ctl(struct au_hinode *hinode, int do_set)
17303+{
17304+ if (hinode->hi_notify)
17305+ au_hnotify_op.ctl(hinode, do_set);
17306+}
17307+
17308+void au_hn_reset(struct inode *inode, unsigned int flags)
17309+{
5afbbe0d 17310+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
17311+ struct inode *hi;
17312+ struct dentry *iwhdentry;
1facf9fc 17313+
5afbbe0d
AM
17314+ bbot = au_ibbot(inode);
17315+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
4a4d8108
AM
17316+ hi = au_h_iptr(inode, bindex);
17317+ if (!hi)
17318+ continue;
1308ab2a 17319+
febd17d6 17320+ /* inode_lock_nested(hi, AuLsc_I_CHILD); */
4a4d8108
AM
17321+ iwhdentry = au_hi_wh(inode, bindex);
17322+ if (iwhdentry)
17323+ dget(iwhdentry);
17324+ au_igrab(hi);
17325+ au_set_h_iptr(inode, bindex, NULL, 0);
17326+ au_set_h_iptr(inode, bindex, au_igrab(hi),
17327+ flags & ~AuHi_XINO);
17328+ iput(hi);
17329+ dput(iwhdentry);
febd17d6 17330+ /* inode_unlock(hi); */
1facf9fc 17331+ }
1facf9fc 17332+}
17333+
1308ab2a 17334+/* ---------------------------------------------------------------------- */
1facf9fc 17335+
4a4d8108 17336+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 17337+{
4a4d8108 17338+ int err;
5afbbe0d 17339+ aufs_bindex_t bindex, bbot, bfound, btop;
4a4d8108 17340+ struct inode *h_i;
1facf9fc 17341+
4a4d8108
AM
17342+ err = 0;
17343+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 17344+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
17345+ goto out;
17346+ }
1facf9fc 17347+
4a4d8108 17348+ bfound = -1;
5afbbe0d
AM
17349+ bbot = au_ibbot(inode);
17350+ btop = au_ibtop(inode);
4a4d8108 17351+#if 0 /* reserved for future use */
5afbbe0d 17352+ if (bindex == bbot) {
4a4d8108
AM
17353+ /* keep this ino in rename case */
17354+ goto out;
17355+ }
17356+#endif
5afbbe0d 17357+ for (bindex = btop; bindex <= bbot; bindex++)
4a4d8108
AM
17358+ if (au_h_iptr(inode, bindex) == h_inode) {
17359+ bfound = bindex;
17360+ break;
17361+ }
17362+ if (bfound < 0)
1308ab2a 17363+ goto out;
1facf9fc 17364+
5afbbe0d 17365+ for (bindex = btop; bindex <= bbot; bindex++) {
4a4d8108
AM
17366+ h_i = au_h_iptr(inode, bindex);
17367+ if (!h_i)
17368+ continue;
1facf9fc 17369+
4a4d8108
AM
17370+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
17371+ /* ignore this error */
17372+ /* bad action? */
1facf9fc 17373+ }
1facf9fc 17374+
4a4d8108 17375+ /* children inode number will be broken */
1facf9fc 17376+
4f0767ce 17377+out:
4a4d8108
AM
17378+ AuTraceErr(err);
17379+ return err;
1facf9fc 17380+}
17381+
4a4d8108 17382+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 17383+{
4a4d8108
AM
17384+ int err, i, j, ndentry;
17385+ struct au_dcsub_pages dpages;
17386+ struct au_dpage *dpage;
17387+ struct dentry **dentries;
1facf9fc 17388+
4a4d8108
AM
17389+ err = au_dpages_init(&dpages, GFP_NOFS);
17390+ if (unlikely(err))
17391+ goto out;
17392+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
17393+ if (unlikely(err))
17394+ goto out_dpages;
1facf9fc 17395+
4a4d8108
AM
17396+ for (i = 0; i < dpages.ndpage; i++) {
17397+ dpage = dpages.dpages + i;
17398+ dentries = dpage->dentries;
17399+ ndentry = dpage->ndentry;
17400+ for (j = 0; j < ndentry; j++) {
17401+ struct dentry *d;
17402+
17403+ d = dentries[j];
17404+ if (IS_ROOT(d))
17405+ continue;
17406+
4a4d8108 17407+ au_digen_dec(d);
5527c038 17408+ if (d_really_is_positive(d))
4a4d8108
AM
17409+ /* todo: reset children xino?
17410+ cached children only? */
5527c038 17411+ au_iigen_dec(d_inode(d));
1308ab2a 17412+ }
dece6358 17413+ }
1facf9fc 17414+
4f0767ce 17415+out_dpages:
4a4d8108 17416+ au_dpages_free(&dpages);
dece6358 17417+
027c5e7a 17418+#if 0
4a4d8108
AM
17419+ /* discard children */
17420+ dentry_unhash(dentry);
17421+ dput(dentry);
027c5e7a 17422+#endif
4f0767ce 17423+out:
dece6358
AM
17424+ return err;
17425+}
17426+
1308ab2a 17427+/*
4a4d8108 17428+ * return 0 if processed.
1308ab2a 17429+ */
4a4d8108
AM
17430+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
17431+ const unsigned int isdir)
dece6358 17432+{
1308ab2a 17433+ int err;
4a4d8108
AM
17434+ struct dentry *d;
17435+ struct qstr *dname;
1facf9fc 17436+
4a4d8108
AM
17437+ err = 1;
17438+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 17439+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
17440+ err = 0;
17441+ goto out;
17442+ }
dece6358 17443+
4a4d8108
AM
17444+ if (!isdir) {
17445+ AuDebugOn(!name);
17446+ au_iigen_dec(inode);
027c5e7a 17447+ spin_lock(&inode->i_lock);
c1595e42 17448+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 17449+ spin_lock(&d->d_lock);
4a4d8108
AM
17450+ dname = &d->d_name;
17451+ if (dname->len != nlen
027c5e7a
AM
17452+ && memcmp(dname->name, name, nlen)) {
17453+ spin_unlock(&d->d_lock);
4a4d8108 17454+ continue;
027c5e7a 17455+ }
4a4d8108 17456+ err = 0;
4a4d8108
AM
17457+ au_digen_dec(d);
17458+ spin_unlock(&d->d_lock);
17459+ break;
1facf9fc 17460+ }
027c5e7a 17461+ spin_unlock(&inode->i_lock);
1308ab2a 17462+ } else {
027c5e7a 17463+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
c1595e42 17464+ d = d_find_any_alias(inode);
4a4d8108
AM
17465+ if (!d) {
17466+ au_iigen_dec(inode);
17467+ goto out;
17468+ }
1facf9fc 17469+
027c5e7a 17470+ spin_lock(&d->d_lock);
4a4d8108 17471+ dname = &d->d_name;
027c5e7a
AM
17472+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
17473+ spin_unlock(&d->d_lock);
4a4d8108 17474+ err = hn_gen_tree(d);
027c5e7a
AM
17475+ spin_lock(&d->d_lock);
17476+ }
17477+ spin_unlock(&d->d_lock);
4a4d8108
AM
17478+ dput(d);
17479+ }
1facf9fc 17480+
4f0767ce 17481+out:
4a4d8108 17482+ AuTraceErr(err);
1308ab2a 17483+ return err;
17484+}
dece6358 17485+
4a4d8108 17486+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 17487+{
4a4d8108 17488+ int err;
1facf9fc 17489+
5527c038 17490+ if (IS_ROOT(dentry)) {
0c3ec466 17491+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
17492+ return 0;
17493+ }
1308ab2a 17494+
4a4d8108
AM
17495+ err = 0;
17496+ if (!isdir) {
4a4d8108 17497+ au_digen_dec(dentry);
5527c038
JR
17498+ if (d_really_is_positive(dentry))
17499+ au_iigen_dec(d_inode(dentry));
4a4d8108 17500+ } else {
027c5e7a 17501+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
5527c038 17502+ if (d_really_is_positive(dentry))
4a4d8108
AM
17503+ err = hn_gen_tree(dentry);
17504+ }
17505+
17506+ AuTraceErr(err);
17507+ return err;
1facf9fc 17508+}
17509+
4a4d8108 17510+/* ---------------------------------------------------------------------- */
1facf9fc 17511+
4a4d8108
AM
17512+/* hnotify job flags */
17513+#define AuHnJob_XINO0 1
17514+#define AuHnJob_GEN (1 << 1)
17515+#define AuHnJob_DIRENT (1 << 2)
17516+#define AuHnJob_ISDIR (1 << 3)
17517+#define AuHnJob_TRYXINO0 (1 << 4)
17518+#define AuHnJob_MNTPNT (1 << 5)
17519+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
17520+#define au_fset_hnjob(flags, name) \
17521+ do { (flags) |= AuHnJob_##name; } while (0)
17522+#define au_fclr_hnjob(flags, name) \
17523+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 17524+
4a4d8108
AM
17525+enum {
17526+ AuHn_CHILD,
17527+ AuHn_PARENT,
17528+ AuHnLast
17529+};
1facf9fc 17530+
4a4d8108
AM
17531+struct au_hnotify_args {
17532+ struct inode *h_dir, *dir, *h_child_inode;
17533+ u32 mask;
17534+ unsigned int flags[AuHnLast];
17535+ unsigned int h_child_nlen;
17536+ char h_child_name[];
17537+};
1facf9fc 17538+
4a4d8108
AM
17539+struct hn_job_args {
17540+ unsigned int flags;
17541+ struct inode *inode, *h_inode, *dir, *h_dir;
17542+ struct dentry *dentry;
17543+ char *h_name;
17544+ int h_nlen;
17545+};
1308ab2a 17546+
4a4d8108
AM
17547+static int hn_job(struct hn_job_args *a)
17548+{
17549+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
076b876e 17550+ int e;
1308ab2a 17551+
4a4d8108
AM
17552+ /* reset xino */
17553+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
17554+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 17555+
4a4d8108
AM
17556+ if (au_ftest_hnjob(a->flags, TRYXINO0)
17557+ && a->inode
17558+ && a->h_inode) {
be118d29 17559+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
38d290e6
JR
17560+ if (!a->h_inode->i_nlink
17561+ && !(a->h_inode->i_state & I_LINKABLE))
4a4d8108 17562+ hn_xino(a->inode, a->h_inode); /* ignore this error */
3c1bdaff 17563+ inode_unlock_shared(a->h_inode);
1308ab2a 17564+ }
1facf9fc 17565+
4a4d8108
AM
17566+ /* make the generation obsolete */
17567+ if (au_ftest_hnjob(a->flags, GEN)) {
076b876e 17568+ e = -1;
4a4d8108 17569+ if (a->inode)
076b876e 17570+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
4a4d8108 17571+ isdir);
076b876e 17572+ if (e && a->dentry)
4a4d8108
AM
17573+ hn_gen_by_name(a->dentry, isdir);
17574+ /* ignore this error */
1facf9fc 17575+ }
1facf9fc 17576+
4a4d8108
AM
17577+ /* make dir entries obsolete */
17578+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
17579+ struct au_vdir *vdir;
1facf9fc 17580+
4a4d8108
AM
17581+ vdir = au_ivdir(a->inode);
17582+ if (vdir)
17583+ vdir->vd_jiffy = 0;
17584+ /* IMustLock(a->inode); */
be118d29 17585+ /* inode_inc_iversion(a->inode); */
4a4d8108 17586+ }
1facf9fc 17587+
4a4d8108
AM
17588+ /* can do nothing but warn */
17589+ if (au_ftest_hnjob(a->flags, MNTPNT)
17590+ && a->dentry
17591+ && d_mountpoint(a->dentry))
523b37e3 17592+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 17593+
4a4d8108 17594+ return 0;
1308ab2a 17595+}
1facf9fc 17596+
1308ab2a 17597+/* ---------------------------------------------------------------------- */
1facf9fc 17598+
4a4d8108
AM
17599+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
17600+ struct inode *dir)
1308ab2a 17601+{
4a4d8108
AM
17602+ struct dentry *dentry, *d, *parent;
17603+ struct qstr *dname;
1308ab2a 17604+
c1595e42 17605+ parent = d_find_any_alias(dir);
4a4d8108
AM
17606+ if (!parent)
17607+ return NULL;
1308ab2a 17608+
4a4d8108 17609+ dentry = NULL;
027c5e7a 17610+ spin_lock(&parent->d_lock);
c1595e42 17611+ list_for_each_entry(d, &parent->d_subdirs, d_child) {
523b37e3 17612+ /* AuDbg("%pd\n", d); */
027c5e7a 17613+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
17614+ dname = &d->d_name;
17615+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
17616+ goto cont_unlock;
17617+ if (au_di(d))
17618+ au_digen_dec(d);
17619+ else
17620+ goto cont_unlock;
c1595e42 17621+ if (au_dcount(d) > 0) {
027c5e7a 17622+ dentry = dget_dlock(d);
4a4d8108 17623+ spin_unlock(&d->d_lock);
027c5e7a 17624+ break;
dece6358 17625+ }
1facf9fc 17626+
f6b6e03d 17627+cont_unlock:
027c5e7a 17628+ spin_unlock(&d->d_lock);
1308ab2a 17629+ }
027c5e7a 17630+ spin_unlock(&parent->d_lock);
4a4d8108 17631+ dput(parent);
1facf9fc 17632+
4a4d8108
AM
17633+ if (dentry)
17634+ di_write_lock_child(dentry);
1308ab2a 17635+
4a4d8108
AM
17636+ return dentry;
17637+}
dece6358 17638+
4a4d8108
AM
17639+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
17640+ aufs_bindex_t bindex, ino_t h_ino)
17641+{
17642+ struct inode *inode;
17643+ ino_t ino;
17644+ int err;
17645+
17646+ inode = NULL;
17647+ err = au_xino_read(sb, bindex, h_ino, &ino);
17648+ if (!err && ino)
17649+ inode = ilookup(sb, ino);
17650+ if (!inode)
17651+ goto out;
17652+
17653+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 17654+ pr_warn("wrong root branch\n");
4a4d8108
AM
17655+ iput(inode);
17656+ inode = NULL;
17657+ goto out;
1308ab2a 17658+ }
17659+
4a4d8108 17660+ ii_write_lock_child(inode);
1308ab2a 17661+
4f0767ce 17662+out:
4a4d8108 17663+ return inode;
dece6358
AM
17664+}
17665+
4a4d8108 17666+static void au_hn_bh(void *_args)
1facf9fc 17667+{
4a4d8108
AM
17668+ struct au_hnotify_args *a = _args;
17669+ struct super_block *sb;
5afbbe0d 17670+ aufs_bindex_t bindex, bbot, bfound;
4a4d8108 17671+ unsigned char xino, try_iput;
1facf9fc 17672+ int err;
1308ab2a 17673+ struct inode *inode;
4a4d8108
AM
17674+ ino_t h_ino;
17675+ struct hn_job_args args;
17676+ struct dentry *dentry;
17677+ struct au_sbinfo *sbinfo;
1facf9fc 17678+
4a4d8108
AM
17679+ AuDebugOn(!_args);
17680+ AuDebugOn(!a->h_dir);
17681+ AuDebugOn(!a->dir);
17682+ AuDebugOn(!a->mask);
17683+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
17684+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
17685+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 17686+
4a4d8108
AM
17687+ inode = NULL;
17688+ dentry = NULL;
17689+ /*
17690+ * do not lock a->dir->i_mutex here
17691+ * because of d_revalidate() may cause a deadlock.
17692+ */
17693+ sb = a->dir->i_sb;
17694+ AuDebugOn(!sb);
17695+ sbinfo = au_sbi(sb);
17696+ AuDebugOn(!sbinfo);
7f207e10 17697+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 17698+
8b6a4947
AM
17699+ if (au_opt_test(sbinfo->si_mntflags, DIRREN))
17700+ switch (a->mask & FS_EVENTS_POSS_ON_CHILD) {
17701+ case FS_MOVED_FROM:
17702+ case FS_MOVED_TO:
17703+ AuWarn1("DIRREN with UDBA may not work correctly "
17704+ "for the direct rename(2)\n");
17705+ }
17706+
4a4d8108
AM
17707+ ii_read_lock_parent(a->dir);
17708+ bfound = -1;
5afbbe0d
AM
17709+ bbot = au_ibbot(a->dir);
17710+ for (bindex = au_ibtop(a->dir); bindex <= bbot; bindex++)
4a4d8108
AM
17711+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
17712+ bfound = bindex;
17713+ break;
17714+ }
17715+ ii_read_unlock(a->dir);
17716+ if (unlikely(bfound < 0))
17717+ goto out;
1facf9fc 17718+
4a4d8108
AM
17719+ xino = !!au_opt_test(au_mntflags(sb), XINO);
17720+ h_ino = 0;
17721+ if (a->h_child_inode)
17722+ h_ino = a->h_child_inode->i_ino;
1facf9fc 17723+
4a4d8108
AM
17724+ if (a->h_child_nlen
17725+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
17726+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
17727+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
17728+ a->dir);
17729+ try_iput = 0;
5527c038
JR
17730+ if (dentry && d_really_is_positive(dentry))
17731+ inode = d_inode(dentry);
4a4d8108
AM
17732+ if (xino && !inode && h_ino
17733+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
17734+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
17735+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
17736+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
17737+ try_iput = 1;
f0c0a007 17738+ }
1facf9fc 17739+
4a4d8108
AM
17740+ args.flags = a->flags[AuHn_CHILD];
17741+ args.dentry = dentry;
17742+ args.inode = inode;
17743+ args.h_inode = a->h_child_inode;
17744+ args.dir = a->dir;
17745+ args.h_dir = a->h_dir;
17746+ args.h_name = a->h_child_name;
17747+ args.h_nlen = a->h_child_nlen;
17748+ err = hn_job(&args);
17749+ if (dentry) {
027c5e7a 17750+ if (au_di(dentry))
4a4d8108
AM
17751+ di_write_unlock(dentry);
17752+ dput(dentry);
17753+ }
17754+ if (inode && try_iput) {
17755+ ii_write_unlock(inode);
17756+ iput(inode);
17757+ }
1facf9fc 17758+
4a4d8108
AM
17759+ ii_write_lock_parent(a->dir);
17760+ args.flags = a->flags[AuHn_PARENT];
17761+ args.dentry = NULL;
17762+ args.inode = a->dir;
17763+ args.h_inode = a->h_dir;
17764+ args.dir = NULL;
17765+ args.h_dir = NULL;
17766+ args.h_name = NULL;
17767+ args.h_nlen = 0;
17768+ err = hn_job(&args);
17769+ ii_write_unlock(a->dir);
1facf9fc 17770+
4f0767ce 17771+out:
4a4d8108
AM
17772+ iput(a->h_child_inode);
17773+ iput(a->h_dir);
17774+ iput(a->dir);
027c5e7a
AM
17775+ si_write_unlock(sb);
17776+ au_nwt_done(&sbinfo->si_nowait);
1c60b727 17777+ kfree(a);
dece6358 17778+}
1facf9fc 17779+
4a4d8108
AM
17780+/* ---------------------------------------------------------------------- */
17781+
17782+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
17783+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 17784+{
4a4d8108 17785+ int err, len;
53392da6 17786+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
17787+ unsigned char isdir, isroot, wh;
17788+ struct inode *dir;
17789+ struct au_hnotify_args *args;
17790+ char *p, *h_child_name;
dece6358 17791+
1308ab2a 17792+ err = 0;
4a4d8108
AM
17793+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
17794+ dir = igrab(hnotify->hn_aufs_inode);
17795+ if (!dir)
17796+ goto out;
1facf9fc 17797+
4a4d8108
AM
17798+ isroot = (dir->i_ino == AUFS_ROOT_INO);
17799+ wh = 0;
17800+ h_child_name = (void *)h_child_qstr->name;
17801+ len = h_child_qstr->len;
17802+ if (h_child_name) {
17803+ if (len > AUFS_WH_PFX_LEN
17804+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
17805+ h_child_name += AUFS_WH_PFX_LEN;
17806+ len -= AUFS_WH_PFX_LEN;
17807+ wh = 1;
17808+ }
1facf9fc 17809+ }
dece6358 17810+
4a4d8108
AM
17811+ isdir = 0;
17812+ if (h_child_inode)
17813+ isdir = !!S_ISDIR(h_child_inode->i_mode);
17814+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
17815+ flags[AuHn_CHILD] = 0;
17816+ if (isdir)
17817+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
17818+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
17819+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
17820+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
17821+ case FS_MOVED_FROM:
17822+ case FS_MOVED_TO:
17823+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
17824+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
17825+ /*FALLTHROUGH*/
17826+ case FS_CREATE:
fb47a38f 17827+ AuDebugOn(!h_child_name);
4a4d8108 17828+ break;
1facf9fc 17829+
4a4d8108
AM
17830+ case FS_DELETE:
17831+ /*
17832+ * aufs never be able to get this child inode.
17833+ * revalidation should be in d_revalidate()
17834+ * by checking i_nlink, i_generation or d_unhashed().
17835+ */
17836+ AuDebugOn(!h_child_name);
17837+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
17838+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
17839+ break;
dece6358 17840+
4a4d8108
AM
17841+ default:
17842+ AuDebugOn(1);
17843+ }
1308ab2a 17844+
4a4d8108
AM
17845+ if (wh)
17846+ h_child_inode = NULL;
1308ab2a 17847+
4a4d8108
AM
17848+ err = -ENOMEM;
17849+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 17850+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
17851+ if (unlikely(!args)) {
17852+ AuErr1("no memory\n");
17853+ iput(dir);
17854+ goto out;
17855+ }
17856+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
17857+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
17858+ args->mask = mask;
17859+ args->dir = dir;
17860+ args->h_dir = igrab(h_dir);
17861+ if (h_child_inode)
17862+ h_child_inode = igrab(h_child_inode); /* can be NULL */
17863+ args->h_child_inode = h_child_inode;
17864+ args->h_child_nlen = len;
17865+ if (len) {
17866+ p = (void *)args;
17867+ p += sizeof(*args);
17868+ memcpy(p, h_child_name, len);
17869+ p[len] = 0;
1308ab2a 17870+ }
1308ab2a 17871+
38d290e6 17872+ /* NFS fires the event for silly-renamed one from kworker */
53392da6 17873+ f = 0;
38d290e6
JR
17874+ if (!dir->i_nlink
17875+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
53392da6
AM
17876+ f = AuWkq_NEST;
17877+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
17878+ if (unlikely(err)) {
17879+ pr_err("wkq %d\n", err);
17880+ iput(args->h_child_inode);
17881+ iput(args->h_dir);
17882+ iput(args->dir);
1c60b727 17883+ kfree(args);
1facf9fc 17884+ }
1facf9fc 17885+
4a4d8108 17886+out:
1facf9fc 17887+ return err;
17888+}
17889+
027c5e7a
AM
17890+/* ---------------------------------------------------------------------- */
17891+
17892+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
17893+{
17894+ int err;
17895+
17896+ AuDebugOn(!(udba & AuOptMask_UDBA));
17897+
17898+ err = 0;
17899+ if (au_hnotify_op.reset_br)
17900+ err = au_hnotify_op.reset_br(udba, br, perm);
17901+
17902+ return err;
17903+}
17904+
17905+int au_hnotify_init_br(struct au_branch *br, int perm)
17906+{
17907+ int err;
17908+
17909+ err = 0;
17910+ if (au_hnotify_op.init_br)
17911+ err = au_hnotify_op.init_br(br, perm);
17912+
17913+ return err;
17914+}
17915+
17916+void au_hnotify_fin_br(struct au_branch *br)
17917+{
17918+ if (au_hnotify_op.fin_br)
17919+ au_hnotify_op.fin_br(br);
17920+}
17921+
4a4d8108
AM
17922+static void au_hn_destroy_cache(void)
17923+{
1c60b727
AM
17924+ kmem_cache_destroy(au_cache[AuCache_HNOTIFY]);
17925+ au_cache[AuCache_HNOTIFY] = NULL;
4a4d8108 17926+}
1308ab2a 17927+
4a4d8108 17928+int __init au_hnotify_init(void)
1facf9fc 17929+{
1308ab2a 17930+ int err;
1308ab2a 17931+
4a4d8108 17932+ err = -ENOMEM;
1c60b727
AM
17933+ au_cache[AuCache_HNOTIFY] = AuCache(au_hnotify);
17934+ if (au_cache[AuCache_HNOTIFY]) {
027c5e7a
AM
17935+ err = 0;
17936+ if (au_hnotify_op.init)
17937+ err = au_hnotify_op.init();
4a4d8108
AM
17938+ if (unlikely(err))
17939+ au_hn_destroy_cache();
1308ab2a 17940+ }
1308ab2a 17941+ AuTraceErr(err);
4a4d8108 17942+ return err;
1308ab2a 17943+}
17944+
4a4d8108 17945+void au_hnotify_fin(void)
1308ab2a 17946+{
027c5e7a
AM
17947+ if (au_hnotify_op.fin)
17948+ au_hnotify_op.fin();
f0c0a007 17949+
4a4d8108 17950+ /* cf. au_cache_fin() */
1c60b727 17951+ if (au_cache[AuCache_HNOTIFY])
4a4d8108 17952+ au_hn_destroy_cache();
dece6358 17953+}
7f207e10
AM
17954diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
17955--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 17956+++ linux/fs/aufs/iinfo.c 2018-10-23 12:33:35.599375796 +0200
062440b3 17957@@ -0,0 +1,286 @@
cd7a4cd9 17958+// SPDX-License-Identifier: GPL-2.0
dece6358 17959+/*
b00004a5 17960+ * Copyright (C) 2005-2018 Junjiro R. Okajima
dece6358
AM
17961+ *
17962+ * This program, aufs is free software; you can redistribute it and/or modify
17963+ * it under the terms of the GNU General Public License as published by
17964+ * the Free Software Foundation; either version 2 of the License, or
17965+ * (at your option) any later version.
17966+ *
17967+ * This program is distributed in the hope that it will be useful,
17968+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17969+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17970+ * GNU General Public License for more details.
17971+ *
17972+ * You should have received a copy of the GNU General Public License
523b37e3 17973+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 17974+ */
1facf9fc 17975+
dece6358 17976+/*
4a4d8108 17977+ * inode private data
dece6358 17978+ */
1facf9fc 17979+
1308ab2a 17980+#include "aufs.h"
1facf9fc 17981+
4a4d8108 17982+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 17983+{
4a4d8108 17984+ struct inode *h_inode;
5afbbe0d 17985+ struct au_hinode *hinode;
1facf9fc 17986+
4a4d8108 17987+ IiMustAnyLock(inode);
1facf9fc 17988+
5afbbe0d
AM
17989+ hinode = au_hinode(au_ii(inode), bindex);
17990+ h_inode = hinode->hi_inode;
4a4d8108
AM
17991+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
17992+ return h_inode;
17993+}
1facf9fc 17994+
4a4d8108
AM
17995+/* todo: hard/soft set? */
17996+void au_hiput(struct au_hinode *hinode)
17997+{
17998+ au_hn_free(hinode);
17999+ dput(hinode->hi_whdentry);
18000+ iput(hinode->hi_inode);
18001+}
1facf9fc 18002+
4a4d8108
AM
18003+unsigned int au_hi_flags(struct inode *inode, int isdir)
18004+{
18005+ unsigned int flags;
18006+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 18007+
4a4d8108
AM
18008+ flags = 0;
18009+ if (au_opt_test(mnt_flags, XINO))
18010+ au_fset_hi(flags, XINO);
18011+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
18012+ au_fset_hi(flags, HNOTIFY);
18013+ return flags;
1facf9fc 18014+}
18015+
4a4d8108
AM
18016+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
18017+ struct inode *h_inode, unsigned int flags)
1308ab2a 18018+{
4a4d8108
AM
18019+ struct au_hinode *hinode;
18020+ struct inode *hi;
18021+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 18022+
4a4d8108 18023+ IiMustWriteLock(inode);
dece6358 18024+
5afbbe0d 18025+ hinode = au_hinode(iinfo, bindex);
4a4d8108
AM
18026+ hi = hinode->hi_inode;
18027+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
18028+
18029+ if (hi)
18030+ au_hiput(hinode);
18031+ hinode->hi_inode = h_inode;
18032+ if (h_inode) {
18033+ int err;
18034+ struct super_block *sb = inode->i_sb;
18035+ struct au_branch *br;
18036+
027c5e7a
AM
18037+ AuDebugOn(inode->i_mode
18038+ && (h_inode->i_mode & S_IFMT)
18039+ != (inode->i_mode & S_IFMT));
5afbbe0d 18040+ if (bindex == iinfo->ii_btop)
4a4d8108
AM
18041+ au_cpup_igen(inode, h_inode);
18042+ br = au_sbr(sb, bindex);
18043+ hinode->hi_id = br->br_id;
18044+ if (au_ftest_hi(flags, XINO)) {
18045+ err = au_xino_write(sb, bindex, h_inode->i_ino,
18046+ inode->i_ino);
18047+ if (unlikely(err))
18048+ AuIOErr1("failed au_xino_write() %d\n", err);
18049+ }
18050+
18051+ if (au_ftest_hi(flags, HNOTIFY)
18052+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 18053+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
18054+ if (unlikely(err))
18055+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 18056+ }
18057+ }
4a4d8108 18058+}
dece6358 18059+
4a4d8108
AM
18060+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
18061+ struct dentry *h_wh)
18062+{
18063+ struct au_hinode *hinode;
dece6358 18064+
4a4d8108
AM
18065+ IiMustWriteLock(inode);
18066+
5afbbe0d 18067+ hinode = au_hinode(au_ii(inode), bindex);
4a4d8108
AM
18068+ AuDebugOn(hinode->hi_whdentry);
18069+ hinode->hi_whdentry = h_wh;
1facf9fc 18070+}
18071+
537831f9 18072+void au_update_iigen(struct inode *inode, int half)
1308ab2a 18073+{
537831f9
AM
18074+ struct au_iinfo *iinfo;
18075+ struct au_iigen *iigen;
18076+ unsigned int sigen;
18077+
18078+ sigen = au_sigen(inode->i_sb);
18079+ iinfo = au_ii(inode);
18080+ iigen = &iinfo->ii_generation;
be52b249 18081+ spin_lock(&iigen->ig_spin);
537831f9
AM
18082+ iigen->ig_generation = sigen;
18083+ if (half)
18084+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
18085+ else
18086+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
be52b249 18087+ spin_unlock(&iigen->ig_spin);
4a4d8108 18088+}
1facf9fc 18089+
4a4d8108
AM
18090+/* it may be called at remount time, too */
18091+void au_update_ibrange(struct inode *inode, int do_put_zero)
18092+{
18093+ struct au_iinfo *iinfo;
5afbbe0d 18094+ aufs_bindex_t bindex, bbot;
1facf9fc 18095+
5afbbe0d 18096+ AuDebugOn(au_is_bad_inode(inode));
4a4d8108 18097+ IiMustWriteLock(inode);
1facf9fc 18098+
5afbbe0d
AM
18099+ iinfo = au_ii(inode);
18100+ if (do_put_zero && iinfo->ii_btop >= 0) {
18101+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot;
4a4d8108
AM
18102+ bindex++) {
18103+ struct inode *h_i;
1facf9fc 18104+
5afbbe0d 18105+ h_i = au_hinode(iinfo, bindex)->hi_inode;
38d290e6
JR
18106+ if (h_i
18107+ && !h_i->i_nlink
18108+ && !(h_i->i_state & I_LINKABLE))
027c5e7a
AM
18109+ au_set_h_iptr(inode, bindex, NULL, 0);
18110+ }
4a4d8108
AM
18111+ }
18112+
5afbbe0d
AM
18113+ iinfo->ii_btop = -1;
18114+ iinfo->ii_bbot = -1;
18115+ bbot = au_sbbot(inode->i_sb);
18116+ for (bindex = 0; bindex <= bbot; bindex++)
18117+ if (au_hinode(iinfo, bindex)->hi_inode) {
18118+ iinfo->ii_btop = bindex;
4a4d8108 18119+ break;
027c5e7a 18120+ }
5afbbe0d
AM
18121+ if (iinfo->ii_btop >= 0)
18122+ for (bindex = bbot; bindex >= iinfo->ii_btop; bindex--)
18123+ if (au_hinode(iinfo, bindex)->hi_inode) {
18124+ iinfo->ii_bbot = bindex;
027c5e7a
AM
18125+ break;
18126+ }
5afbbe0d 18127+ AuDebugOn(iinfo->ii_btop > iinfo->ii_bbot);
1308ab2a 18128+}
1facf9fc 18129+
dece6358 18130+/* ---------------------------------------------------------------------- */
1facf9fc 18131+
4a4d8108 18132+void au_icntnr_init_once(void *_c)
dece6358 18133+{
4a4d8108
AM
18134+ struct au_icntnr *c = _c;
18135+ struct au_iinfo *iinfo = &c->iinfo;
1facf9fc 18136+
be52b249 18137+ spin_lock_init(&iinfo->ii_generation.ig_spin);
4a4d8108
AM
18138+ au_rw_init(&iinfo->ii_rwsem);
18139+ inode_init_once(&c->vfs_inode);
18140+}
1facf9fc 18141+
5afbbe0d
AM
18142+void au_hinode_init(struct au_hinode *hinode)
18143+{
18144+ hinode->hi_inode = NULL;
18145+ hinode->hi_id = -1;
18146+ au_hn_init(hinode);
18147+ hinode->hi_whdentry = NULL;
18148+}
18149+
4a4d8108
AM
18150+int au_iinfo_init(struct inode *inode)
18151+{
18152+ struct au_iinfo *iinfo;
18153+ struct super_block *sb;
5afbbe0d 18154+ struct au_hinode *hi;
4a4d8108 18155+ int nbr, i;
1facf9fc 18156+
4a4d8108
AM
18157+ sb = inode->i_sb;
18158+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
5afbbe0d 18159+ nbr = au_sbbot(sb) + 1;
4a4d8108
AM
18160+ if (unlikely(nbr <= 0))
18161+ nbr = 1;
5afbbe0d
AM
18162+ hi = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
18163+ if (hi) {
acd2b654 18164+ au_lcnt_inc(&au_sbi(sb)->si_ninodes);
5afbbe0d
AM
18165+
18166+ iinfo->ii_hinode = hi;
18167+ for (i = 0; i < nbr; i++, hi++)
18168+ au_hinode_init(hi);
1facf9fc 18169+
537831f9 18170+ iinfo->ii_generation.ig_generation = au_sigen(sb);
5afbbe0d
AM
18171+ iinfo->ii_btop = -1;
18172+ iinfo->ii_bbot = -1;
4a4d8108
AM
18173+ iinfo->ii_vdir = NULL;
18174+ return 0;
1308ab2a 18175+ }
4a4d8108
AM
18176+ return -ENOMEM;
18177+}
1facf9fc 18178+
e2f27e51 18179+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink)
4a4d8108 18180+{
5afbbe0d 18181+ int err, i;
4a4d8108 18182+ struct au_hinode *hip;
1facf9fc 18183+
4a4d8108
AM
18184+ AuRwMustWriteLock(&iinfo->ii_rwsem);
18185+
18186+ err = -ENOMEM;
e2f27e51
AM
18187+ hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS,
18188+ may_shrink);
4a4d8108
AM
18189+ if (hip) {
18190+ iinfo->ii_hinode = hip;
5afbbe0d
AM
18191+ i = iinfo->ii_bbot + 1;
18192+ hip += i;
18193+ for (; i < nbr; i++, hip++)
18194+ au_hinode_init(hip);
4a4d8108 18195+ err = 0;
1308ab2a 18196+ }
4a4d8108 18197+
1308ab2a 18198+ return err;
1facf9fc 18199+}
18200+
4a4d8108 18201+void au_iinfo_fin(struct inode *inode)
1facf9fc 18202+{
4a4d8108
AM
18203+ struct au_iinfo *iinfo;
18204+ struct au_hinode *hi;
18205+ struct super_block *sb;
5afbbe0d 18206+ aufs_bindex_t bindex, bbot;
b752ccd1 18207+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 18208+
5afbbe0d 18209+ AuDebugOn(au_is_bad_inode(inode));
1308ab2a 18210+
b752ccd1 18211+ sb = inode->i_sb;
acd2b654 18212+ au_lcnt_dec(&au_sbi(sb)->si_ninodes);
b752ccd1
AM
18213+ if (si_pid_test(sb))
18214+ au_xino_delete_inode(inode, unlinked);
18215+ else {
18216+ /*
18217+ * it is safe to hide the dependency between sbinfo and
18218+ * sb->s_umount.
18219+ */
18220+ lockdep_off();
18221+ si_noflush_read_lock(sb);
18222+ au_xino_delete_inode(inode, unlinked);
18223+ si_read_unlock(sb);
18224+ lockdep_on();
18225+ }
18226+
5afbbe0d 18227+ iinfo = au_ii(inode);
4a4d8108 18228+ if (iinfo->ii_vdir)
1c60b727 18229+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 18230+
5afbbe0d 18231+ bindex = iinfo->ii_btop;
b752ccd1 18232+ if (bindex >= 0) {
5afbbe0d
AM
18233+ hi = au_hinode(iinfo, bindex);
18234+ bbot = iinfo->ii_bbot;
18235+ while (bindex++ <= bbot) {
b752ccd1 18236+ if (hi->hi_inode)
4a4d8108 18237+ au_hiput(hi);
4a4d8108
AM
18238+ hi++;
18239+ }
18240+ }
1c60b727 18241+ kfree(iinfo->ii_hinode);
4a4d8108 18242+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 18243+}
7f207e10
AM
18244diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
18245--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 18246+++ linux/fs/aufs/inode.c 2018-08-12 23:43:05.460124736 +0200
062440b3 18247@@ -0,0 +1,528 @@
cd7a4cd9 18248+// SPDX-License-Identifier: GPL-2.0
4a4d8108 18249+/*
b00004a5 18250+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
18251+ *
18252+ * This program, aufs is free software; you can redistribute it and/or modify
18253+ * it under the terms of the GNU General Public License as published by
18254+ * the Free Software Foundation; either version 2 of the License, or
18255+ * (at your option) any later version.
18256+ *
18257+ * This program is distributed in the hope that it will be useful,
18258+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18259+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18260+ * GNU General Public License for more details.
18261+ *
18262+ * You should have received a copy of the GNU General Public License
523b37e3 18263+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 18264+ */
1facf9fc 18265+
4a4d8108
AM
18266+/*
18267+ * inode functions
18268+ */
1facf9fc 18269+
4a4d8108 18270+#include "aufs.h"
1308ab2a 18271+
4a4d8108
AM
18272+struct inode *au_igrab(struct inode *inode)
18273+{
18274+ if (inode) {
18275+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 18276+ ihold(inode);
1facf9fc 18277+ }
4a4d8108
AM
18278+ return inode;
18279+}
1facf9fc 18280+
4a4d8108
AM
18281+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
18282+{
18283+ au_cpup_attr_all(inode, /*force*/0);
537831f9 18284+ au_update_iigen(inode, /*half*/1);
4a4d8108 18285+ if (do_version)
be118d29 18286+ inode_inc_iversion(inode);
dece6358 18287+}
1facf9fc 18288+
027c5e7a 18289+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 18290+{
e2f27e51 18291+ int err, e, nbr;
027c5e7a 18292+ umode_t type;
4a4d8108 18293+ aufs_bindex_t bindex, new_bindex;
1308ab2a 18294+ struct super_block *sb;
4a4d8108 18295+ struct au_iinfo *iinfo;
027c5e7a 18296+ struct au_hinode *p, *q, tmp;
1facf9fc 18297+
5afbbe0d 18298+ AuDebugOn(au_is_bad_inode(inode));
4a4d8108 18299+ IiMustWriteLock(inode);
1facf9fc 18300+
027c5e7a 18301+ *update = 0;
4a4d8108 18302+ sb = inode->i_sb;
e2f27e51 18303+ nbr = au_sbbot(sb) + 1;
027c5e7a 18304+ type = inode->i_mode & S_IFMT;
4a4d8108 18305+ iinfo = au_ii(inode);
e2f27e51 18306+ err = au_hinode_realloc(iinfo, nbr, /*may_shrink*/0);
4a4d8108 18307+ if (unlikely(err))
1308ab2a 18308+ goto out;
1facf9fc 18309+
5afbbe0d
AM
18310+ AuDebugOn(iinfo->ii_btop < 0);
18311+ p = au_hinode(iinfo, iinfo->ii_btop);
18312+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot;
4a4d8108
AM
18313+ bindex++, p++) {
18314+ if (!p->hi_inode)
18315+ continue;
1facf9fc 18316+
027c5e7a 18317+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
18318+ new_bindex = au_br_index(sb, p->hi_id);
18319+ if (new_bindex == bindex)
18320+ continue;
1facf9fc 18321+
4a4d8108 18322+ if (new_bindex < 0) {
027c5e7a 18323+ *update = 1;
4a4d8108
AM
18324+ au_hiput(p);
18325+ p->hi_inode = NULL;
18326+ continue;
1308ab2a 18327+ }
4a4d8108 18328+
5afbbe0d
AM
18329+ if (new_bindex < iinfo->ii_btop)
18330+ iinfo->ii_btop = new_bindex;
18331+ if (iinfo->ii_bbot < new_bindex)
18332+ iinfo->ii_bbot = new_bindex;
4a4d8108 18333+ /* swap two lower inode, and loop again */
5afbbe0d 18334+ q = au_hinode(iinfo, new_bindex);
4a4d8108
AM
18335+ tmp = *q;
18336+ *q = *p;
18337+ *p = tmp;
18338+ if (tmp.hi_inode) {
18339+ bindex--;
18340+ p--;
1308ab2a 18341+ }
18342+ }
4a4d8108 18343+ au_update_ibrange(inode, /*do_put_zero*/0);
e2f27e51 18344+ au_hinode_realloc(iinfo, nbr, /*may_shrink*/1); /* harmless if err */
4a4d8108
AM
18345+ e = au_dy_irefresh(inode);
18346+ if (unlikely(e && !err))
18347+ err = e;
1facf9fc 18348+
4f0767ce 18349+out:
027c5e7a
AM
18350+ AuTraceErr(err);
18351+ return err;
18352+}
18353+
b95c5147
AM
18354+void au_refresh_iop(struct inode *inode, int force_getattr)
18355+{
18356+ int type;
18357+ struct au_sbinfo *sbi = au_sbi(inode->i_sb);
18358+ const struct inode_operations *iop
18359+ = force_getattr ? aufs_iop : sbi->si_iop_array;
18360+
18361+ if (inode->i_op == iop)
18362+ return;
18363+
18364+ switch (inode->i_mode & S_IFMT) {
18365+ case S_IFDIR:
18366+ type = AuIop_DIR;
18367+ break;
18368+ case S_IFLNK:
18369+ type = AuIop_SYMLINK;
18370+ break;
18371+ default:
18372+ type = AuIop_OTHER;
18373+ break;
18374+ }
18375+
18376+ inode->i_op = iop + type;
18377+ /* unnecessary smp_wmb() */
18378+}
18379+
027c5e7a
AM
18380+int au_refresh_hinode_self(struct inode *inode)
18381+{
18382+ int err, update;
18383+
18384+ err = au_ii_refresh(inode, &update);
18385+ if (!err)
18386+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
18387+
18388+ AuTraceErr(err);
4a4d8108
AM
18389+ return err;
18390+}
1facf9fc 18391+
4a4d8108
AM
18392+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
18393+{
027c5e7a 18394+ int err, e, update;
4a4d8108 18395+ unsigned int flags;
027c5e7a 18396+ umode_t mode;
5afbbe0d 18397+ aufs_bindex_t bindex, bbot;
027c5e7a 18398+ unsigned char isdir;
4a4d8108
AM
18399+ struct au_hinode *p;
18400+ struct au_iinfo *iinfo;
1facf9fc 18401+
027c5e7a 18402+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
18403+ if (unlikely(err))
18404+ goto out;
18405+
18406+ update = 0;
18407+ iinfo = au_ii(inode);
5afbbe0d 18408+ p = au_hinode(iinfo, iinfo->ii_btop);
027c5e7a
AM
18409+ mode = (inode->i_mode & S_IFMT);
18410+ isdir = S_ISDIR(mode);
4a4d8108 18411+ flags = au_hi_flags(inode, isdir);
5afbbe0d
AM
18412+ bbot = au_dbbot(dentry);
18413+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) {
5527c038 18414+ struct inode *h_i, *h_inode;
4a4d8108
AM
18415+ struct dentry *h_d;
18416+
18417+ h_d = au_h_dptr(dentry, bindex);
5527c038 18418+ if (!h_d || d_is_negative(h_d))
4a4d8108
AM
18419+ continue;
18420+
5527c038
JR
18421+ h_inode = d_inode(h_d);
18422+ AuDebugOn(mode != (h_inode->i_mode & S_IFMT));
5afbbe0d 18423+ if (iinfo->ii_btop <= bindex && bindex <= iinfo->ii_bbot) {
4a4d8108
AM
18424+ h_i = au_h_iptr(inode, bindex);
18425+ if (h_i) {
5527c038 18426+ if (h_i == h_inode)
4a4d8108
AM
18427+ continue;
18428+ err = -EIO;
18429+ break;
18430+ }
18431+ }
5afbbe0d
AM
18432+ if (bindex < iinfo->ii_btop)
18433+ iinfo->ii_btop = bindex;
18434+ if (iinfo->ii_bbot < bindex)
18435+ iinfo->ii_bbot = bindex;
5527c038 18436+ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags);
4a4d8108 18437+ update = 1;
1308ab2a 18438+ }
4a4d8108
AM
18439+ au_update_ibrange(inode, /*do_put_zero*/0);
18440+ e = au_dy_irefresh(inode);
18441+ if (unlikely(e && !err))
18442+ err = e;
027c5e7a
AM
18443+ if (!err)
18444+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 18445+
4f0767ce 18446+out:
4a4d8108 18447+ AuTraceErr(err);
1308ab2a 18448+ return err;
dece6358
AM
18449+}
18450+
4a4d8108 18451+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 18452+{
4a4d8108
AM
18453+ int err;
18454+ unsigned int flags;
18455+ umode_t mode;
5afbbe0d 18456+ aufs_bindex_t bindex, btop, btail;
4a4d8108
AM
18457+ unsigned char isdir;
18458+ struct dentry *h_dentry;
18459+ struct inode *h_inode;
18460+ struct au_iinfo *iinfo;
b95c5147 18461+ struct inode_operations *iop;
dece6358 18462+
4a4d8108 18463+ IiMustWriteLock(inode);
dece6358 18464+
4a4d8108
AM
18465+ err = 0;
18466+ isdir = 0;
b95c5147 18467+ iop = au_sbi(inode->i_sb)->si_iop_array;
5afbbe0d
AM
18468+ btop = au_dbtop(dentry);
18469+ h_dentry = au_h_dptr(dentry, btop);
5527c038 18470+ h_inode = d_inode(h_dentry);
4a4d8108
AM
18471+ mode = h_inode->i_mode;
18472+ switch (mode & S_IFMT) {
18473+ case S_IFREG:
18474+ btail = au_dbtail(dentry);
b95c5147 18475+ inode->i_op = iop + AuIop_OTHER;
4a4d8108 18476+ inode->i_fop = &aufs_file_fop;
5afbbe0d 18477+ err = au_dy_iaop(inode, btop, h_inode);
4a4d8108
AM
18478+ if (unlikely(err))
18479+ goto out;
18480+ break;
18481+ case S_IFDIR:
18482+ isdir = 1;
18483+ btail = au_dbtaildir(dentry);
b95c5147 18484+ inode->i_op = iop + AuIop_DIR;
4a4d8108
AM
18485+ inode->i_fop = &aufs_dir_fop;
18486+ break;
18487+ case S_IFLNK:
18488+ btail = au_dbtail(dentry);
b95c5147 18489+ inode->i_op = iop + AuIop_SYMLINK;
4a4d8108
AM
18490+ break;
18491+ case S_IFBLK:
18492+ case S_IFCHR:
18493+ case S_IFIFO:
18494+ case S_IFSOCK:
18495+ btail = au_dbtail(dentry);
b95c5147 18496+ inode->i_op = iop + AuIop_OTHER;
38d290e6 18497+ init_special_inode(inode, mode, h_inode->i_rdev);
4a4d8108
AM
18498+ break;
18499+ default:
18500+ AuIOErr("Unknown file type 0%o\n", mode);
18501+ err = -EIO;
1308ab2a 18502+ goto out;
4a4d8108 18503+ }
dece6358 18504+
4a4d8108
AM
18505+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
18506+ flags = au_hi_flags(inode, isdir);
18507+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
18508+ && au_ftest_hi(flags, HNOTIFY)
18509+ && dentry->d_name.len > AUFS_WH_PFX_LEN
18510+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
18511+ au_fclr_hi(flags, HNOTIFY);
18512+ iinfo = au_ii(inode);
5afbbe0d
AM
18513+ iinfo->ii_btop = btop;
18514+ iinfo->ii_bbot = btail;
18515+ for (bindex = btop; bindex <= btail; bindex++) {
4a4d8108
AM
18516+ h_dentry = au_h_dptr(dentry, bindex);
18517+ if (h_dentry)
18518+ au_set_h_iptr(inode, bindex,
5527c038 18519+ au_igrab(d_inode(h_dentry)), flags);
4a4d8108
AM
18520+ }
18521+ au_cpup_attr_all(inode, /*force*/1);
c1595e42
JR
18522+ /*
18523+ * to force calling aufs_get_acl() every time,
18524+ * do not call cache_no_acl() for aufs inode.
18525+ */
dece6358 18526+
4f0767ce 18527+out:
4a4d8108
AM
18528+ return err;
18529+}
dece6358 18530+
027c5e7a
AM
18531+/*
18532+ * successful returns with iinfo write_locked
18533+ * minus: errno
18534+ * zero: success, matched
18535+ * plus: no error, but unmatched
18536+ */
18537+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
18538+{
18539+ int err;
cfc41e69 18540+ unsigned int gen, igflags;
5afbbe0d 18541+ aufs_bindex_t bindex, bbot;
4a4d8108 18542+ struct inode *h_inode, *h_dinode;
5527c038 18543+ struct dentry *h_dentry;
dece6358 18544+
4a4d8108
AM
18545+ /*
18546+ * before this function, if aufs got any iinfo lock, it must be only
18547+ * one, the parent dir.
18548+ * it can happen by UDBA and the obsoleted inode number.
18549+ */
18550+ err = -EIO;
18551+ if (unlikely(inode->i_ino == parent_ino(dentry)))
18552+ goto out;
18553+
027c5e7a 18554+ err = 1;
4a4d8108 18555+ ii_write_lock_new_child(inode);
5afbbe0d 18556+ h_dentry = au_h_dptr(dentry, au_dbtop(dentry));
5527c038 18557+ h_dinode = d_inode(h_dentry);
5afbbe0d
AM
18558+ bbot = au_ibbot(inode);
18559+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
4a4d8108 18560+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
18561+ if (!h_inode || h_inode != h_dinode)
18562+ continue;
18563+
18564+ err = 0;
cfc41e69 18565+ gen = au_iigen(inode, &igflags);
537831f9 18566+ if (gen == au_digen(dentry)
cfc41e69 18567+ && !au_ig_ftest(igflags, HALF_REFRESHED))
4a4d8108 18568+ break;
537831f9
AM
18569+
18570+ /* fully refresh inode using dentry */
18571+ err = au_refresh_hinode(inode, dentry);
18572+ if (!err)
18573+ au_update_iigen(inode, /*half*/0);
18574+ break;
1facf9fc 18575+ }
dece6358 18576+
4a4d8108
AM
18577+ if (unlikely(err))
18578+ ii_write_unlock(inode);
4f0767ce 18579+out:
1facf9fc 18580+ return err;
18581+}
1facf9fc 18582+
4a4d8108
AM
18583+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
18584+ unsigned int d_type, ino_t *ino)
1facf9fc 18585+{
521ced18
JR
18586+ int err, idx;
18587+ const int isnondir = d_type != DT_DIR;
1facf9fc 18588+
b752ccd1 18589+ /* prevent hardlinked inode number from race condition */
521ced18
JR
18590+ if (isnondir) {
18591+ err = au_xinondir_enter(sb, bindex, h_ino, &idx);
18592+ if (unlikely(err))
18593+ goto out;
4a4d8108 18594+ }
521ced18 18595+
4a4d8108
AM
18596+ err = au_xino_read(sb, bindex, h_ino, ino);
18597+ if (unlikely(err))
521ced18 18598+ goto out_xinondir;
1308ab2a 18599+
4a4d8108
AM
18600+ if (!*ino) {
18601+ err = -EIO;
18602+ *ino = au_xino_new_ino(sb);
18603+ if (unlikely(!*ino))
521ced18 18604+ goto out_xinondir;
4a4d8108
AM
18605+ err = au_xino_write(sb, bindex, h_ino, *ino);
18606+ if (unlikely(err))
521ced18 18607+ goto out_xinondir;
1308ab2a 18608+ }
1facf9fc 18609+
521ced18
JR
18610+out_xinondir:
18611+ if (isnondir && idx >= 0)
18612+ au_xinondir_leave(sb, bindex, h_ino, idx);
4f0767ce 18613+out:
1facf9fc 18614+ return err;
18615+}
18616+
4a4d8108
AM
18617+/* successful returns with iinfo write_locked */
18618+/* todo: return with unlocked? */
18619+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 18620+{
5527c038 18621+ struct inode *inode, *h_inode;
4a4d8108
AM
18622+ struct dentry *h_dentry;
18623+ struct super_block *sb;
18624+ ino_t h_ino, ino;
521ced18 18625+ int err, idx, hlinked;
5afbbe0d 18626+ aufs_bindex_t btop;
1facf9fc 18627+
4a4d8108 18628+ sb = dentry->d_sb;
5afbbe0d
AM
18629+ btop = au_dbtop(dentry);
18630+ h_dentry = au_h_dptr(dentry, btop);
5527c038
JR
18631+ h_inode = d_inode(h_dentry);
18632+ h_ino = h_inode->i_ino;
521ced18 18633+ hlinked = !d_is_dir(h_dentry) && h_inode->i_nlink > 1;
b752ccd1 18634+
521ced18 18635+new_ino:
b752ccd1
AM
18636+ /*
18637+ * stop 'race'-ing between hardlinks under different
18638+ * parents.
18639+ */
521ced18
JR
18640+ if (hlinked) {
18641+ err = au_xinondir_enter(sb, btop, h_ino, &idx);
18642+ inode = ERR_PTR(err);
18643+ if (unlikely(err))
18644+ goto out;
18645+ }
b752ccd1 18646+
5afbbe0d 18647+ err = au_xino_read(sb, btop, h_ino, &ino);
4a4d8108
AM
18648+ inode = ERR_PTR(err);
18649+ if (unlikely(err))
521ced18 18650+ goto out_xinondir;
b752ccd1 18651+
4a4d8108
AM
18652+ if (!ino) {
18653+ ino = au_xino_new_ino(sb);
18654+ if (unlikely(!ino)) {
18655+ inode = ERR_PTR(-EIO);
521ced18 18656+ goto out_xinondir;
dece6358
AM
18657+ }
18658+ }
1facf9fc 18659+
4a4d8108
AM
18660+ AuDbg("i%lu\n", (unsigned long)ino);
18661+ inode = au_iget_locked(sb, ino);
18662+ err = PTR_ERR(inode);
18663+ if (IS_ERR(inode))
521ced18 18664+ goto out_xinondir;
1facf9fc 18665+
4a4d8108
AM
18666+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
18667+ if (inode->i_state & I_NEW) {
18668+ ii_write_lock_new_child(inode);
18669+ err = set_inode(inode, dentry);
18670+ if (!err) {
18671+ unlock_new_inode(inode);
521ced18 18672+ goto out_xinondir; /* success */
4a4d8108 18673+ }
1308ab2a 18674+
027c5e7a
AM
18675+ /*
18676+ * iget_failed() calls iput(), but we need to call
18677+ * ii_write_unlock() after iget_failed(). so dirty hack for
18678+ * i_count.
18679+ */
18680+ atomic_inc(&inode->i_count);
4a4d8108 18681+ iget_failed(inode);
027c5e7a 18682+ ii_write_unlock(inode);
5afbbe0d 18683+ au_xino_write(sb, btop, h_ino, /*ino*/0);
027c5e7a
AM
18684+ /* ignore this error */
18685+ goto out_iput;
18686+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
18687+ /*
18688+ * horrible race condition between lookup, readdir and copyup
18689+ * (or something).
18690+ */
521ced18
JR
18691+ if (hlinked && idx >= 0)
18692+ au_xinondir_leave(sb, btop, h_ino, idx);
027c5e7a
AM
18693+ err = reval_inode(inode, dentry);
18694+ if (unlikely(err < 0)) {
521ced18 18695+ hlinked = 0;
027c5e7a
AM
18696+ goto out_iput;
18697+ }
521ced18 18698+ if (!err)
4a4d8108 18699+ goto out; /* success */
521ced18
JR
18700+ else if (hlinked && idx >= 0) {
18701+ err = au_xinondir_enter(sb, btop, h_ino, &idx);
18702+ if (unlikely(err)) {
18703+ iput(inode);
18704+ inode = ERR_PTR(err);
18705+ goto out;
18706+ }
18707+ }
4a4d8108
AM
18708+ }
18709+
5527c038 18710+ if (unlikely(au_test_fs_unique_ino(h_inode)))
4a4d8108 18711+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3 18712+ " b%d, %s, %pd, hi%lu, i%lu.\n",
5afbbe0d 18713+ btop, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
18714+ (unsigned long)h_ino, (unsigned long)ino);
18715+ ino = 0;
5afbbe0d 18716+ err = au_xino_write(sb, btop, h_ino, /*ino*/0);
4a4d8108
AM
18717+ if (!err) {
18718+ iput(inode);
521ced18
JR
18719+ if (hlinked && idx >= 0)
18720+ au_xinondir_leave(sb, btop, h_ino, idx);
4a4d8108
AM
18721+ goto new_ino;
18722+ }
1308ab2a 18723+
4f0767ce 18724+out_iput:
4a4d8108 18725+ iput(inode);
4a4d8108 18726+ inode = ERR_PTR(err);
521ced18
JR
18727+out_xinondir:
18728+ if (hlinked && idx >= 0)
18729+ au_xinondir_leave(sb, btop, h_ino, idx);
4f0767ce 18730+out:
4a4d8108 18731+ return inode;
1facf9fc 18732+}
18733+
4a4d8108 18734+/* ---------------------------------------------------------------------- */
1facf9fc 18735+
4a4d8108
AM
18736+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
18737+ struct inode *inode)
18738+{
18739+ int err;
076b876e 18740+ struct inode *hi;
1facf9fc 18741+
4a4d8108 18742+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 18743+
4a4d8108
AM
18744+ /* pseudo-link after flushed may happen out of bounds */
18745+ if (!err
18746+ && inode
5afbbe0d
AM
18747+ && au_ibtop(inode) <= bindex
18748+ && bindex <= au_ibbot(inode)) {
4a4d8108
AM
18749+ /*
18750+ * permission check is unnecessary since vfsub routine
18751+ * will be called later
18752+ */
076b876e 18753+ hi = au_h_iptr(inode, bindex);
4a4d8108
AM
18754+ if (hi)
18755+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 18756+ }
18757+
4a4d8108
AM
18758+ return err;
18759+}
dece6358 18760+
4a4d8108
AM
18761+int au_test_h_perm(struct inode *h_inode, int mask)
18762+{
2dfbb274 18763+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
18764+ return 0;
18765+ return inode_permission(h_inode, mask);
18766+}
1facf9fc 18767+
4a4d8108
AM
18768+int au_test_h_perm_sio(struct inode *h_inode, int mask)
18769+{
18770+ if (au_test_nfs(h_inode->i_sb)
18771+ && (mask & MAY_WRITE)
18772+ && S_ISDIR(h_inode->i_mode))
18773+ mask |= MAY_READ; /* force permission check */
18774+ return au_test_h_perm(h_inode, mask);
1facf9fc 18775+}
7f207e10
AM
18776diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
18777--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 18778+++ linux/fs/aufs/inode.h 2018-08-12 23:43:05.460124736 +0200
062440b3
AM
18779@@ -0,0 +1,696 @@
18780+/* SPDX-License-Identifier: GPL-2.0 */
4a4d8108 18781+/*
b00004a5 18782+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
18783+ *
18784+ * This program, aufs is free software; you can redistribute it and/or modify
18785+ * it under the terms of the GNU General Public License as published by
18786+ * the Free Software Foundation; either version 2 of the License, or
18787+ * (at your option) any later version.
18788+ *
18789+ * This program is distributed in the hope that it will be useful,
18790+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18791+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18792+ * GNU General Public License for more details.
18793+ *
18794+ * You should have received a copy of the GNU General Public License
523b37e3 18795+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 18796+ */
1facf9fc 18797+
1308ab2a 18798+/*
4a4d8108 18799+ * inode operations
1308ab2a 18800+ */
dece6358 18801+
4a4d8108
AM
18802+#ifndef __AUFS_INODE_H__
18803+#define __AUFS_INODE_H__
dece6358 18804+
4a4d8108 18805+#ifdef __KERNEL__
1308ab2a 18806+
4a4d8108 18807+#include <linux/fsnotify.h>
4a4d8108 18808+#include "rwsem.h"
1308ab2a 18809+
4a4d8108 18810+struct vfsmount;
1facf9fc 18811+
4a4d8108
AM
18812+struct au_hnotify {
18813+#ifdef CONFIG_AUFS_HNOTIFY
18814+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 18815+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 18816+ struct fsnotify_mark hn_mark;
4a4d8108 18817+#endif
1c60b727 18818+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
18819+#endif
18820+} ____cacheline_aligned_in_smp;
1facf9fc 18821+
4a4d8108
AM
18822+struct au_hinode {
18823+ struct inode *hi_inode;
18824+ aufs_bindex_t hi_id;
18825+#ifdef CONFIG_AUFS_HNOTIFY
18826+ struct au_hnotify *hi_notify;
18827+#endif
dece6358 18828+
4a4d8108
AM
18829+ /* reference to the copied-up whiteout with get/put */
18830+ struct dentry *hi_whdentry;
18831+};
dece6358 18832+
537831f9
AM
18833+/* ig_flags */
18834+#define AuIG_HALF_REFRESHED 1
18835+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
18836+#define au_ig_fset(flags, name) \
18837+ do { (flags) |= AuIG_##name; } while (0)
18838+#define au_ig_fclr(flags, name) \
18839+ do { (flags) &= ~AuIG_##name; } while (0)
18840+
18841+struct au_iigen {
be52b249 18842+ spinlock_t ig_spin;
537831f9
AM
18843+ __u32 ig_generation, ig_flags;
18844+};
18845+
4a4d8108
AM
18846+struct au_vdir;
18847+struct au_iinfo {
7a9e40b8 18848+ struct au_iigen ii_generation;
4a4d8108 18849+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 18850+
4a4d8108 18851+ struct au_rwsem ii_rwsem;
5afbbe0d 18852+ aufs_bindex_t ii_btop, ii_bbot;
4a4d8108
AM
18853+ __u32 ii_higen;
18854+ struct au_hinode *ii_hinode;
18855+ struct au_vdir *ii_vdir;
18856+};
1facf9fc 18857+
4a4d8108
AM
18858+struct au_icntnr {
18859+ struct au_iinfo iinfo;
18860+ struct inode vfs_inode;
8b6a4947 18861+ struct hlist_bl_node plink;
4a4d8108 18862+} ____cacheline_aligned_in_smp;
1308ab2a 18863+
4a4d8108
AM
18864+/* au_pin flags */
18865+#define AuPin_DI_LOCKED 1
18866+#define AuPin_MNT_WRITE (1 << 1)
18867+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
18868+#define au_fset_pin(flags, name) \
18869+ do { (flags) |= AuPin_##name; } while (0)
18870+#define au_fclr_pin(flags, name) \
18871+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
18872+
18873+struct au_pin {
18874+ /* input */
18875+ struct dentry *dentry;
18876+ unsigned int udba;
18877+ unsigned char lsc_di, lsc_hi, flags;
18878+ aufs_bindex_t bindex;
18879+
18880+ /* output */
18881+ struct dentry *parent;
18882+ struct au_hinode *hdir;
18883+ struct vfsmount *h_mnt;
86dc4139
AM
18884+
18885+ /* temporary unlock/relock for copyup */
18886+ struct dentry *h_dentry, *h_parent;
18887+ struct au_branch *br;
18888+ struct task_struct *task;
4a4d8108 18889+};
1facf9fc 18890+
86dc4139 18891+void au_pin_hdir_unlock(struct au_pin *p);
c1595e42 18892+int au_pin_hdir_lock(struct au_pin *p);
86dc4139 18893+int au_pin_hdir_relock(struct au_pin *p);
86dc4139
AM
18894+void au_pin_hdir_acquire_nest(struct au_pin *p);
18895+void au_pin_hdir_release(struct au_pin *p);
18896+
1308ab2a 18897+/* ---------------------------------------------------------------------- */
18898+
4a4d8108 18899+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 18900+{
5afbbe0d
AM
18901+ BUG_ON(is_bad_inode(inode));
18902+ return &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
4a4d8108 18903+}
1facf9fc 18904+
4a4d8108 18905+/* ---------------------------------------------------------------------- */
1facf9fc 18906+
4a4d8108
AM
18907+/* inode.c */
18908+struct inode *au_igrab(struct inode *inode);
b95c5147 18909+void au_refresh_iop(struct inode *inode, int force_getattr);
027c5e7a 18910+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
18911+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
18912+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
18913+ unsigned int d_type, ino_t *ino);
18914+struct inode *au_new_inode(struct dentry *dentry, int must_new);
18915+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
18916+ struct inode *inode);
18917+int au_test_h_perm(struct inode *h_inode, int mask);
18918+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 18919+
4a4d8108
AM
18920+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
18921+ ino_t h_ino, unsigned int d_type, ino_t *ino)
18922+{
18923+#ifdef CONFIG_AUFS_SHWH
18924+ return au_ino(sb, bindex, h_ino, d_type, ino);
18925+#else
18926+ return 0;
18927+#endif
18928+}
1facf9fc 18929+
4a4d8108 18930+/* i_op.c */
b95c5147
AM
18931+enum {
18932+ AuIop_SYMLINK,
18933+ AuIop_DIR,
18934+ AuIop_OTHER,
18935+ AuIop_Last
18936+};
18937+extern struct inode_operations aufs_iop[AuIop_Last],
18938+ aufs_iop_nogetattr[AuIop_Last];
1308ab2a 18939+
4a4d8108
AM
18940+/* au_wr_dir flags */
18941+#define AuWrDir_ADD_ENTRY 1
7e9cd9fe
AM
18942+#define AuWrDir_ISDIR (1 << 1)
18943+#define AuWrDir_TMPFILE (1 << 2)
4a4d8108 18944+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
18945+#define au_fset_wrdir(flags, name) \
18946+ do { (flags) |= AuWrDir_##name; } while (0)
18947+#define au_fclr_wrdir(flags, name) \
18948+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 18949+
4a4d8108
AM
18950+struct au_wr_dir_args {
18951+ aufs_bindex_t force_btgt;
18952+ unsigned char flags;
18953+};
18954+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
18955+ struct au_wr_dir_args *args);
dece6358 18956+
4a4d8108
AM
18957+struct dentry *au_pinned_h_parent(struct au_pin *pin);
18958+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
18959+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
18960+ unsigned int udba, unsigned char flags);
18961+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
18962+ unsigned int udba, unsigned char flags) __must_check;
18963+int au_do_pin(struct au_pin *pin) __must_check;
18964+void au_unpin(struct au_pin *pin);
c1595e42
JR
18965+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
18966+
18967+#define AuIcpup_DID_CPUP 1
18968+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
18969+#define au_fset_icpup(flags, name) \
18970+ do { (flags) |= AuIcpup_##name; } while (0)
18971+#define au_fclr_icpup(flags, name) \
18972+ do { (flags) &= ~AuIcpup_##name; } while (0)
18973+
18974+struct au_icpup_args {
18975+ unsigned char flags;
18976+ unsigned char pin_flags;
18977+ aufs_bindex_t btgt;
18978+ unsigned int udba;
18979+ struct au_pin pin;
18980+ struct path h_path;
18981+ struct inode *h_inode;
18982+};
18983+
18984+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
18985+ struct au_icpup_args *a);
18986+
a2654f78
AM
18987+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
18988+ int locked);
1facf9fc 18989+
4a4d8108
AM
18990+/* i_op_add.c */
18991+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
18992+ struct dentry *h_parent, int isdir);
7eafdf33
AM
18993+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
18994+ dev_t dev);
4a4d8108 18995+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 18996+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 18997+ bool want_excl);
b912730e
AM
18998+struct vfsub_aopen_args;
18999+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
19000+ struct vfsub_aopen_args *args);
38d290e6 19001+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
4a4d8108
AM
19002+int aufs_link(struct dentry *src_dentry, struct inode *dir,
19003+ struct dentry *dentry);
7eafdf33 19004+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 19005+
4a4d8108
AM
19006+/* i_op_del.c */
19007+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
19008+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
19009+ struct dentry *h_parent, int isdir);
19010+int aufs_unlink(struct inode *dir, struct dentry *dentry);
19011+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 19012+
4a4d8108
AM
19013+/* i_op_ren.c */
19014+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
19015+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
f2c43d5f
AM
19016+ struct inode *dir, struct dentry *dentry,
19017+ unsigned int flags);
1facf9fc 19018+
4a4d8108
AM
19019+/* iinfo.c */
19020+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
19021+void au_hiput(struct au_hinode *hinode);
19022+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
19023+ struct dentry *h_wh);
19024+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 19025+
4a4d8108
AM
19026+/* hinode flags */
19027+#define AuHi_XINO 1
19028+#define AuHi_HNOTIFY (1 << 1)
19029+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
19030+#define au_fset_hi(flags, name) \
19031+ do { (flags) |= AuHi_##name; } while (0)
19032+#define au_fclr_hi(flags, name) \
19033+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 19034+
4a4d8108
AM
19035+#ifndef CONFIG_AUFS_HNOTIFY
19036+#undef AuHi_HNOTIFY
19037+#define AuHi_HNOTIFY 0
19038+#endif
1facf9fc 19039+
4a4d8108
AM
19040+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
19041+ struct inode *h_inode, unsigned int flags);
1facf9fc 19042+
537831f9 19043+void au_update_iigen(struct inode *inode, int half);
4a4d8108 19044+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 19045+
4a4d8108 19046+void au_icntnr_init_once(void *_c);
5afbbe0d 19047+void au_hinode_init(struct au_hinode *hinode);
4a4d8108
AM
19048+int au_iinfo_init(struct inode *inode);
19049+void au_iinfo_fin(struct inode *inode);
e2f27e51 19050+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink);
1308ab2a 19051+
e49829fe 19052+#ifdef CONFIG_PROC_FS
4a4d8108 19053+/* plink.c */
e49829fe 19054+int au_plink_maint(struct super_block *sb, int flags);
7e9cd9fe 19055+struct au_sbinfo;
e49829fe
JR
19056+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
19057+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
19058+#ifdef CONFIG_AUFS_DEBUG
19059+void au_plink_list(struct super_block *sb);
19060+#else
19061+AuStubVoid(au_plink_list, struct super_block *sb)
19062+#endif
19063+int au_plink_test(struct inode *inode);
19064+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
19065+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
19066+ struct dentry *h_dentry);
e49829fe
JR
19067+void au_plink_put(struct super_block *sb, int verbose);
19068+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 19069+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
19070+#else
19071+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
19072+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
19073+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
19074+AuStubVoid(au_plink_list, struct super_block *sb);
19075+AuStubInt0(au_plink_test, struct inode *inode);
19076+AuStub(struct dentry *, au_plink_lkup, return NULL,
19077+ struct inode *inode, aufs_bindex_t bindex);
19078+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
19079+ struct dentry *h_dentry);
19080+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
19081+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
19082+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
19083+#endif /* CONFIG_PROC_FS */
1facf9fc 19084+
c1595e42
JR
19085+#ifdef CONFIG_AUFS_XATTR
19086+/* xattr.c */
7e9cd9fe
AM
19087+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
19088+ unsigned int verbose);
c1595e42 19089+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
f2c43d5f 19090+void au_xattr_init(struct super_block *sb);
c1595e42
JR
19091+#else
19092+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe 19093+ int ignore_flags, unsigned int verbose);
f2c43d5f 19094+AuStubVoid(au_xattr_init, struct super_block *sb);
c1595e42
JR
19095+#endif
19096+
19097+#ifdef CONFIG_FS_POSIX_ACL
19098+struct posix_acl *aufs_get_acl(struct inode *inode, int type);
19099+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
19100+#endif
19101+
19102+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
19103+enum {
19104+ AU_XATTR_SET,
c1595e42
JR
19105+ AU_ACL_SET
19106+};
19107+
f2c43d5f 19108+struct au_sxattr {
c1595e42
JR
19109+ int type;
19110+ union {
19111+ struct {
19112+ const char *name;
19113+ const void *value;
19114+ size_t size;
19115+ int flags;
19116+ } set;
19117+ struct {
c1595e42
JR
19118+ struct posix_acl *acl;
19119+ int type;
19120+ } acl_set;
19121+ } u;
19122+};
f2c43d5f
AM
19123+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
19124+ struct au_sxattr *arg);
c1595e42
JR
19125+#endif
19126+
4a4d8108 19127+/* ---------------------------------------------------------------------- */
1308ab2a 19128+
4a4d8108
AM
19129+/* lock subclass for iinfo */
19130+enum {
19131+ AuLsc_II_CHILD, /* child first */
19132+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
19133+ AuLsc_II_CHILD3, /* copyup dirs */
19134+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
19135+ AuLsc_II_PARENT2,
19136+ AuLsc_II_PARENT3, /* copyup dirs */
19137+ AuLsc_II_NEW_CHILD
19138+};
1308ab2a 19139+
1facf9fc 19140+/*
4a4d8108
AM
19141+ * ii_read_lock_child, ii_write_lock_child,
19142+ * ii_read_lock_child2, ii_write_lock_child2,
19143+ * ii_read_lock_child3, ii_write_lock_child3,
19144+ * ii_read_lock_parent, ii_write_lock_parent,
19145+ * ii_read_lock_parent2, ii_write_lock_parent2,
19146+ * ii_read_lock_parent3, ii_write_lock_parent3,
19147+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 19148+ */
4a4d8108
AM
19149+#define AuReadLockFunc(name, lsc) \
19150+static inline void ii_read_lock_##name(struct inode *i) \
19151+{ \
19152+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
19153+}
19154+
19155+#define AuWriteLockFunc(name, lsc) \
19156+static inline void ii_write_lock_##name(struct inode *i) \
19157+{ \
19158+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
19159+}
19160+
19161+#define AuRWLockFuncs(name, lsc) \
19162+ AuReadLockFunc(name, lsc) \
19163+ AuWriteLockFunc(name, lsc)
19164+
19165+AuRWLockFuncs(child, CHILD);
19166+AuRWLockFuncs(child2, CHILD2);
19167+AuRWLockFuncs(child3, CHILD3);
19168+AuRWLockFuncs(parent, PARENT);
19169+AuRWLockFuncs(parent2, PARENT2);
19170+AuRWLockFuncs(parent3, PARENT3);
19171+AuRWLockFuncs(new_child, NEW_CHILD);
19172+
19173+#undef AuReadLockFunc
19174+#undef AuWriteLockFunc
19175+#undef AuRWLockFuncs
1facf9fc 19176+
8b6a4947
AM
19177+#define ii_read_unlock(i) au_rw_read_unlock(&au_ii(i)->ii_rwsem)
19178+#define ii_write_unlock(i) au_rw_write_unlock(&au_ii(i)->ii_rwsem)
19179+#define ii_downgrade_lock(i) au_rw_dgrade_lock(&au_ii(i)->ii_rwsem)
1facf9fc 19180+
4a4d8108
AM
19181+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
19182+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
19183+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 19184+
4a4d8108 19185+/* ---------------------------------------------------------------------- */
1308ab2a 19186+
027c5e7a
AM
19187+static inline void au_icntnr_init(struct au_icntnr *c)
19188+{
19189+#ifdef CONFIG_AUFS_DEBUG
19190+ c->vfs_inode.i_mode = 0;
19191+#endif
19192+}
19193+
cfc41e69 19194+static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags)
4a4d8108 19195+{
537831f9
AM
19196+ unsigned int gen;
19197+ struct au_iinfo *iinfo;
be52b249 19198+ struct au_iigen *iigen;
537831f9
AM
19199+
19200+ iinfo = au_ii(inode);
be52b249
AM
19201+ iigen = &iinfo->ii_generation;
19202+ spin_lock(&iigen->ig_spin);
cfc41e69
AM
19203+ if (igflags)
19204+ *igflags = iigen->ig_flags;
be52b249
AM
19205+ gen = iigen->ig_generation;
19206+ spin_unlock(&iigen->ig_spin);
537831f9
AM
19207+
19208+ return gen;
4a4d8108 19209+}
1308ab2a 19210+
4a4d8108
AM
19211+/* tiny test for inode number */
19212+/* tmpfs generation is too rough */
19213+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
19214+{
19215+ struct au_iinfo *iinfo;
1308ab2a 19216+
4a4d8108
AM
19217+ iinfo = au_ii(inode);
19218+ AuRwMustAnyLock(&iinfo->ii_rwsem);
19219+ return !(iinfo->ii_hsb1 == h_inode->i_sb
19220+ && iinfo->ii_higen == h_inode->i_generation);
19221+}
1308ab2a 19222+
4a4d8108
AM
19223+static inline void au_iigen_dec(struct inode *inode)
19224+{
537831f9 19225+ struct au_iinfo *iinfo;
be52b249 19226+ struct au_iigen *iigen;
537831f9
AM
19227+
19228+ iinfo = au_ii(inode);
be52b249
AM
19229+ iigen = &iinfo->ii_generation;
19230+ spin_lock(&iigen->ig_spin);
19231+ iigen->ig_generation--;
19232+ spin_unlock(&iigen->ig_spin);
027c5e7a
AM
19233+}
19234+
19235+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
19236+{
19237+ int err;
19238+
19239+ err = 0;
537831f9 19240+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
19241+ err = -EIO;
19242+
19243+ return err;
4a4d8108 19244+}
1308ab2a 19245+
4a4d8108 19246+/* ---------------------------------------------------------------------- */
1308ab2a 19247+
5afbbe0d
AM
19248+static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo,
19249+ aufs_bindex_t bindex)
19250+{
19251+ return iinfo->ii_hinode + bindex;
19252+}
19253+
19254+static inline int au_is_bad_inode(struct inode *inode)
19255+{
19256+ return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0));
19257+}
19258+
4a4d8108
AM
19259+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
19260+ aufs_bindex_t bindex)
19261+{
19262+ IiMustAnyLock(inode);
5afbbe0d 19263+ return au_hinode(au_ii(inode), bindex)->hi_id;
4a4d8108 19264+}
1308ab2a 19265+
5afbbe0d 19266+static inline aufs_bindex_t au_ibtop(struct inode *inode)
4a4d8108
AM
19267+{
19268+ IiMustAnyLock(inode);
5afbbe0d 19269+ return au_ii(inode)->ii_btop;
4a4d8108 19270+}
1308ab2a 19271+
5afbbe0d 19272+static inline aufs_bindex_t au_ibbot(struct inode *inode)
4a4d8108
AM
19273+{
19274+ IiMustAnyLock(inode);
5afbbe0d 19275+ return au_ii(inode)->ii_bbot;
4a4d8108 19276+}
1308ab2a 19277+
4a4d8108
AM
19278+static inline struct au_vdir *au_ivdir(struct inode *inode)
19279+{
19280+ IiMustAnyLock(inode);
19281+ return au_ii(inode)->ii_vdir;
19282+}
1308ab2a 19283+
4a4d8108
AM
19284+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
19285+{
19286+ IiMustAnyLock(inode);
5afbbe0d 19287+ return au_hinode(au_ii(inode), bindex)->hi_whdentry;
4a4d8108 19288+}
1308ab2a 19289+
5afbbe0d 19290+static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 19291+{
4a4d8108 19292+ IiMustWriteLock(inode);
5afbbe0d 19293+ au_ii(inode)->ii_btop = bindex;
4a4d8108 19294+}
1308ab2a 19295+
5afbbe0d 19296+static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex)
4a4d8108
AM
19297+{
19298+ IiMustWriteLock(inode);
5afbbe0d 19299+ au_ii(inode)->ii_bbot = bindex;
1308ab2a 19300+}
19301+
4a4d8108
AM
19302+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
19303+{
19304+ IiMustWriteLock(inode);
19305+ au_ii(inode)->ii_vdir = vdir;
19306+}
1facf9fc 19307+
4a4d8108 19308+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 19309+{
4a4d8108 19310+ IiMustAnyLock(inode);
5afbbe0d 19311+ return au_hinode(au_ii(inode), bindex);
4a4d8108 19312+}
dece6358 19313+
4a4d8108 19314+/* ---------------------------------------------------------------------- */
1facf9fc 19315+
4a4d8108
AM
19316+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
19317+{
19318+ if (pin)
19319+ return pin->parent;
19320+ return NULL;
1facf9fc 19321+}
19322+
4a4d8108 19323+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 19324+{
4a4d8108
AM
19325+ if (pin && pin->hdir)
19326+ return pin->hdir->hi_inode;
19327+ return NULL;
1308ab2a 19328+}
1facf9fc 19329+
4a4d8108
AM
19330+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
19331+{
19332+ if (pin)
19333+ return pin->hdir;
19334+ return NULL;
19335+}
1facf9fc 19336+
4a4d8108 19337+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 19338+{
4a4d8108
AM
19339+ if (pin)
19340+ pin->dentry = dentry;
19341+}
1308ab2a 19342+
4a4d8108
AM
19343+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
19344+ unsigned char lflag)
19345+{
19346+ if (pin) {
7f207e10 19347+ if (lflag)
4a4d8108 19348+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 19349+ else
4a4d8108 19350+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 19351+ }
4a4d8108
AM
19352+}
19353+
7e9cd9fe 19354+#if 0 /* reserved */
4a4d8108
AM
19355+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
19356+{
19357+ if (pin) {
19358+ dput(pin->parent);
19359+ pin->parent = dget(parent);
1facf9fc 19360+ }
4a4d8108 19361+}
7e9cd9fe 19362+#endif
1facf9fc 19363+
4a4d8108
AM
19364+/* ---------------------------------------------------------------------- */
19365+
027c5e7a 19366+struct au_branch;
4a4d8108
AM
19367+#ifdef CONFIG_AUFS_HNOTIFY
19368+struct au_hnotify_op {
19369+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 19370+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
19371+
19372+ /*
19373+ * if it returns true, the the caller should free hinode->hi_notify,
19374+ * otherwise ->free() frees it.
19375+ */
19376+ int (*free)(struct au_hinode *hinode,
19377+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
19378+
19379+ void (*fin)(void);
19380+ int (*init)(void);
027c5e7a
AM
19381+
19382+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
19383+ void (*fin_br)(struct au_branch *br);
19384+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
19385+};
19386+
19387+/* hnotify.c */
027c5e7a 19388+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
19389+void au_hn_free(struct au_hinode *hinode);
19390+void au_hn_ctl(struct au_hinode *hinode, int do_set);
19391+void au_hn_reset(struct inode *inode, unsigned int flags);
19392+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
19393+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
19394+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
19395+int au_hnotify_init_br(struct au_branch *br, int perm);
19396+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
19397+int __init au_hnotify_init(void);
19398+void au_hnotify_fin(void);
19399+
7f207e10 19400+/* hfsnotify.c */
4a4d8108
AM
19401+extern const struct au_hnotify_op au_hnotify_op;
19402+
19403+static inline
19404+void au_hn_init(struct au_hinode *hinode)
19405+{
19406+ hinode->hi_notify = NULL;
1308ab2a 19407+}
19408+
53392da6
AM
19409+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
19410+{
19411+ return hinode->hi_notify;
19412+}
19413+
4a4d8108 19414+#else
c1595e42
JR
19415+AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
19416+ struct au_hinode *hinode __maybe_unused,
19417+ struct inode *inode __maybe_unused)
19418+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
4a4d8108
AM
19419+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
19420+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
19421+ int do_set __maybe_unused)
19422+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
19423+ unsigned int flags __maybe_unused)
027c5e7a
AM
19424+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
19425+ struct au_branch *br __maybe_unused,
19426+ int perm __maybe_unused)
19427+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
19428+ int perm __maybe_unused)
19429+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
19430+AuStubInt0(__init au_hnotify_init, void)
19431+AuStubVoid(au_hnotify_fin, void)
19432+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
19433+#endif /* CONFIG_AUFS_HNOTIFY */
19434+
19435+static inline void au_hn_suspend(struct au_hinode *hdir)
19436+{
19437+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 19438+}
19439+
4a4d8108 19440+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 19441+{
4a4d8108
AM
19442+ au_hn_ctl(hdir, /*do_set*/1);
19443+}
1308ab2a 19444+
5afbbe0d 19445+static inline void au_hn_inode_lock(struct au_hinode *hdir)
4a4d8108 19446+{
febd17d6 19447+ inode_lock(hdir->hi_inode);
4a4d8108
AM
19448+ au_hn_suspend(hdir);
19449+}
dece6358 19450+
5afbbe0d 19451+static inline void au_hn_inode_lock_nested(struct au_hinode *hdir,
4a4d8108
AM
19452+ unsigned int sc __maybe_unused)
19453+{
febd17d6 19454+ inode_lock_nested(hdir->hi_inode, sc);
4a4d8108 19455+ au_hn_suspend(hdir);
1facf9fc 19456+}
1facf9fc 19457+
8b6a4947
AM
19458+#if 0 /* unused */
19459+#include "vfsub.h"
3c1bdaff
AM
19460+static inline void au_hn_inode_lock_shared_nested(struct au_hinode *hdir,
19461+ unsigned int sc)
19462+{
be118d29 19463+ inode_lock_shared_nested(hdir->hi_inode, sc);
3c1bdaff
AM
19464+ au_hn_suspend(hdir);
19465+}
8b6a4947 19466+#endif
3c1bdaff 19467+
5afbbe0d 19468+static inline void au_hn_inode_unlock(struct au_hinode *hdir)
4a4d8108
AM
19469+{
19470+ au_hn_resume(hdir);
febd17d6 19471+ inode_unlock(hdir->hi_inode);
4a4d8108
AM
19472+}
19473+
19474+#endif /* __KERNEL__ */
19475+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
19476diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
19477--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 19478+++ linux/fs/aufs/ioctl.c 2018-10-23 12:33:35.599375796 +0200
062440b3 19479@@ -0,0 +1,220 @@
cd7a4cd9 19480+// SPDX-License-Identifier: GPL-2.0
4a4d8108 19481+/*
b00004a5 19482+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
19483+ *
19484+ * This program, aufs is free software; you can redistribute it and/or modify
19485+ * it under the terms of the GNU General Public License as published by
19486+ * the Free Software Foundation; either version 2 of the License, or
19487+ * (at your option) any later version.
19488+ *
19489+ * This program is distributed in the hope that it will be useful,
19490+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19491+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19492+ * GNU General Public License for more details.
19493+ *
19494+ * You should have received a copy of the GNU General Public License
523b37e3 19495+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
19496+ */
19497+
19498+/*
19499+ * ioctl
19500+ * plink-management and readdir in userspace.
19501+ * assist the pathconf(3) wrapper library.
c2b27bf2 19502+ * move-down
076b876e 19503+ * File-based Hierarchical Storage Management.
4a4d8108
AM
19504+ */
19505+
c2b27bf2
AM
19506+#include <linux/compat.h>
19507+#include <linux/file.h>
4a4d8108
AM
19508+#include "aufs.h"
19509+
1e00d052 19510+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
19511+{
19512+ int err, fd;
5afbbe0d 19513+ aufs_bindex_t wbi, bindex, bbot;
4a4d8108
AM
19514+ struct file *h_file;
19515+ struct super_block *sb;
19516+ struct dentry *root;
1e00d052
AM
19517+ struct au_branch *br;
19518+ struct aufs_wbr_fd wbrfd = {
19519+ .oflags = au_dir_roflags,
19520+ .brid = -1
19521+ };
19522+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
19523+ | O_NOATIME | O_CLOEXEC;
4a4d8108 19524+
1e00d052
AM
19525+ AuDebugOn(wbrfd.oflags & ~valid);
19526+
19527+ if (arg) {
19528+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
19529+ if (unlikely(err)) {
19530+ err = -EFAULT;
19531+ goto out;
19532+ }
19533+
19534+ err = -EINVAL;
19535+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
19536+ wbrfd.oflags |= au_dir_roflags;
19537+ AuDbg("0%o\n", wbrfd.oflags);
19538+ if (unlikely(wbrfd.oflags & ~valid))
19539+ goto out;
19540+ }
19541+
2000de60 19542+ fd = get_unused_fd_flags(0);
1e00d052
AM
19543+ err = fd;
19544+ if (unlikely(fd < 0))
4a4d8108 19545+ goto out;
4a4d8108 19546+
1e00d052 19547+ h_file = ERR_PTR(-EINVAL);
4a4d8108 19548+ wbi = 0;
1e00d052 19549+ br = NULL;
4a4d8108
AM
19550+ sb = path->dentry->d_sb;
19551+ root = sb->s_root;
19552+ aufs_read_lock(root, AuLock_IR);
5afbbe0d 19553+ bbot = au_sbbot(sb);
1e00d052
AM
19554+ if (wbrfd.brid >= 0) {
19555+ wbi = au_br_index(sb, wbrfd.brid);
5afbbe0d 19556+ if (unlikely(wbi < 0 || wbi > bbot))
1e00d052
AM
19557+ goto out_unlock;
19558+ }
19559+
19560+ h_file = ERR_PTR(-ENOENT);
19561+ br = au_sbr(sb, wbi);
19562+ if (!au_br_writable(br->br_perm)) {
19563+ if (arg)
19564+ goto out_unlock;
19565+
19566+ bindex = wbi + 1;
19567+ wbi = -1;
5afbbe0d 19568+ for (; bindex <= bbot; bindex++) {
1e00d052
AM
19569+ br = au_sbr(sb, bindex);
19570+ if (au_br_writable(br->br_perm)) {
4a4d8108 19571+ wbi = bindex;
1e00d052 19572+ br = au_sbr(sb, wbi);
4a4d8108
AM
19573+ break;
19574+ }
19575+ }
4a4d8108
AM
19576+ }
19577+ AuDbg("wbi %d\n", wbi);
1e00d052 19578+ if (wbi >= 0)
392086de
AM
19579+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
19580+ /*force_wr*/0);
1e00d052
AM
19581+
19582+out_unlock:
4a4d8108
AM
19583+ aufs_read_unlock(root, AuLock_IR);
19584+ err = PTR_ERR(h_file);
19585+ if (IS_ERR(h_file))
19586+ goto out_fd;
19587+
acd2b654 19588+ au_lcnt_dec(&br->br_nfiles); /* cf. au_h_open() */
4a4d8108
AM
19589+ fd_install(fd, h_file);
19590+ err = fd;
19591+ goto out; /* success */
19592+
4f0767ce 19593+out_fd:
4a4d8108 19594+ put_unused_fd(fd);
4f0767ce 19595+out:
1e00d052 19596+ AuTraceErr(err);
4a4d8108
AM
19597+ return err;
19598+}
19599+
19600+/* ---------------------------------------------------------------------- */
19601+
19602+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
19603+{
19604+ long err;
c1595e42 19605+ struct dentry *dentry;
4a4d8108
AM
19606+
19607+ switch (cmd) {
4a4d8108
AM
19608+ case AUFS_CTL_RDU:
19609+ case AUFS_CTL_RDU_INO:
19610+ err = au_rdu_ioctl(file, cmd, arg);
19611+ break;
19612+
19613+ case AUFS_CTL_WBR_FD:
1e00d052 19614+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
19615+ break;
19616+
027c5e7a
AM
19617+ case AUFS_CTL_IBUSY:
19618+ err = au_ibusy_ioctl(file, arg);
19619+ break;
19620+
076b876e
AM
19621+ case AUFS_CTL_BRINFO:
19622+ err = au_brinfo_ioctl(file, arg);
19623+ break;
19624+
19625+ case AUFS_CTL_FHSM_FD:
2000de60 19626+ dentry = file->f_path.dentry;
c1595e42
JR
19627+ if (IS_ROOT(dentry))
19628+ err = au_fhsm_fd(dentry->d_sb, arg);
19629+ else
19630+ err = -ENOTTY;
076b876e
AM
19631+ break;
19632+
4a4d8108
AM
19633+ default:
19634+ /* do not call the lower */
19635+ AuDbg("0x%x\n", cmd);
19636+ err = -ENOTTY;
19637+ }
19638+
19639+ AuTraceErr(err);
19640+ return err;
19641+}
19642+
19643+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
19644+{
19645+ long err;
19646+
19647+ switch (cmd) {
c2b27bf2 19648+ case AUFS_CTL_MVDOWN:
2000de60 19649+ err = au_mvdown(file->f_path.dentry, (void __user *)arg);
c2b27bf2
AM
19650+ break;
19651+
4a4d8108 19652+ case AUFS_CTL_WBR_FD:
1e00d052 19653+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
19654+ break;
19655+
19656+ default:
19657+ /* do not call the lower */
19658+ AuDbg("0x%x\n", cmd);
19659+ err = -ENOTTY;
19660+ }
19661+
19662+ AuTraceErr(err);
19663+ return err;
19664+}
b752ccd1
AM
19665+
19666+#ifdef CONFIG_COMPAT
19667+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
19668+ unsigned long arg)
19669+{
19670+ long err;
19671+
19672+ switch (cmd) {
19673+ case AUFS_CTL_RDU:
19674+ case AUFS_CTL_RDU_INO:
19675+ err = au_rdu_compat_ioctl(file, cmd, arg);
19676+ break;
19677+
027c5e7a
AM
19678+ case AUFS_CTL_IBUSY:
19679+ err = au_ibusy_compat_ioctl(file, arg);
19680+ break;
19681+
076b876e
AM
19682+ case AUFS_CTL_BRINFO:
19683+ err = au_brinfo_compat_ioctl(file, arg);
19684+ break;
19685+
b752ccd1
AM
19686+ default:
19687+ err = aufs_ioctl_dir(file, cmd, arg);
19688+ }
19689+
19690+ AuTraceErr(err);
19691+ return err;
19692+}
19693+
b752ccd1
AM
19694+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
19695+ unsigned long arg)
19696+{
19697+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
19698+}
19699+#endif
7f207e10
AM
19700diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
19701--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
19702+++ linux/fs/aufs/i_op_add.c 2018-10-23 12:33:35.596042364 +0200
19703@@ -0,0 +1,935 @@
cd7a4cd9 19704+// SPDX-License-Identifier: GPL-2.0
4a4d8108 19705+/*
b00004a5 19706+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
19707+ *
19708+ * This program, aufs is free software; you can redistribute it and/or modify
19709+ * it under the terms of the GNU General Public License as published by
19710+ * the Free Software Foundation; either version 2 of the License, or
19711+ * (at your option) any later version.
19712+ *
19713+ * This program is distributed in the hope that it will be useful,
19714+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19715+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19716+ * GNU General Public License for more details.
19717+ *
19718+ * You should have received a copy of the GNU General Public License
523b37e3 19719+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
19720+ */
19721+
19722+/*
19723+ * inode operations (add entry)
19724+ */
19725+
19726+#include "aufs.h"
19727+
19728+/*
19729+ * final procedure of adding a new entry, except link(2).
19730+ * remove whiteout, instantiate, copyup the parent dir's times and size
19731+ * and update version.
19732+ * if it failed, re-create the removed whiteout.
19733+ */
19734+static int epilog(struct inode *dir, aufs_bindex_t bindex,
19735+ struct dentry *wh_dentry, struct dentry *dentry)
19736+{
19737+ int err, rerr;
19738+ aufs_bindex_t bwh;
19739+ struct path h_path;
076b876e 19740+ struct super_block *sb;
4a4d8108
AM
19741+ struct inode *inode, *h_dir;
19742+ struct dentry *wh;
19743+
19744+ bwh = -1;
076b876e 19745+ sb = dir->i_sb;
4a4d8108 19746+ if (wh_dentry) {
5527c038 19747+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
4a4d8108
AM
19748+ IMustLock(h_dir);
19749+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
19750+ bwh = au_dbwh(dentry);
19751+ h_path.dentry = wh_dentry;
076b876e 19752+ h_path.mnt = au_sbr_mnt(sb, bindex);
4a4d8108
AM
19753+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
19754+ dentry);
19755+ if (unlikely(err))
19756+ goto out;
19757+ }
19758+
19759+ inode = au_new_inode(dentry, /*must_new*/1);
19760+ if (!IS_ERR(inode)) {
19761+ d_instantiate(dentry, inode);
5527c038 19762+ dir = d_inode(dentry->d_parent); /* dir inode is locked */
4a4d8108 19763+ IMustLock(dir);
b912730e 19764+ au_dir_ts(dir, bindex);
be118d29 19765+ inode_inc_iversion(dir);
076b876e 19766+ au_fhsm_wrote(sb, bindex, /*force*/0);
4a4d8108
AM
19767+ return 0; /* success */
19768+ }
19769+
19770+ err = PTR_ERR(inode);
19771+ if (!wh_dentry)
19772+ goto out;
19773+
19774+ /* revert */
19775+ /* dir inode is locked */
19776+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
19777+ rerr = PTR_ERR(wh);
19778+ if (IS_ERR(wh)) {
523b37e3
AM
19779+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
19780+ dentry, err, rerr);
4a4d8108
AM
19781+ err = -EIO;
19782+ } else
19783+ dput(wh);
19784+
4f0767ce 19785+out:
4a4d8108
AM
19786+ return err;
19787+}
19788+
027c5e7a
AM
19789+static int au_d_may_add(struct dentry *dentry)
19790+{
19791+ int err;
19792+
19793+ err = 0;
19794+ if (unlikely(d_unhashed(dentry)))
19795+ err = -ENOENT;
5527c038 19796+ if (unlikely(d_really_is_positive(dentry)))
027c5e7a
AM
19797+ err = -EEXIST;
19798+ return err;
19799+}
19800+
4a4d8108
AM
19801+/*
19802+ * simple tests for the adding inode operations.
19803+ * following the checks in vfs, plus the parent-child relationship.
19804+ */
19805+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
19806+ struct dentry *h_parent, int isdir)
19807+{
19808+ int err;
19809+ umode_t h_mode;
19810+ struct dentry *h_dentry;
19811+ struct inode *h_inode;
19812+
19813+ err = -ENAMETOOLONG;
19814+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
19815+ goto out;
19816+
19817+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 19818+ if (d_really_is_negative(dentry)) {
4a4d8108 19819+ err = -EEXIST;
5527c038 19820+ if (unlikely(d_is_positive(h_dentry)))
4a4d8108
AM
19821+ goto out;
19822+ } else {
19823+ /* rename(2) case */
19824+ err = -EIO;
5527c038
JR
19825+ if (unlikely(d_is_negative(h_dentry)))
19826+ goto out;
19827+ h_inode = d_inode(h_dentry);
19828+ if (unlikely(!h_inode->i_nlink))
4a4d8108
AM
19829+ goto out;
19830+
19831+ h_mode = h_inode->i_mode;
19832+ if (!isdir) {
19833+ err = -EISDIR;
19834+ if (unlikely(S_ISDIR(h_mode)))
19835+ goto out;
19836+ } else if (unlikely(!S_ISDIR(h_mode))) {
19837+ err = -ENOTDIR;
19838+ goto out;
19839+ }
19840+ }
19841+
19842+ err = 0;
19843+ /* expected parent dir is locked */
19844+ if (unlikely(h_parent != h_dentry->d_parent))
19845+ err = -EIO;
19846+
4f0767ce 19847+out:
4a4d8108
AM
19848+ AuTraceErr(err);
19849+ return err;
19850+}
19851+
19852+/*
19853+ * initial procedure of adding a new entry.
19854+ * prepare writable branch and the parent dir, lock it,
19855+ * and lookup whiteout for the new entry.
19856+ */
19857+static struct dentry*
19858+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
19859+ struct dentry *src_dentry, struct au_pin *pin,
19860+ struct au_wr_dir_args *wr_dir_args)
19861+{
19862+ struct dentry *wh_dentry, *h_parent;
19863+ struct super_block *sb;
19864+ struct au_branch *br;
19865+ int err;
19866+ unsigned int udba;
19867+ aufs_bindex_t bcpup;
19868+
523b37e3 19869+ AuDbg("%pd\n", dentry);
4a4d8108
AM
19870+
19871+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
19872+ bcpup = err;
19873+ wh_dentry = ERR_PTR(err);
19874+ if (unlikely(err < 0))
19875+ goto out;
19876+
19877+ sb = dentry->d_sb;
19878+ udba = au_opt_udba(sb);
19879+ err = au_pin(pin, dentry, bcpup, udba,
19880+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
19881+ wh_dentry = ERR_PTR(err);
19882+ if (unlikely(err))
19883+ goto out;
19884+
19885+ h_parent = au_pinned_h_parent(pin);
19886+ if (udba != AuOpt_UDBA_NONE
5afbbe0d 19887+ && au_dbtop(dentry) == bcpup)
4a4d8108
AM
19888+ err = au_may_add(dentry, bcpup, h_parent,
19889+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
19890+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
19891+ err = -ENAMETOOLONG;
19892+ wh_dentry = ERR_PTR(err);
19893+ if (unlikely(err))
19894+ goto out_unpin;
19895+
19896+ br = au_sbr(sb, bcpup);
19897+ if (dt) {
19898+ struct path tmp = {
19899+ .dentry = h_parent,
86dc4139 19900+ .mnt = au_br_mnt(br)
4a4d8108
AM
19901+ };
19902+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
19903+ }
19904+
19905+ wh_dentry = NULL;
19906+ if (bcpup != au_dbwh(dentry))
19907+ goto out; /* success */
19908+
2000de60
JR
19909+ /*
19910+ * ENAMETOOLONG here means that if we allowed create such name, then it
19911+ * would not be able to removed in the future. So we don't allow such
19912+ * name here and we don't handle ENAMETOOLONG differently here.
19913+ */
4a4d8108
AM
19914+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
19915+
4f0767ce 19916+out_unpin:
4a4d8108
AM
19917+ if (IS_ERR(wh_dentry))
19918+ au_unpin(pin);
4f0767ce 19919+out:
4a4d8108
AM
19920+ return wh_dentry;
19921+}
19922+
19923+/* ---------------------------------------------------------------------- */
19924+
19925+enum { Mknod, Symlink, Creat };
19926+struct simple_arg {
19927+ int type;
19928+ union {
19929+ struct {
b912730e
AM
19930+ umode_t mode;
19931+ bool want_excl;
19932+ bool try_aopen;
19933+ struct vfsub_aopen_args *aopen;
4a4d8108
AM
19934+ } c;
19935+ struct {
19936+ const char *symname;
19937+ } s;
19938+ struct {
7eafdf33 19939+ umode_t mode;
4a4d8108
AM
19940+ dev_t dev;
19941+ } m;
19942+ } u;
19943+};
19944+
19945+static int add_simple(struct inode *dir, struct dentry *dentry,
19946+ struct simple_arg *arg)
19947+{
076b876e 19948+ int err, rerr;
5afbbe0d 19949+ aufs_bindex_t btop;
4a4d8108 19950+ unsigned char created;
b912730e
AM
19951+ const unsigned char try_aopen
19952+ = (arg->type == Creat && arg->u.c.try_aopen);
acd2b654 19953+ struct vfsub_aopen_args *aopen = arg->u.c.aopen;
4a4d8108
AM
19954+ struct dentry *wh_dentry, *parent;
19955+ struct inode *h_dir;
b912730e
AM
19956+ struct super_block *sb;
19957+ struct au_branch *br;
acd2b654 19958+ /* to reduce stack size */
c2b27bf2
AM
19959+ struct {
19960+ struct au_dtime dt;
19961+ struct au_pin pin;
19962+ struct path h_path;
19963+ struct au_wr_dir_args wr_dir_args;
19964+ } *a;
4a4d8108 19965+
523b37e3 19966+ AuDbg("%pd\n", dentry);
4a4d8108
AM
19967+ IMustLock(dir);
19968+
c2b27bf2
AM
19969+ err = -ENOMEM;
19970+ a = kmalloc(sizeof(*a), GFP_NOFS);
19971+ if (unlikely(!a))
19972+ goto out;
19973+ a->wr_dir_args.force_btgt = -1;
19974+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
19975+
4a4d8108 19976+ parent = dentry->d_parent; /* dir inode is locked */
b912730e
AM
19977+ if (!try_aopen) {
19978+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
19979+ if (unlikely(err))
19980+ goto out_free;
19981+ }
027c5e7a
AM
19982+ err = au_d_may_add(dentry);
19983+ if (unlikely(err))
19984+ goto out_unlock;
b912730e
AM
19985+ if (!try_aopen)
19986+ di_write_lock_parent(parent);
c2b27bf2
AM
19987+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
19988+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
19989+ err = PTR_ERR(wh_dentry);
19990+ if (IS_ERR(wh_dentry))
027c5e7a 19991+ goto out_parent;
4a4d8108 19992+
5afbbe0d 19993+ btop = au_dbtop(dentry);
b912730e 19994+ sb = dentry->d_sb;
5afbbe0d
AM
19995+ br = au_sbr(sb, btop);
19996+ a->h_path.dentry = au_h_dptr(dentry, btop);
b912730e 19997+ a->h_path.mnt = au_br_mnt(br);
c2b27bf2 19998+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
19999+ switch (arg->type) {
20000+ case Creat:
acd2b654 20001+ if (!try_aopen || !h_dir->i_op->atomic_open) {
b912730e
AM
20002+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
20003+ arg->u.c.want_excl);
acd2b654
AM
20004+ created = !err;
20005+ if (!err && try_aopen)
20006+ aopen->file->f_mode |= FMODE_CREATED;
20007+ } else {
20008+ aopen->br = br;
20009+ err = vfsub_atomic_open(h_dir, a->h_path.dentry, aopen);
20010+ AuDbg("err %d\n", err);
20011+ AuDbgFile(aopen->file);
20012+ created = err >= 0
20013+ && !!(aopen->file->f_mode & FMODE_CREATED);
20014+ }
4a4d8108
AM
20015+ break;
20016+ case Symlink:
c2b27bf2 20017+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
acd2b654 20018+ created = !err;
4a4d8108
AM
20019+ break;
20020+ case Mknod:
c2b27bf2
AM
20021+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
20022+ arg->u.m.dev);
acd2b654 20023+ created = !err;
4a4d8108
AM
20024+ break;
20025+ default:
20026+ BUG();
20027+ }
acd2b654
AM
20028+ if (unlikely(err < 0))
20029+ goto out_unpin;
20030+
20031+ err = epilog(dir, btop, wh_dentry, dentry);
4a4d8108 20032+ if (!err)
acd2b654 20033+ goto out_unpin; /* success */
4a4d8108
AM
20034+
20035+ /* revert */
acd2b654 20036+ if (created /* && d_is_positive(a->h_path.dentry) */) {
523b37e3
AM
20037+ /* no delegation since it is just created */
20038+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
20039+ /*force*/0);
4a4d8108 20040+ if (rerr) {
523b37e3
AM
20041+ AuIOErr("%pd revert failure(%d, %d)\n",
20042+ dentry, err, rerr);
4a4d8108
AM
20043+ err = -EIO;
20044+ }
c2b27bf2 20045+ au_dtime_revert(&a->dt);
4a4d8108 20046+ }
acd2b654
AM
20047+ if (try_aopen && h_dir->i_op->atomic_open
20048+ && (aopen->file->f_mode & FMODE_OPENED))
20049+ /* aopen->file is still opened */
20050+ au_lcnt_dec(&aopen->br->br_nfiles);
4a4d8108 20051+
acd2b654 20052+out_unpin:
c2b27bf2 20053+ au_unpin(&a->pin);
4a4d8108 20054+ dput(wh_dentry);
027c5e7a 20055+out_parent:
b912730e
AM
20056+ if (!try_aopen)
20057+ di_write_unlock(parent);
027c5e7a 20058+out_unlock:
4a4d8108 20059+ if (unlikely(err)) {
5afbbe0d 20060+ au_update_dbtop(dentry);
4a4d8108
AM
20061+ d_drop(dentry);
20062+ }
b912730e
AM
20063+ if (!try_aopen)
20064+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 20065+out_free:
1c60b727 20066+ kfree(a);
027c5e7a 20067+out:
4a4d8108
AM
20068+ return err;
20069+}
20070+
7eafdf33
AM
20071+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
20072+ dev_t dev)
4a4d8108
AM
20073+{
20074+ struct simple_arg arg = {
20075+ .type = Mknod,
20076+ .u.m = {
20077+ .mode = mode,
20078+ .dev = dev
20079+ }
20080+ };
20081+ return add_simple(dir, dentry, &arg);
20082+}
20083+
20084+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
20085+{
20086+ struct simple_arg arg = {
20087+ .type = Symlink,
20088+ .u.s.symname = symname
20089+ };
20090+ return add_simple(dir, dentry, &arg);
20091+}
20092+
7eafdf33 20093+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 20094+ bool want_excl)
4a4d8108
AM
20095+{
20096+ struct simple_arg arg = {
20097+ .type = Creat,
20098+ .u.c = {
b4510431
AM
20099+ .mode = mode,
20100+ .want_excl = want_excl
4a4d8108
AM
20101+ }
20102+ };
20103+ return add_simple(dir, dentry, &arg);
20104+}
20105+
b912730e
AM
20106+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
20107+ struct vfsub_aopen_args *aopen_args)
20108+{
20109+ struct simple_arg arg = {
20110+ .type = Creat,
20111+ .u.c = {
20112+ .mode = aopen_args->create_mode,
20113+ .want_excl = aopen_args->open_flag & O_EXCL,
20114+ .try_aopen = true,
20115+ .aopen = aopen_args
20116+ }
20117+ };
20118+ return add_simple(dir, dentry, &arg);
20119+}
20120+
38d290e6
JR
20121+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
20122+{
20123+ int err;
20124+ aufs_bindex_t bindex;
20125+ struct super_block *sb;
20126+ struct dentry *parent, *h_parent, *h_dentry;
20127+ struct inode *h_dir, *inode;
20128+ struct vfsmount *h_mnt;
20129+ struct au_wr_dir_args wr_dir_args = {
20130+ .force_btgt = -1,
20131+ .flags = AuWrDir_TMPFILE
20132+ };
20133+
20134+ /* copy-up may happen */
febd17d6 20135+ inode_lock(dir);
38d290e6
JR
20136+
20137+ sb = dir->i_sb;
20138+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
20139+ if (unlikely(err))
20140+ goto out;
20141+
20142+ err = au_di_init(dentry);
20143+ if (unlikely(err))
20144+ goto out_si;
20145+
20146+ err = -EBUSY;
20147+ parent = d_find_any_alias(dir);
20148+ AuDebugOn(!parent);
20149+ di_write_lock_parent(parent);
5527c038 20150+ if (unlikely(d_inode(parent) != dir))
38d290e6
JR
20151+ goto out_parent;
20152+
20153+ err = au_digen_test(parent, au_sigen(sb));
20154+ if (unlikely(err))
20155+ goto out_parent;
20156+
5afbbe0d
AM
20157+ bindex = au_dbtop(parent);
20158+ au_set_dbtop(dentry, bindex);
20159+ au_set_dbbot(dentry, bindex);
38d290e6
JR
20160+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
20161+ bindex = err;
20162+ if (unlikely(err < 0))
20163+ goto out_parent;
20164+
20165+ err = -EOPNOTSUPP;
20166+ h_dir = au_h_iptr(dir, bindex);
20167+ if (unlikely(!h_dir->i_op->tmpfile))
20168+ goto out_parent;
20169+
20170+ h_mnt = au_sbr_mnt(sb, bindex);
20171+ err = vfsub_mnt_want_write(h_mnt);
20172+ if (unlikely(err))
20173+ goto out_parent;
20174+
20175+ h_parent = au_h_dptr(parent, bindex);
521ced18
JR
20176+ h_dentry = vfs_tmpfile(h_parent, mode, /*open_flag*/0);
20177+ if (IS_ERR(h_dentry)) {
20178+ err = PTR_ERR(h_dentry);
38d290e6 20179+ goto out_mnt;
521ced18 20180+ }
38d290e6 20181+
5afbbe0d
AM
20182+ au_set_dbtop(dentry, bindex);
20183+ au_set_dbbot(dentry, bindex);
38d290e6
JR
20184+ au_set_h_dptr(dentry, bindex, dget(h_dentry));
20185+ inode = au_new_inode(dentry, /*must_new*/1);
20186+ if (IS_ERR(inode)) {
20187+ err = PTR_ERR(inode);
20188+ au_set_h_dptr(dentry, bindex, NULL);
5afbbe0d
AM
20189+ au_set_dbtop(dentry, -1);
20190+ au_set_dbbot(dentry, -1);
38d290e6
JR
20191+ } else {
20192+ if (!inode->i_nlink)
20193+ set_nlink(inode, 1);
20194+ d_tmpfile(dentry, inode);
20195+ au_di(dentry)->di_tmpfile = 1;
20196+
20197+ /* update without i_mutex */
5afbbe0d 20198+ if (au_ibtop(dir) == au_dbtop(dentry))
38d290e6
JR
20199+ au_cpup_attr_timesizes(dir);
20200+ }
38d290e6 20201+ dput(h_dentry);
521ced18 20202+
38d290e6
JR
20203+out_mnt:
20204+ vfsub_mnt_drop_write(h_mnt);
20205+out_parent:
20206+ di_write_unlock(parent);
20207+ dput(parent);
20208+ di_write_unlock(dentry);
5afbbe0d 20209+ if (unlikely(err)) {
38d290e6
JR
20210+ au_di_fin(dentry);
20211+ dentry->d_fsdata = NULL;
20212+ }
20213+out_si:
20214+ si_read_unlock(sb);
20215+out:
febd17d6 20216+ inode_unlock(dir);
38d290e6
JR
20217+ return err;
20218+}
20219+
4a4d8108
AM
20220+/* ---------------------------------------------------------------------- */
20221+
20222+struct au_link_args {
20223+ aufs_bindex_t bdst, bsrc;
20224+ struct au_pin pin;
20225+ struct path h_path;
20226+ struct dentry *src_parent, *parent;
20227+};
20228+
20229+static int au_cpup_before_link(struct dentry *src_dentry,
20230+ struct au_link_args *a)
20231+{
20232+ int err;
20233+ struct dentry *h_src_dentry;
c2b27bf2
AM
20234+ struct au_cp_generic cpg = {
20235+ .dentry = src_dentry,
20236+ .bdst = a->bdst,
20237+ .bsrc = a->bsrc,
20238+ .len = -1,
20239+ .pin = &a->pin,
20240+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
20241+ };
4a4d8108
AM
20242+
20243+ di_read_lock_parent(a->src_parent, AuLock_IR);
20244+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
20245+ if (unlikely(err))
20246+ goto out;
20247+
20248+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
20249+ err = au_pin(&a->pin, src_dentry, a->bdst,
20250+ au_opt_udba(src_dentry->d_sb),
20251+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
20252+ if (unlikely(err))
20253+ goto out;
367653fa 20254+
c2b27bf2 20255+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
20256+ au_unpin(&a->pin);
20257+
4f0767ce 20258+out:
4a4d8108
AM
20259+ di_read_unlock(a->src_parent, AuLock_IR);
20260+ return err;
20261+}
20262+
86dc4139
AM
20263+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
20264+ struct au_link_args *a)
4a4d8108
AM
20265+{
20266+ int err;
20267+ unsigned char plink;
5afbbe0d 20268+ aufs_bindex_t bbot;
4a4d8108 20269+ struct dentry *h_src_dentry;
523b37e3 20270+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
20271+ struct super_block *sb;
20272+ struct file *h_file;
20273+
20274+ plink = 0;
20275+ h_inode = NULL;
20276+ sb = src_dentry->d_sb;
5527c038 20277+ inode = d_inode(src_dentry);
5afbbe0d 20278+ if (au_ibtop(inode) <= a->bdst)
4a4d8108
AM
20279+ h_inode = au_h_iptr(inode, a->bdst);
20280+ if (!h_inode || !h_inode->i_nlink) {
20281+ /* copyup src_dentry as the name of dentry. */
5afbbe0d
AM
20282+ bbot = au_dbbot(dentry);
20283+ if (bbot < a->bsrc)
20284+ au_set_dbbot(dentry, a->bsrc);
86dc4139
AM
20285+ au_set_h_dptr(dentry, a->bsrc,
20286+ dget(au_h_dptr(src_dentry, a->bsrc)));
20287+ dget(a->h_path.dentry);
20288+ au_set_h_dptr(dentry, a->bdst, NULL);
c1595e42
JR
20289+ AuDbg("temporary d_inode...\n");
20290+ spin_lock(&dentry->d_lock);
5527c038 20291+ dentry->d_inode = d_inode(src_dentry); /* tmp */
c1595e42 20292+ spin_unlock(&dentry->d_lock);
392086de 20293+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 20294+ if (IS_ERR(h_file))
4a4d8108 20295+ err = PTR_ERR(h_file);
86dc4139 20296+ else {
c2b27bf2
AM
20297+ struct au_cp_generic cpg = {
20298+ .dentry = dentry,
20299+ .bdst = a->bdst,
20300+ .bsrc = -1,
20301+ .len = -1,
20302+ .pin = &a->pin,
20303+ .flags = AuCpup_KEEPLINO
20304+ };
20305+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
20306+ au_h_open_post(dentry, a->bsrc, h_file);
20307+ if (!err) {
20308+ dput(a->h_path.dentry);
20309+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
20310+ } else
20311+ au_set_h_dptr(dentry, a->bdst,
20312+ a->h_path.dentry);
20313+ }
c1595e42 20314+ spin_lock(&dentry->d_lock);
86dc4139 20315+ dentry->d_inode = NULL; /* restore */
c1595e42
JR
20316+ spin_unlock(&dentry->d_lock);
20317+ AuDbg("temporary d_inode...done\n");
86dc4139 20318+ au_set_h_dptr(dentry, a->bsrc, NULL);
5afbbe0d 20319+ au_set_dbbot(dentry, bbot);
4a4d8108
AM
20320+ } else {
20321+ /* the inode of src_dentry already exists on a.bdst branch */
20322+ h_src_dentry = d_find_alias(h_inode);
20323+ if (!h_src_dentry && au_plink_test(inode)) {
20324+ plink = 1;
20325+ h_src_dentry = au_plink_lkup(inode, a->bdst);
20326+ err = PTR_ERR(h_src_dentry);
20327+ if (IS_ERR(h_src_dentry))
20328+ goto out;
20329+
5527c038 20330+ if (unlikely(d_is_negative(h_src_dentry))) {
4a4d8108
AM
20331+ dput(h_src_dentry);
20332+ h_src_dentry = NULL;
20333+ }
20334+
20335+ }
20336+ if (h_src_dentry) {
523b37e3 20337+ delegated = NULL;
4a4d8108 20338+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
20339+ &a->h_path, &delegated);
20340+ if (unlikely(err == -EWOULDBLOCK)) {
20341+ pr_warn("cannot retry for NFSv4 delegation"
20342+ " for an internal link\n");
20343+ iput(delegated);
20344+ }
4a4d8108
AM
20345+ dput(h_src_dentry);
20346+ } else {
20347+ AuIOErr("no dentry found for hi%lu on b%d\n",
20348+ h_inode->i_ino, a->bdst);
20349+ err = -EIO;
20350+ }
20351+ }
20352+
20353+ if (!err && !plink)
20354+ au_plink_append(inode, a->bdst, a->h_path.dentry);
20355+
20356+out:
2cbb1c4b 20357+ AuTraceErr(err);
4a4d8108
AM
20358+ return err;
20359+}
20360+
20361+int aufs_link(struct dentry *src_dentry, struct inode *dir,
20362+ struct dentry *dentry)
20363+{
20364+ int err, rerr;
20365+ struct au_dtime dt;
20366+ struct au_link_args *a;
20367+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 20368+ struct inode *inode, *delegated;
4a4d8108
AM
20369+ struct super_block *sb;
20370+ struct au_wr_dir_args wr_dir_args = {
20371+ /* .force_btgt = -1, */
20372+ .flags = AuWrDir_ADD_ENTRY
20373+ };
20374+
20375+ IMustLock(dir);
5527c038 20376+ inode = d_inode(src_dentry);
4a4d8108
AM
20377+ IMustLock(inode);
20378+
4a4d8108
AM
20379+ err = -ENOMEM;
20380+ a = kzalloc(sizeof(*a), GFP_NOFS);
20381+ if (unlikely(!a))
20382+ goto out;
20383+
20384+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
20385+ err = aufs_read_and_write_lock2(dentry, src_dentry,
20386+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
20387+ if (unlikely(err))
20388+ goto out_kfree;
38d290e6 20389+ err = au_d_linkable(src_dentry);
027c5e7a
AM
20390+ if (unlikely(err))
20391+ goto out_unlock;
20392+ err = au_d_may_add(dentry);
20393+ if (unlikely(err))
20394+ goto out_unlock;
e49829fe 20395+
4a4d8108 20396+ a->src_parent = dget_parent(src_dentry);
5afbbe0d 20397+ wr_dir_args.force_btgt = au_ibtop(inode);
4a4d8108
AM
20398+
20399+ di_write_lock_parent(a->parent);
20400+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
20401+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
20402+ &wr_dir_args);
20403+ err = PTR_ERR(wh_dentry);
20404+ if (IS_ERR(wh_dentry))
027c5e7a 20405+ goto out_parent;
4a4d8108
AM
20406+
20407+ err = 0;
20408+ sb = dentry->d_sb;
5afbbe0d 20409+ a->bdst = au_dbtop(dentry);
4a4d8108
AM
20410+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
20411+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
5afbbe0d 20412+ a->bsrc = au_ibtop(inode);
2cbb1c4b 20413+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
38d290e6
JR
20414+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
20415+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
2cbb1c4b 20416+ if (!h_src_dentry) {
5afbbe0d 20417+ a->bsrc = au_dbtop(src_dentry);
2cbb1c4b
JR
20418+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
20419+ AuDebugOn(!h_src_dentry);
38d290e6
JR
20420+ } else if (IS_ERR(h_src_dentry)) {
20421+ err = PTR_ERR(h_src_dentry);
2cbb1c4b 20422+ goto out_parent;
38d290e6 20423+ }
2cbb1c4b 20424+
f2c43d5f
AM
20425+ /*
20426+ * aufs doesn't touch the credential so
acd2b654 20427+ * security_dentry_create_files_as() is unnecessary.
f2c43d5f 20428+ */
4a4d8108
AM
20429+ if (au_opt_test(au_mntflags(sb), PLINK)) {
20430+ if (a->bdst < a->bsrc
20431+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 20432+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
20433+ else {
20434+ delegated = NULL;
4a4d8108 20435+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
20436+ &a->h_path, &delegated);
20437+ if (unlikely(err == -EWOULDBLOCK)) {
20438+ pr_warn("cannot retry for NFSv4 delegation"
20439+ " for an internal link\n");
20440+ iput(delegated);
20441+ }
20442+ }
2cbb1c4b 20443+ dput(h_src_dentry);
4a4d8108
AM
20444+ } else {
20445+ /*
20446+ * copyup src_dentry to the branch we process,
20447+ * and then link(2) to it.
20448+ */
2cbb1c4b 20449+ dput(h_src_dentry);
4a4d8108
AM
20450+ if (a->bdst < a->bsrc
20451+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
20452+ au_unpin(&a->pin);
20453+ di_write_unlock(a->parent);
20454+ err = au_cpup_before_link(src_dentry, a);
20455+ di_write_lock_parent(a->parent);
20456+ if (!err)
20457+ err = au_pin(&a->pin, dentry, a->bdst,
20458+ au_opt_udba(sb),
20459+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
20460+ if (unlikely(err))
20461+ goto out_wh;
20462+ }
20463+ if (!err) {
20464+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
20465+ err = -ENOENT;
5527c038 20466+ if (h_src_dentry && d_is_positive(h_src_dentry)) {
523b37e3 20467+ delegated = NULL;
4a4d8108
AM
20468+ err = vfsub_link(h_src_dentry,
20469+ au_pinned_h_dir(&a->pin),
523b37e3
AM
20470+ &a->h_path, &delegated);
20471+ if (unlikely(err == -EWOULDBLOCK)) {
20472+ pr_warn("cannot retry"
20473+ " for NFSv4 delegation"
20474+ " for an internal link\n");
20475+ iput(delegated);
20476+ }
20477+ }
4a4d8108
AM
20478+ }
20479+ }
20480+ if (unlikely(err))
20481+ goto out_unpin;
20482+
20483+ if (wh_dentry) {
20484+ a->h_path.dentry = wh_dentry;
20485+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
20486+ dentry);
20487+ if (unlikely(err))
20488+ goto out_revert;
20489+ }
20490+
b912730e 20491+ au_dir_ts(dir, a->bdst);
be118d29 20492+ inode_inc_iversion(dir);
4a4d8108
AM
20493+ inc_nlink(inode);
20494+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
20495+ d_instantiate(dentry, au_igrab(inode));
20496+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
20497+ /* some filesystem calls d_drop() */
20498+ d_drop(dentry);
076b876e
AM
20499+ /* some filesystems consume an inode even hardlink */
20500+ au_fhsm_wrote(sb, a->bdst, /*force*/0);
4a4d8108
AM
20501+ goto out_unpin; /* success */
20502+
4f0767ce 20503+out_revert:
523b37e3
AM
20504+ /* no delegation since it is just created */
20505+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
20506+ /*delegated*/NULL, /*force*/0);
027c5e7a 20507+ if (unlikely(rerr)) {
523b37e3 20508+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
20509+ err = -EIO;
20510+ }
4a4d8108 20511+ au_dtime_revert(&dt);
4f0767ce 20512+out_unpin:
4a4d8108 20513+ au_unpin(&a->pin);
4f0767ce 20514+out_wh:
4a4d8108 20515+ dput(wh_dentry);
027c5e7a
AM
20516+out_parent:
20517+ di_write_unlock(a->parent);
20518+ dput(a->src_parent);
4f0767ce 20519+out_unlock:
4a4d8108 20520+ if (unlikely(err)) {
5afbbe0d 20521+ au_update_dbtop(dentry);
4a4d8108
AM
20522+ d_drop(dentry);
20523+ }
4a4d8108 20524+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 20525+out_kfree:
1c60b727 20526+ kfree(a);
4f0767ce 20527+out:
86dc4139 20528+ AuTraceErr(err);
4a4d8108
AM
20529+ return err;
20530+}
20531+
7eafdf33 20532+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
20533+{
20534+ int err, rerr;
20535+ aufs_bindex_t bindex;
20536+ unsigned char diropq;
20537+ struct path h_path;
20538+ struct dentry *wh_dentry, *parent, *opq_dentry;
febd17d6 20539+ struct inode *h_inode;
4a4d8108
AM
20540+ struct super_block *sb;
20541+ struct {
20542+ struct au_pin pin;
20543+ struct au_dtime dt;
20544+ } *a; /* reduce the stack usage */
20545+ struct au_wr_dir_args wr_dir_args = {
20546+ .force_btgt = -1,
20547+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
20548+ };
20549+
20550+ IMustLock(dir);
20551+
20552+ err = -ENOMEM;
20553+ a = kmalloc(sizeof(*a), GFP_NOFS);
20554+ if (unlikely(!a))
20555+ goto out;
20556+
027c5e7a
AM
20557+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
20558+ if (unlikely(err))
20559+ goto out_free;
20560+ err = au_d_may_add(dentry);
20561+ if (unlikely(err))
20562+ goto out_unlock;
20563+
4a4d8108
AM
20564+ parent = dentry->d_parent; /* dir inode is locked */
20565+ di_write_lock_parent(parent);
20566+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
20567+ &a->pin, &wr_dir_args);
20568+ err = PTR_ERR(wh_dentry);
20569+ if (IS_ERR(wh_dentry))
027c5e7a 20570+ goto out_parent;
4a4d8108
AM
20571+
20572+ sb = dentry->d_sb;
5afbbe0d 20573+ bindex = au_dbtop(dentry);
4a4d8108
AM
20574+ h_path.dentry = au_h_dptr(dentry, bindex);
20575+ h_path.mnt = au_sbr_mnt(sb, bindex);
20576+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
20577+ if (unlikely(err))
027c5e7a 20578+ goto out_unpin;
4a4d8108
AM
20579+
20580+ /* make the dir opaque */
20581+ diropq = 0;
febd17d6 20582+ h_inode = d_inode(h_path.dentry);
4a4d8108
AM
20583+ if (wh_dentry
20584+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
febd17d6 20585+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 20586+ opq_dentry = au_diropq_create(dentry, bindex);
febd17d6 20587+ inode_unlock(h_inode);
4a4d8108
AM
20588+ err = PTR_ERR(opq_dentry);
20589+ if (IS_ERR(opq_dentry))
20590+ goto out_dir;
20591+ dput(opq_dentry);
20592+ diropq = 1;
20593+ }
20594+
20595+ err = epilog(dir, bindex, wh_dentry, dentry);
20596+ if (!err) {
20597+ inc_nlink(dir);
027c5e7a 20598+ goto out_unpin; /* success */
4a4d8108
AM
20599+ }
20600+
20601+ /* revert */
20602+ if (diropq) {
20603+ AuLabel(revert opq);
febd17d6 20604+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 20605+ rerr = au_diropq_remove(dentry, bindex);
febd17d6 20606+ inode_unlock(h_inode);
4a4d8108 20607+ if (rerr) {
523b37e3
AM
20608+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
20609+ dentry, err, rerr);
4a4d8108
AM
20610+ err = -EIO;
20611+ }
20612+ }
20613+
4f0767ce 20614+out_dir:
4a4d8108
AM
20615+ AuLabel(revert dir);
20616+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
20617+ if (rerr) {
523b37e3
AM
20618+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
20619+ dentry, err, rerr);
4a4d8108
AM
20620+ err = -EIO;
20621+ }
4a4d8108 20622+ au_dtime_revert(&a->dt);
027c5e7a 20623+out_unpin:
4a4d8108
AM
20624+ au_unpin(&a->pin);
20625+ dput(wh_dentry);
027c5e7a
AM
20626+out_parent:
20627+ di_write_unlock(parent);
20628+out_unlock:
4a4d8108 20629+ if (unlikely(err)) {
5afbbe0d 20630+ au_update_dbtop(dentry);
4a4d8108
AM
20631+ d_drop(dentry);
20632+ }
4a4d8108 20633+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 20634+out_free:
1c60b727 20635+ kfree(a);
4f0767ce 20636+out:
4a4d8108
AM
20637+ return err;
20638+}
7f207e10
AM
20639diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
20640--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
20641+++ linux/fs/aufs/i_op.c 2018-10-23 12:33:35.596042364 +0200
20642@@ -0,0 +1,1506 @@
cd7a4cd9 20643+// SPDX-License-Identifier: GPL-2.0
4a4d8108 20644+/*
b00004a5 20645+ * Copyright (C) 2005-2018 Junjiro R. Okajima
4a4d8108
AM
20646+ *
20647+ * This program, aufs is free software; you can redistribute it and/or modify
20648+ * it under the terms of the GNU General Public License as published by
20649+ * the Free Software Foundation; either version 2 of the License, or
20650+ * (at your option) any later version.
20651+ *
20652+ * This program is distributed in the hope that it will be useful,
20653+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20654+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20655+ * GNU General Public License for more details.
20656+ *
20657+ * You should have received a copy of the GNU General Public License
523b37e3 20658+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 20659+ */
1facf9fc 20660+
1308ab2a 20661+/*
4a4d8108 20662+ * inode operations (except add/del/rename)
1308ab2a 20663+ */
4a4d8108
AM
20664+
20665+#include <linux/device_cgroup.h>
20666+#include <linux/fs_stack.h>
4a4d8108
AM
20667+#include <linux/namei.h>
20668+#include <linux/security.h>
4a4d8108
AM
20669+#include "aufs.h"
20670+
1e00d052 20671+static int h_permission(struct inode *h_inode, int mask,
79b8bda9 20672+ struct path *h_path, int brperm)
1facf9fc 20673+{
1308ab2a 20674+ int err;
4a4d8108 20675+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 20676+
e2f27e51
AM
20677+ err = -EPERM;
20678+ if (write_mask && IS_IMMUTABLE(h_inode))
20679+ goto out;
20680+
4a4d8108 20681+ err = -EACCES;
e2f27e51
AM
20682+ if (((mask & MAY_EXEC)
20683+ && S_ISREG(h_inode->i_mode)
20684+ && (path_noexec(h_path)
cd7a4cd9 20685+ || !(h_inode->i_mode & 0111))))
4a4d8108
AM
20686+ goto out;
20687+
20688+ /*
20689+ * - skip the lower fs test in the case of write to ro branch.
20690+ * - nfs dir permission write check is optimized, but a policy for
20691+ * link/rename requires a real check.
2121bcd9 20692+ * - nfs always sets SB_POSIXACL regardless its mount option 'noacl.'
b912730e 20693+ * in this case, generic_permission() returns -EOPNOTSUPP.
4a4d8108
AM
20694+ */
20695+ if ((write_mask && !au_br_writable(brperm))
20696+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
20697+ && write_mask && !(mask & MAY_READ))
20698+ || !h_inode->i_op->permission) {
20699+ /* AuLabel(generic_permission); */
062440b3 20700+ /* AuDbg("get_acl %ps\n", h_inode->i_op->get_acl); */
1e00d052 20701+ err = generic_permission(h_inode, mask);
b912730e
AM
20702+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode))
20703+ err = h_inode->i_op->permission(h_inode, mask);
20704+ AuTraceErr(err);
1308ab2a 20705+ } else {
4a4d8108 20706+ /* AuLabel(h_inode->permission); */
1e00d052 20707+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
20708+ AuTraceErr(err);
20709+ }
1facf9fc 20710+
4a4d8108
AM
20711+ if (!err)
20712+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 20713+ if (!err)
4a4d8108 20714+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
20715+
20716+#if 0
20717+ if (!err) {
20718+ /* todo: do we need to call ima_path_check()? */
20719+ struct path h_path = {
20720+ .dentry =
20721+ .mnt = h_mnt
20722+ };
20723+ err = ima_path_check(&h_path,
20724+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
20725+ IMA_COUNT_LEAVE);
1308ab2a 20726+ }
4a4d8108 20727+#endif
dece6358 20728+
4f0767ce 20729+out:
1308ab2a 20730+ return err;
20731+}
dece6358 20732+
1e00d052 20733+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 20734+{
20735+ int err;
5afbbe0d 20736+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
20737+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
20738+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
20739+ struct inode *h_inode;
20740+ struct super_block *sb;
20741+ struct au_branch *br;
1facf9fc 20742+
027c5e7a 20743+ /* todo: support rcu-walk? */
1e00d052 20744+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
20745+ return -ECHILD;
20746+
4a4d8108
AM
20747+ sb = inode->i_sb;
20748+ si_read_lock(sb, AuLock_FLUSH);
20749+ ii_read_lock_child(inode);
027c5e7a
AM
20750+#if 0
20751+ err = au_iigen_test(inode, au_sigen(sb));
20752+ if (unlikely(err))
20753+ goto out;
20754+#endif
dece6358 20755+
076b876e
AM
20756+ if (!isdir
20757+ || write_mask
20758+ || au_opt_test(au_mntflags(sb), DIRPERM1)) {
4a4d8108 20759+ err = au_busy_or_stale();
5afbbe0d 20760+ h_inode = au_h_iptr(inode, au_ibtop(inode));
4a4d8108
AM
20761+ if (unlikely(!h_inode
20762+ || (h_inode->i_mode & S_IFMT)
20763+ != (inode->i_mode & S_IFMT)))
20764+ goto out;
1facf9fc 20765+
4a4d8108 20766+ err = 0;
5afbbe0d 20767+ bindex = au_ibtop(inode);
4a4d8108 20768+ br = au_sbr(sb, bindex);
79b8bda9 20769+ err = h_permission(h_inode, mask, &br->br_path, br->br_perm);
4a4d8108
AM
20770+ if (write_mask
20771+ && !err
20772+ && !special_file(h_inode->i_mode)) {
20773+ /* test whether the upper writable branch exists */
20774+ err = -EROFS;
20775+ for (; bindex >= 0; bindex--)
20776+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
20777+ err = 0;
20778+ break;
20779+ }
20780+ }
20781+ goto out;
20782+ }
dece6358 20783+
4a4d8108 20784+ /* non-write to dir */
1308ab2a 20785+ err = 0;
5afbbe0d
AM
20786+ bbot = au_ibbot(inode);
20787+ for (bindex = au_ibtop(inode); !err && bindex <= bbot; bindex++) {
4a4d8108
AM
20788+ h_inode = au_h_iptr(inode, bindex);
20789+ if (h_inode) {
20790+ err = au_busy_or_stale();
20791+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
20792+ break;
20793+
20794+ br = au_sbr(sb, bindex);
79b8bda9 20795+ err = h_permission(h_inode, mask, &br->br_path,
4a4d8108
AM
20796+ br->br_perm);
20797+ }
20798+ }
1308ab2a 20799+
4f0767ce 20800+out:
4a4d8108
AM
20801+ ii_read_unlock(inode);
20802+ si_read_unlock(sb);
1308ab2a 20803+ return err;
20804+}
20805+
4a4d8108 20806+/* ---------------------------------------------------------------------- */
1facf9fc 20807+
4a4d8108 20808+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 20809+ unsigned int flags)
4a4d8108
AM
20810+{
20811+ struct dentry *ret, *parent;
b752ccd1 20812+ struct inode *inode;
4a4d8108 20813+ struct super_block *sb;
1716fcea 20814+ int err, npositive;
dece6358 20815+
4a4d8108 20816+ IMustLock(dir);
1308ab2a 20817+
537831f9
AM
20818+ /* todo: support rcu-walk? */
20819+ ret = ERR_PTR(-ECHILD);
20820+ if (flags & LOOKUP_RCU)
20821+ goto out;
20822+
20823+ ret = ERR_PTR(-ENAMETOOLONG);
20824+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
20825+ goto out;
20826+
4a4d8108 20827+ sb = dir->i_sb;
7f207e10
AM
20828+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
20829+ ret = ERR_PTR(err);
20830+ if (unlikely(err))
20831+ goto out;
20832+
4a4d8108
AM
20833+ err = au_di_init(dentry);
20834+ ret = ERR_PTR(err);
20835+ if (unlikely(err))
7f207e10 20836+ goto out_si;
1308ab2a 20837+
9dbd164d 20838+ inode = NULL;
027c5e7a 20839+ npositive = 0; /* suppress a warning */
4a4d8108
AM
20840+ parent = dentry->d_parent; /* dir inode is locked */
20841+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
20842+ err = au_alive_dir(parent);
20843+ if (!err)
20844+ err = au_digen_test(parent, au_sigen(sb));
20845+ if (!err) {
5afbbe0d
AM
20846+ /* regardless LOOKUP_CREATE, always ALLOW_NEG */
20847+ npositive = au_lkup_dentry(dentry, au_dbtop(parent),
20848+ AuLkup_ALLOW_NEG);
027c5e7a
AM
20849+ err = npositive;
20850+ }
4a4d8108 20851+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
20852+ ret = ERR_PTR(err);
20853+ if (unlikely(err < 0))
20854+ goto out_unlock;
1308ab2a 20855+
4a4d8108 20856+ if (npositive) {
b752ccd1 20857+ inode = au_new_inode(dentry, /*must_new*/0);
c1595e42
JR
20858+ if (IS_ERR(inode)) {
20859+ ret = (void *)inode;
20860+ inode = NULL;
20861+ goto out_unlock;
20862+ }
9dbd164d 20863+ }
4a4d8108 20864+
c1595e42
JR
20865+ if (inode)
20866+ atomic_inc(&inode->i_count);
4a4d8108 20867+ ret = d_splice_alias(inode, dentry);
537831f9
AM
20868+#if 0
20869+ if (unlikely(d_need_lookup(dentry))) {
20870+ spin_lock(&dentry->d_lock);
20871+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
20872+ spin_unlock(&dentry->d_lock);
20873+ } else
20874+#endif
c1595e42 20875+ if (inode) {
2000de60 20876+ if (!IS_ERR(ret)) {
c1595e42 20877+ iput(inode);
2000de60
JR
20878+ if (ret && ret != dentry)
20879+ ii_write_unlock(inode);
20880+ } else {
c1595e42
JR
20881+ ii_write_unlock(inode);
20882+ iput(inode);
20883+ inode = NULL;
20884+ }
7f207e10 20885+ }
1facf9fc 20886+
4f0767ce 20887+out_unlock:
4a4d8108 20888+ di_write_unlock(dentry);
7f207e10 20889+out_si:
4a4d8108 20890+ si_read_unlock(sb);
7f207e10 20891+out:
4a4d8108
AM
20892+ return ret;
20893+}
1facf9fc 20894+
4a4d8108 20895+/* ---------------------------------------------------------------------- */
1facf9fc 20896+
acd2b654
AM
20897+/*
20898+ * very dirty and complicated aufs ->atomic_open().
20899+ * aufs_atomic_open()
20900+ * + au_aopen_or_create()
20901+ * + add_simple()
20902+ * + vfsub_atomic_open()
20903+ * + branch fs ->atomic_open()
20904+ * may call the actual 'open' for h_file
20905+ * + inc br_nfiles only if opened
20906+ * + au_aopen_no_open() or au_aopen_do_open()
20907+ *
20908+ * au_aopen_do_open()
20909+ * + finish_open()
20910+ * + au_do_aopen()
20911+ * + au_do_open() the body of all 'open'
20912+ * + au_do_open_nondir()
20913+ * set the passed h_file
20914+ *
20915+ * au_aopen_no_open()
20916+ * + finish_no_open()
20917+ */
20918+
b912730e 20919+struct aopen_node {
8b6a4947 20920+ struct hlist_bl_node hblist;
b912730e
AM
20921+ struct file *file, *h_file;
20922+};
20923+
20924+static int au_do_aopen(struct inode *inode, struct file *file)
20925+{
8b6a4947
AM
20926+ struct hlist_bl_head *aopen;
20927+ struct hlist_bl_node *pos;
b912730e
AM
20928+ struct aopen_node *node;
20929+ struct au_do_open_args args = {
8b6a4947
AM
20930+ .aopen = 1,
20931+ .open = au_do_open_nondir
b912730e
AM
20932+ };
20933+
20934+ aopen = &au_sbi(inode->i_sb)->si_aopen;
8b6a4947
AM
20935+ hlist_bl_lock(aopen);
20936+ hlist_bl_for_each_entry(node, pos, aopen, hblist)
b912730e
AM
20937+ if (node->file == file) {
20938+ args.h_file = node->h_file;
20939+ break;
20940+ }
8b6a4947 20941+ hlist_bl_unlock(aopen);
b912730e
AM
20942+ /* AuDebugOn(!args.h_file); */
20943+
20944+ return au_do_open(file, &args);
20945+}
20946+
acd2b654
AM
20947+static int au_aopen_do_open(struct file *file, struct dentry *dentry,
20948+ struct aopen_node *aopen_node)
20949+{
20950+ int err;
20951+ struct hlist_bl_head *aopen;
20952+
20953+ AuLabel(here);
20954+ aopen = &au_sbi(dentry->d_sb)->si_aopen;
20955+ au_hbl_add(&aopen_node->hblist, aopen);
20956+ err = finish_open(file, dentry, au_do_aopen);
20957+ au_hbl_del(&aopen_node->hblist, aopen);
20958+ /* AuDbgFile(file); */
20959+ AuDbg("%pd%s%s\n", dentry,
20960+ (file->f_mode & FMODE_CREATED) ? " created" : "",
20961+ (file->f_mode & FMODE_OPENED) ? " opened" : "");
20962+
20963+ AuTraceErr(err);
20964+ return err;
20965+}
20966+
20967+static int au_aopen_no_open(struct file *file, struct dentry *dentry)
20968+{
20969+ int err;
20970+
20971+ AuLabel(here);
20972+ dget(dentry);
20973+ err = finish_no_open(file, dentry);
20974+
20975+ AuTraceErr(err);
20976+ return err;
20977+}
20978+
b912730e
AM
20979+static int aufs_atomic_open(struct inode *dir, struct dentry *dentry,
20980+ struct file *file, unsigned int open_flag,
acd2b654 20981+ umode_t create_mode)
b912730e 20982+{
acd2b654 20983+ int err, did_open;
5afbbe0d 20984+ unsigned int lkup_flags;
acd2b654
AM
20985+ aufs_bindex_t bindex;
20986+ struct super_block *sb;
f0c0a007 20987+ struct dentry *parent, *d;
b912730e
AM
20988+ struct vfsub_aopen_args args = {
20989+ .open_flag = open_flag,
acd2b654 20990+ .create_mode = create_mode
b912730e
AM
20991+ };
20992+ struct aopen_node aopen_node = {
20993+ .file = file
20994+ };
20995+
20996+ IMustLock(dir);
5afbbe0d 20997+ AuDbg("open_flag 0%o\n", open_flag);
b912730e
AM
20998+ AuDbgDentry(dentry);
20999+
21000+ err = 0;
21001+ if (!au_di(dentry)) {
5afbbe0d
AM
21002+ lkup_flags = LOOKUP_OPEN;
21003+ if (open_flag & O_CREAT)
21004+ lkup_flags |= LOOKUP_CREATE;
21005+ d = aufs_lookup(dir, dentry, lkup_flags);
b912730e
AM
21006+ if (IS_ERR(d)) {
21007+ err = PTR_ERR(d);
5afbbe0d 21008+ AuTraceErr(err);
b912730e
AM
21009+ goto out;
21010+ } else if (d) {
21011+ /*
21012+ * obsoleted dentry found.
21013+ * another error will be returned later.
21014+ */
21015+ d_drop(d);
b912730e 21016+ AuDbgDentry(d);
5afbbe0d 21017+ dput(d);
b912730e
AM
21018+ }
21019+ AuDbgDentry(dentry);
21020+ }
21021+
21022+ if (d_is_positive(dentry)
21023+ || d_unhashed(dentry)
21024+ || d_unlinked(dentry)
acd2b654
AM
21025+ || !(open_flag & O_CREAT)) {
21026+ err = au_aopen_no_open(file, dentry);
21027+ goto out; /* success */
21028+ }
b912730e
AM
21029+
21030+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
21031+ if (unlikely(err))
21032+ goto out;
21033+
acd2b654 21034+ sb = dentry->d_sb;
b912730e
AM
21035+ parent = dentry->d_parent; /* dir is locked */
21036+ di_write_lock_parent(parent);
5afbbe0d 21037+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG);
acd2b654
AM
21038+ if (unlikely(err < 0))
21039+ goto out_parent;
b912730e
AM
21040+
21041+ AuDbgDentry(dentry);
acd2b654
AM
21042+ if (d_is_positive(dentry)) {
21043+ err = au_aopen_no_open(file, dentry);
21044+ goto out_parent; /* success */
21045+ }
b912730e 21046+
acd2b654 21047+ args.file = alloc_empty_file(file->f_flags, current_cred());
b912730e
AM
21048+ err = PTR_ERR(args.file);
21049+ if (IS_ERR(args.file))
acd2b654 21050+ goto out_parent;
b912730e 21051+
acd2b654 21052+ bindex = au_dbtop(dentry);
b912730e
AM
21053+ err = au_aopen_or_create(dir, dentry, &args);
21054+ AuTraceErr(err);
21055+ AuDbgFile(args.file);
acd2b654
AM
21056+ file->f_mode = args.file->f_mode & ~FMODE_OPENED;
21057+ did_open = !!(args.file->f_mode & FMODE_OPENED);
21058+ if (!did_open) {
21059+ fput(args.file);
21060+ args.file = NULL;
b912730e 21061+ }
8b6a4947
AM
21062+ di_write_unlock(parent);
21063+ di_write_unlock(dentry);
acd2b654
AM
21064+ if (unlikely(err < 0)) {
21065+ if (args.file)
21066+ fput(args.file);
21067+ goto out_sb;
b912730e 21068+ }
b912730e 21069+
acd2b654
AM
21070+ if (!did_open)
21071+ err = au_aopen_no_open(file, dentry);
8b6a4947 21072+ else {
acd2b654
AM
21073+ aopen_node.h_file = args.file;
21074+ err = au_aopen_do_open(file, dentry, &aopen_node);
8b6a4947 21075+ }
acd2b654
AM
21076+ if (unlikely(err < 0)) {
21077+ if (args.file)
21078+ fput(args.file);
21079+ if (did_open)
21080+ au_lcnt_dec(&args.br->br_nfiles);
b912730e 21081+ }
acd2b654
AM
21082+ goto out_sb; /* success */
21083+
21084+out_parent:
21085+ di_write_unlock(parent);
21086+ di_write_unlock(dentry);
21087+out_sb:
21088+ si_read_unlock(sb);
b912730e 21089+out:
b912730e 21090+ AuTraceErr(err);
acd2b654 21091+ AuDbgFile(file);
b912730e
AM
21092+ return err;
21093+}
21094+
21095+
21096+/* ---------------------------------------------------------------------- */
21097+
4a4d8108
AM
21098+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
21099+ const unsigned char add_entry, aufs_bindex_t bcpup,
5afbbe0d 21100+ aufs_bindex_t btop)
4a4d8108
AM
21101+{
21102+ int err;
21103+ struct dentry *h_parent;
21104+ struct inode *h_dir;
1facf9fc 21105+
027c5e7a 21106+ if (add_entry)
5527c038 21107+ IMustLock(d_inode(parent));
027c5e7a 21108+ else
4a4d8108
AM
21109+ di_write_lock_parent(parent);
21110+
21111+ err = 0;
21112+ if (!au_h_dptr(parent, bcpup)) {
5afbbe0d 21113+ if (btop > bcpup)
c2b27bf2 21114+ err = au_cpup_dirs(dentry, bcpup);
5afbbe0d 21115+ else if (btop < bcpup)
4a4d8108
AM
21116+ err = au_cpdown_dirs(dentry, bcpup);
21117+ else
c2b27bf2 21118+ BUG();
4a4d8108 21119+ }
38d290e6 21120+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
4a4d8108 21121+ h_parent = au_h_dptr(parent, bcpup);
5527c038 21122+ h_dir = d_inode(h_parent);
be118d29 21123+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
7e9cd9fe 21124+ err = au_lkup_neg(dentry, bcpup, /*wh*/0);
4a4d8108 21125+ /* todo: no unlock here */
3c1bdaff 21126+ inode_unlock_shared(h_dir);
027c5e7a
AM
21127+
21128+ AuDbg("bcpup %d\n", bcpup);
21129+ if (!err) {
5527c038 21130+ if (d_really_is_negative(dentry))
5afbbe0d 21131+ au_set_h_dptr(dentry, btop, NULL);
4a4d8108
AM
21132+ au_update_dbrange(dentry, /*do_put_zero*/0);
21133+ }
1308ab2a 21134+ }
1facf9fc 21135+
4a4d8108
AM
21136+ if (!add_entry)
21137+ di_write_unlock(parent);
21138+ if (!err)
21139+ err = bcpup; /* success */
1308ab2a 21140+
027c5e7a 21141+ AuTraceErr(err);
4a4d8108
AM
21142+ return err;
21143+}
1facf9fc 21144+
4a4d8108
AM
21145+/*
21146+ * decide the branch and the parent dir where we will create a new entry.
21147+ * returns new bindex or an error.
21148+ * copyup the parent dir if needed.
21149+ */
21150+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
21151+ struct au_wr_dir_args *args)
21152+{
21153+ int err;
392086de 21154+ unsigned int flags;
5afbbe0d 21155+ aufs_bindex_t bcpup, btop, src_btop;
86dc4139
AM
21156+ const unsigned char add_entry
21157+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
38d290e6 21158+ | au_ftest_wrdir(args->flags, TMPFILE);
4a4d8108
AM
21159+ struct super_block *sb;
21160+ struct dentry *parent;
21161+ struct au_sbinfo *sbinfo;
1facf9fc 21162+
4a4d8108
AM
21163+ sb = dentry->d_sb;
21164+ sbinfo = au_sbi(sb);
21165+ parent = dget_parent(dentry);
5afbbe0d
AM
21166+ btop = au_dbtop(dentry);
21167+ bcpup = btop;
4a4d8108
AM
21168+ if (args->force_btgt < 0) {
21169+ if (src_dentry) {
5afbbe0d
AM
21170+ src_btop = au_dbtop(src_dentry);
21171+ if (src_btop < btop)
21172+ bcpup = src_btop;
4a4d8108 21173+ } else if (add_entry) {
392086de
AM
21174+ flags = 0;
21175+ if (au_ftest_wrdir(args->flags, ISDIR))
21176+ au_fset_wbr(flags, DIR);
21177+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
21178+ bcpup = err;
21179+ }
1facf9fc 21180+
5527c038 21181+ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) {
4a4d8108
AM
21182+ if (add_entry)
21183+ err = AuWbrCopyup(sbinfo, dentry);
21184+ else {
21185+ if (!IS_ROOT(dentry)) {
21186+ di_read_lock_parent(parent, !AuLock_IR);
21187+ err = AuWbrCopyup(sbinfo, dentry);
21188+ di_read_unlock(parent, !AuLock_IR);
21189+ } else
21190+ err = AuWbrCopyup(sbinfo, dentry);
21191+ }
21192+ bcpup = err;
21193+ if (unlikely(err < 0))
21194+ goto out;
21195+ }
21196+ } else {
21197+ bcpup = args->force_btgt;
5527c038 21198+ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry)));
1308ab2a 21199+ }
027c5e7a 21200+
5afbbe0d 21201+ AuDbg("btop %d, bcpup %d\n", btop, bcpup);
4a4d8108 21202+ err = bcpup;
5afbbe0d 21203+ if (bcpup == btop)
4a4d8108 21204+ goto out; /* success */
4a4d8108
AM
21205+
21206+ /* copyup the new parent into the branch we process */
5afbbe0d 21207+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, btop);
027c5e7a 21208+ if (err >= 0) {
5527c038 21209+ if (d_really_is_negative(dentry)) {
5afbbe0d
AM
21210+ au_set_h_dptr(dentry, btop, NULL);
21211+ au_set_dbtop(dentry, bcpup);
21212+ au_set_dbbot(dentry, bcpup);
027c5e7a 21213+ }
38d290e6
JR
21214+ AuDebugOn(add_entry
21215+ && !au_ftest_wrdir(args->flags, TMPFILE)
21216+ && !au_h_dptr(dentry, bcpup));
027c5e7a 21217+ }
86dc4139
AM
21218+
21219+out:
21220+ dput(parent);
21221+ return err;
21222+}
21223+
21224+/* ---------------------------------------------------------------------- */
21225+
21226+void au_pin_hdir_unlock(struct au_pin *p)
21227+{
21228+ if (p->hdir)
5afbbe0d 21229+ au_hn_inode_unlock(p->hdir);
86dc4139
AM
21230+}
21231+
c1595e42 21232+int au_pin_hdir_lock(struct au_pin *p)
86dc4139
AM
21233+{
21234+ int err;
21235+
21236+ err = 0;
21237+ if (!p->hdir)
21238+ goto out;
21239+
21240+ /* even if an error happens later, keep this lock */
5afbbe0d 21241+ au_hn_inode_lock_nested(p->hdir, p->lsc_hi);
86dc4139
AM
21242+
21243+ err = -EBUSY;
5527c038 21244+ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent)))
86dc4139
AM
21245+ goto out;
21246+
21247+ err = 0;
21248+ if (p->h_dentry)
21249+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
21250+ p->h_parent, p->br);
21251+
21252+out:
21253+ return err;
21254+}
21255+
21256+int au_pin_hdir_relock(struct au_pin *p)
21257+{
21258+ int err, i;
21259+ struct inode *h_i;
21260+ struct dentry *h_d[] = {
21261+ p->h_dentry,
21262+ p->h_parent
21263+ };
21264+
21265+ err = au_pin_hdir_lock(p);
21266+ if (unlikely(err))
21267+ goto out;
21268+
21269+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
21270+ if (!h_d[i])
21271+ continue;
5527c038
JR
21272+ if (d_is_positive(h_d[i])) {
21273+ h_i = d_inode(h_d[i]);
86dc4139 21274+ err = !h_i->i_nlink;
5527c038 21275+ }
86dc4139
AM
21276+ }
21277+
21278+out:
21279+ return err;
21280+}
21281+
5afbbe0d 21282+static void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
86dc4139 21283+{
5afbbe0d
AM
21284+#if !defined(CONFIG_RWSEM_GENERIC_SPINLOCK) && defined(CONFIG_RWSEM_SPIN_ON_OWNER)
21285+ p->hdir->hi_inode->i_rwsem.owner = task;
86dc4139
AM
21286+#endif
21287+}
21288+
21289+void au_pin_hdir_acquire_nest(struct au_pin *p)
21290+{
21291+ if (p->hdir) {
5afbbe0d 21292+ rwsem_acquire_nest(&p->hdir->hi_inode->i_rwsem.dep_map,
86dc4139
AM
21293+ p->lsc_hi, 0, NULL, _RET_IP_);
21294+ au_pin_hdir_set_owner(p, current);
21295+ }
dece6358 21296+}
1facf9fc 21297+
86dc4139
AM
21298+void au_pin_hdir_release(struct au_pin *p)
21299+{
21300+ if (p->hdir) {
21301+ au_pin_hdir_set_owner(p, p->task);
5afbbe0d 21302+ rwsem_release(&p->hdir->hi_inode->i_rwsem.dep_map, 1, _RET_IP_);
86dc4139
AM
21303+ }
21304+}
1308ab2a 21305+
4a4d8108 21306+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 21307+{
4a4d8108
AM
21308+ if (pin && pin->parent)
21309+ return au_h_dptr(pin->parent, pin->bindex);
21310+ return NULL;
dece6358 21311+}
1facf9fc 21312+
4a4d8108 21313+void au_unpin(struct au_pin *p)
dece6358 21314+{
86dc4139
AM
21315+ if (p->hdir)
21316+ au_pin_hdir_unlock(p);
e49829fe 21317+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 21318+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
21319+ if (!p->hdir)
21320+ return;
1facf9fc 21321+
4a4d8108
AM
21322+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21323+ di_read_unlock(p->parent, AuLock_IR);
21324+ iput(p->hdir->hi_inode);
21325+ dput(p->parent);
21326+ p->parent = NULL;
21327+ p->hdir = NULL;
21328+ p->h_mnt = NULL;
86dc4139 21329+ /* do not clear p->task */
4a4d8108 21330+}
1308ab2a 21331+
4a4d8108
AM
21332+int au_do_pin(struct au_pin *p)
21333+{
21334+ int err;
21335+ struct super_block *sb;
4a4d8108
AM
21336+ struct inode *h_dir;
21337+
21338+ err = 0;
21339+ sb = p->dentry->d_sb;
86dc4139 21340+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
21341+ if (IS_ROOT(p->dentry)) {
21342+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 21343+ p->h_mnt = au_br_mnt(p->br);
b4510431 21344+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
21345+ if (unlikely(err)) {
21346+ au_fclr_pin(p->flags, MNT_WRITE);
21347+ goto out_err;
21348+ }
21349+ }
dece6358 21350+ goto out;
1facf9fc 21351+ }
21352+
86dc4139 21353+ p->h_dentry = NULL;
5afbbe0d 21354+ if (p->bindex <= au_dbbot(p->dentry))
86dc4139 21355+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 21356+
4a4d8108
AM
21357+ p->parent = dget_parent(p->dentry);
21358+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21359+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 21360+
4a4d8108 21361+ h_dir = NULL;
86dc4139 21362+ p->h_parent = au_h_dptr(p->parent, p->bindex);
5527c038 21363+ p->hdir = au_hi(d_inode(p->parent), p->bindex);
4a4d8108
AM
21364+ if (p->hdir)
21365+ h_dir = p->hdir->hi_inode;
dece6358 21366+
b752ccd1
AM
21367+ /*
21368+ * udba case, or
21369+ * if DI_LOCKED is not set, then p->parent may be different
21370+ * and h_parent can be NULL.
21371+ */
86dc4139 21372+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 21373+ err = -EBUSY;
4a4d8108
AM
21374+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21375+ di_read_unlock(p->parent, AuLock_IR);
21376+ dput(p->parent);
21377+ p->parent = NULL;
21378+ goto out_err;
21379+ }
1308ab2a 21380+
4a4d8108 21381+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 21382+ p->h_mnt = au_br_mnt(p->br);
b4510431 21383+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 21384+ if (unlikely(err)) {
4a4d8108 21385+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
21386+ if (!au_ftest_pin(p->flags, DI_LOCKED))
21387+ di_read_unlock(p->parent, AuLock_IR);
21388+ dput(p->parent);
21389+ p->parent = NULL;
21390+ goto out_err;
dece6358
AM
21391+ }
21392+ }
4a4d8108 21393+
86dc4139
AM
21394+ au_igrab(h_dir);
21395+ err = au_pin_hdir_lock(p);
21396+ if (!err)
21397+ goto out; /* success */
21398+
076b876e
AM
21399+ au_unpin(p);
21400+
4f0767ce 21401+out_err:
4a4d8108
AM
21402+ pr_err("err %d\n", err);
21403+ err = au_busy_or_stale();
4f0767ce 21404+out:
1facf9fc 21405+ return err;
21406+}
21407+
4a4d8108
AM
21408+void au_pin_init(struct au_pin *p, struct dentry *dentry,
21409+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
21410+ unsigned int udba, unsigned char flags)
21411+{
21412+ p->dentry = dentry;
21413+ p->udba = udba;
21414+ p->lsc_di = lsc_di;
21415+ p->lsc_hi = lsc_hi;
21416+ p->flags = flags;
21417+ p->bindex = bindex;
21418+
21419+ p->parent = NULL;
21420+ p->hdir = NULL;
21421+ p->h_mnt = NULL;
86dc4139
AM
21422+
21423+ p->h_dentry = NULL;
21424+ p->h_parent = NULL;
21425+ p->br = NULL;
21426+ p->task = current;
4a4d8108
AM
21427+}
21428+
21429+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
21430+ unsigned int udba, unsigned char flags)
21431+{
21432+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
21433+ udba, flags);
21434+ return au_do_pin(pin);
21435+}
21436+
dece6358
AM
21437+/* ---------------------------------------------------------------------- */
21438+
1308ab2a 21439+/*
4a4d8108
AM
21440+ * ->setattr() and ->getattr() are called in various cases.
21441+ * chmod, stat: dentry is revalidated.
21442+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
21443+ * unhashed.
21444+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 21445+ */
027c5e7a 21446+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
c1595e42 21447+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 21448+{
4a4d8108 21449+ int err;
4a4d8108 21450+ struct dentry *parent;
1facf9fc 21451+
1308ab2a 21452+ err = 0;
027c5e7a 21453+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
21454+ parent = dget_parent(dentry);
21455+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 21456+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
21457+ di_read_unlock(parent, AuLock_IR);
21458+ dput(parent);
dece6358 21459+ }
1facf9fc 21460+
4a4d8108 21461+ AuTraceErr(err);
1308ab2a 21462+ return err;
21463+}
dece6358 21464+
c1595e42
JR
21465+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
21466+ struct au_icpup_args *a)
1308ab2a 21467+{
21468+ int err;
4a4d8108 21469+ loff_t sz;
5afbbe0d 21470+ aufs_bindex_t btop, ibtop;
4a4d8108
AM
21471+ struct dentry *hi_wh, *parent;
21472+ struct inode *inode;
4a4d8108
AM
21473+ struct au_wr_dir_args wr_dir_args = {
21474+ .force_btgt = -1,
21475+ .flags = 0
21476+ };
21477+
2000de60 21478+ if (d_is_dir(dentry))
4a4d8108
AM
21479+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
21480+ /* plink or hi_wh() case */
5afbbe0d 21481+ btop = au_dbtop(dentry);
5527c038 21482+ inode = d_inode(dentry);
5afbbe0d
AM
21483+ ibtop = au_ibtop(inode);
21484+ if (btop != ibtop && !au_test_ro(inode->i_sb, ibtop, inode))
21485+ wr_dir_args.force_btgt = ibtop;
4a4d8108
AM
21486+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
21487+ if (unlikely(err < 0))
21488+ goto out;
21489+ a->btgt = err;
5afbbe0d 21490+ if (err != btop)
4a4d8108
AM
21491+ au_fset_icpup(a->flags, DID_CPUP);
21492+
21493+ err = 0;
21494+ a->pin_flags = AuPin_MNT_WRITE;
21495+ parent = NULL;
21496+ if (!IS_ROOT(dentry)) {
21497+ au_fset_pin(a->pin_flags, DI_LOCKED);
21498+ parent = dget_parent(dentry);
21499+ di_write_lock_parent(parent);
21500+ }
21501+
21502+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
21503+ if (unlikely(err))
21504+ goto out_parent;
21505+
4a4d8108 21506+ sz = -1;
5afbbe0d 21507+ a->h_path.dentry = au_h_dptr(dentry, btop);
5527c038 21508+ a->h_inode = d_inode(a->h_path.dentry);
c1595e42 21509+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
be118d29 21510+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
c1595e42
JR
21511+ if (ia->ia_size < i_size_read(a->h_inode))
21512+ sz = ia->ia_size;
3c1bdaff 21513+ inode_unlock_shared(a->h_inode);
c1595e42 21514+ }
4a4d8108 21515+
4a4d8108 21516+ hi_wh = NULL;
027c5e7a 21517+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
21518+ hi_wh = au_hi_wh(inode, a->btgt);
21519+ if (!hi_wh) {
c2b27bf2
AM
21520+ struct au_cp_generic cpg = {
21521+ .dentry = dentry,
21522+ .bdst = a->btgt,
21523+ .bsrc = -1,
21524+ .len = sz,
21525+ .pin = &a->pin
21526+ };
21527+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
21528+ if (unlikely(err))
21529+ goto out_unlock;
21530+ hi_wh = au_hi_wh(inode, a->btgt);
21531+ /* todo: revalidate hi_wh? */
21532+ }
21533+ }
21534+
21535+ if (parent) {
21536+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
21537+ di_downgrade_lock(parent, AuLock_IR);
21538+ dput(parent);
21539+ parent = NULL;
21540+ }
21541+ if (!au_ftest_icpup(a->flags, DID_CPUP))
21542+ goto out; /* success */
21543+
21544+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
21545+ struct au_cp_generic cpg = {
21546+ .dentry = dentry,
21547+ .bdst = a->btgt,
5afbbe0d 21548+ .bsrc = btop,
c2b27bf2
AM
21549+ .len = sz,
21550+ .pin = &a->pin,
21551+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21552+ };
21553+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
21554+ if (!err)
21555+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
21556+ } else if (!hi_wh)
21557+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
21558+ else
21559+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 21560+
4f0767ce 21561+out_unlock:
5527c038 21562+ a->h_inode = d_inode(a->h_path.dentry);
86dc4139 21563+ if (!err)
dece6358 21564+ goto out; /* success */
4a4d8108 21565+ au_unpin(&a->pin);
4f0767ce 21566+out_parent:
4a4d8108
AM
21567+ if (parent) {
21568+ di_write_unlock(parent);
21569+ dput(parent);
21570+ }
4f0767ce 21571+out:
86dc4139 21572+ if (!err)
febd17d6 21573+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
1facf9fc 21574+ return err;
21575+}
21576+
4a4d8108 21577+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 21578+{
4a4d8108 21579+ int err;
523b37e3 21580+ struct inode *inode, *delegated;
4a4d8108
AM
21581+ struct super_block *sb;
21582+ struct file *file;
21583+ struct au_icpup_args *a;
1facf9fc 21584+
5527c038 21585+ inode = d_inode(dentry);
4a4d8108 21586+ IMustLock(inode);
dece6358 21587+
f2c43d5f
AM
21588+ err = setattr_prepare(dentry, ia);
21589+ if (unlikely(err))
21590+ goto out;
21591+
4a4d8108
AM
21592+ err = -ENOMEM;
21593+ a = kzalloc(sizeof(*a), GFP_NOFS);
21594+ if (unlikely(!a))
21595+ goto out;
1facf9fc 21596+
4a4d8108
AM
21597+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
21598+ ia->ia_valid &= ~ATTR_MODE;
dece6358 21599+
4a4d8108
AM
21600+ file = NULL;
21601+ sb = dentry->d_sb;
e49829fe
JR
21602+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21603+ if (unlikely(err))
21604+ goto out_kfree;
21605+
4a4d8108
AM
21606+ if (ia->ia_valid & ATTR_FILE) {
21607+ /* currently ftruncate(2) only */
7e9cd9fe 21608+ AuDebugOn(!d_is_reg(dentry));
4a4d8108 21609+ file = ia->ia_file;
521ced18
JR
21610+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1,
21611+ /*fi_lsc*/0);
4a4d8108
AM
21612+ if (unlikely(err))
21613+ goto out_si;
21614+ ia->ia_file = au_hf_top(file);
21615+ a->udba = AuOpt_UDBA_NONE;
21616+ } else {
21617+ /* fchmod() doesn't pass ia_file */
21618+ a->udba = au_opt_udba(sb);
027c5e7a
AM
21619+ di_write_lock_child(dentry);
21620+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
21621+ if (d_unhashed(dentry))
21622+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
21623+ if (a->udba != AuOpt_UDBA_NONE) {
21624+ AuDebugOn(IS_ROOT(dentry));
21625+ err = au_reval_for_attr(dentry, au_sigen(sb));
21626+ if (unlikely(err))
21627+ goto out_dentry;
21628+ }
dece6358 21629+ }
dece6358 21630+
4a4d8108
AM
21631+ err = au_pin_and_icpup(dentry, ia, a);
21632+ if (unlikely(err < 0))
21633+ goto out_dentry;
21634+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
21635+ ia->ia_file = NULL;
21636+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 21637+ }
dece6358 21638+
4a4d8108
AM
21639+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
21640+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
21641+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 21642+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
21643+ if (unlikely(err))
21644+ goto out_unlock;
21645+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
21646+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 21647+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
21648+ if (unlikely(err))
21649+ goto out_unlock;
21650+ }
dece6358 21651+
4a4d8108
AM
21652+ if (ia->ia_valid & ATTR_SIZE) {
21653+ struct file *f;
1308ab2a 21654+
953406b4 21655+ if (ia->ia_size < i_size_read(inode))
4a4d8108 21656+ /* unmap only */
953406b4 21657+ truncate_setsize(inode, ia->ia_size);
1308ab2a 21658+
4a4d8108
AM
21659+ f = NULL;
21660+ if (ia->ia_valid & ATTR_FILE)
21661+ f = ia->ia_file;
febd17d6 21662+ inode_unlock(a->h_inode);
4a4d8108 21663+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
febd17d6 21664+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
523b37e3
AM
21665+ } else {
21666+ delegated = NULL;
21667+ while (1) {
21668+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
21669+ if (delegated) {
21670+ err = break_deleg_wait(&delegated);
21671+ if (!err)
21672+ continue;
21673+ }
21674+ break;
21675+ }
21676+ }
8cdd5066
JR
21677+ /*
21678+ * regardless aufs 'acl' option setting.
21679+ * why don't all acl-aware fs call this func from their ->setattr()?
21680+ */
21681+ if (!err && (ia->ia_valid & ATTR_MODE))
21682+ err = vfsub_acl_chmod(a->h_inode, ia->ia_mode);
4a4d8108
AM
21683+ if (!err)
21684+ au_cpup_attr_changeable(inode);
1308ab2a 21685+
4f0767ce 21686+out_unlock:
febd17d6 21687+ inode_unlock(a->h_inode);
4a4d8108 21688+ au_unpin(&a->pin);
027c5e7a 21689+ if (unlikely(err))
5afbbe0d 21690+ au_update_dbtop(dentry);
4f0767ce 21691+out_dentry:
4a4d8108
AM
21692+ di_write_unlock(dentry);
21693+ if (file) {
21694+ fi_write_unlock(file);
21695+ ia->ia_file = file;
21696+ ia->ia_valid |= ATTR_FILE;
21697+ }
4f0767ce 21698+out_si:
4a4d8108 21699+ si_read_unlock(sb);
e49829fe 21700+out_kfree:
1c60b727 21701+ kfree(a);
4f0767ce 21702+out:
4a4d8108
AM
21703+ AuTraceErr(err);
21704+ return err;
1facf9fc 21705+}
21706+
c1595e42
JR
21707+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
21708+static int au_h_path_to_set_attr(struct dentry *dentry,
21709+ struct au_icpup_args *a, struct path *h_path)
21710+{
21711+ int err;
21712+ struct super_block *sb;
21713+
21714+ sb = dentry->d_sb;
21715+ a->udba = au_opt_udba(sb);
21716+ /* no d_unlinked(), to set UDBA_NONE for root */
21717+ if (d_unhashed(dentry))
21718+ a->udba = AuOpt_UDBA_NONE;
21719+ if (a->udba != AuOpt_UDBA_NONE) {
21720+ AuDebugOn(IS_ROOT(dentry));
21721+ err = au_reval_for_attr(dentry, au_sigen(sb));
21722+ if (unlikely(err))
21723+ goto out;
21724+ }
21725+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a);
21726+ if (unlikely(err < 0))
21727+ goto out;
21728+
21729+ h_path->dentry = a->h_path.dentry;
21730+ h_path->mnt = au_sbr_mnt(sb, a->btgt);
21731+
21732+out:
21733+ return err;
21734+}
21735+
f2c43d5f
AM
21736+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
21737+ struct au_sxattr *arg)
c1595e42
JR
21738+{
21739+ int err;
21740+ struct path h_path;
21741+ struct super_block *sb;
21742+ struct au_icpup_args *a;
5afbbe0d 21743+ struct inode *h_inode;
c1595e42 21744+
c1595e42
JR
21745+ IMustLock(inode);
21746+
21747+ err = -ENOMEM;
21748+ a = kzalloc(sizeof(*a), GFP_NOFS);
21749+ if (unlikely(!a))
21750+ goto out;
21751+
21752+ sb = dentry->d_sb;
21753+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21754+ if (unlikely(err))
21755+ goto out_kfree;
21756+
21757+ h_path.dentry = NULL; /* silence gcc */
21758+ di_write_lock_child(dentry);
21759+ err = au_h_path_to_set_attr(dentry, a, &h_path);
21760+ if (unlikely(err))
21761+ goto out_di;
21762+
febd17d6 21763+ inode_unlock(a->h_inode);
c1595e42
JR
21764+ switch (arg->type) {
21765+ case AU_XATTR_SET:
5afbbe0d 21766+ AuDebugOn(d_is_negative(h_path.dentry));
c1595e42
JR
21767+ err = vfsub_setxattr(h_path.dentry,
21768+ arg->u.set.name, arg->u.set.value,
21769+ arg->u.set.size, arg->u.set.flags);
21770+ break;
c1595e42
JR
21771+ case AU_ACL_SET:
21772+ err = -EOPNOTSUPP;
5527c038 21773+ h_inode = d_inode(h_path.dentry);
c1595e42 21774+ if (h_inode->i_op->set_acl)
f2c43d5f 21775+ /* this will call posix_acl_update_mode */
c1595e42
JR
21776+ err = h_inode->i_op->set_acl(h_inode,
21777+ arg->u.acl_set.acl,
21778+ arg->u.acl_set.type);
21779+ break;
21780+ }
21781+ if (!err)
21782+ au_cpup_attr_timesizes(inode);
21783+
21784+ au_unpin(&a->pin);
21785+ if (unlikely(err))
5afbbe0d 21786+ au_update_dbtop(dentry);
c1595e42
JR
21787+
21788+out_di:
21789+ di_write_unlock(dentry);
21790+ si_read_unlock(sb);
21791+out_kfree:
1c60b727 21792+ kfree(a);
c1595e42
JR
21793+out:
21794+ AuTraceErr(err);
21795+ return err;
21796+}
21797+#endif
21798+
4a4d8108
AM
21799+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
21800+ unsigned int nlink)
1facf9fc 21801+{
9dbd164d
AM
21802+ unsigned int n;
21803+
4a4d8108 21804+ inode->i_mode = st->mode;
86dc4139
AM
21805+ /* don't i_[ug]id_write() here */
21806+ inode->i_uid = st->uid;
21807+ inode->i_gid = st->gid;
4a4d8108
AM
21808+ inode->i_atime = st->atime;
21809+ inode->i_mtime = st->mtime;
21810+ inode->i_ctime = st->ctime;
1facf9fc 21811+
4a4d8108
AM
21812+ au_cpup_attr_nlink(inode, /*force*/0);
21813+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
21814+ n = inode->i_nlink;
21815+ n -= nlink;
21816+ n += st->nlink;
f6b6e03d 21817+ smp_mb(); /* for i_nlink */
7eafdf33 21818+ /* 0 can happen */
92d182d2 21819+ set_nlink(inode, n);
4a4d8108 21820+ }
1facf9fc 21821+
4a4d8108
AM
21822+ spin_lock(&inode->i_lock);
21823+ inode->i_blocks = st->blocks;
21824+ i_size_write(inode, st->size);
21825+ spin_unlock(&inode->i_lock);
1facf9fc 21826+}
21827+
c1595e42 21828+/*
f2c43d5f 21829+ * common routine for aufs_getattr() and au_getxattr().
c1595e42
JR
21830+ * returns zero or negative (an error).
21831+ * @dentry will be read-locked in success.
21832+ */
a2654f78
AM
21833+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
21834+ int locked)
1facf9fc 21835+{
4a4d8108 21836+ int err;
076b876e 21837+ unsigned int mnt_flags, sigen;
c1595e42 21838+ unsigned char udba_none;
4a4d8108 21839+ aufs_bindex_t bindex;
4a4d8108
AM
21840+ struct super_block *sb, *h_sb;
21841+ struct inode *inode;
1facf9fc 21842+
c1595e42
JR
21843+ h_path->mnt = NULL;
21844+ h_path->dentry = NULL;
21845+
21846+ err = 0;
4a4d8108 21847+ sb = dentry->d_sb;
4a4d8108
AM
21848+ mnt_flags = au_mntflags(sb);
21849+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 21850+
a2654f78
AM
21851+ if (unlikely(locked))
21852+ goto body; /* skip locking dinfo */
21853+
4a4d8108 21854+ /* support fstat(2) */
027c5e7a 21855+ if (!d_unlinked(dentry) && !udba_none) {
076b876e 21856+ sigen = au_sigen(sb);
027c5e7a
AM
21857+ err = au_digen_test(dentry, sigen);
21858+ if (!err) {
4a4d8108 21859+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a 21860+ err = au_dbrange_test(dentry);
c1595e42
JR
21861+ if (unlikely(err)) {
21862+ di_read_unlock(dentry, AuLock_IR);
21863+ goto out;
21864+ }
027c5e7a 21865+ } else {
4a4d8108
AM
21866+ AuDebugOn(IS_ROOT(dentry));
21867+ di_write_lock_child(dentry);
027c5e7a
AM
21868+ err = au_dbrange_test(dentry);
21869+ if (!err)
21870+ err = au_reval_for_attr(dentry, sigen);
c1595e42
JR
21871+ if (!err)
21872+ di_downgrade_lock(dentry, AuLock_IR);
21873+ else {
21874+ di_write_unlock(dentry);
21875+ goto out;
21876+ }
4a4d8108
AM
21877+ }
21878+ } else
21879+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 21880+
a2654f78 21881+body:
5527c038 21882+ inode = d_inode(dentry);
5afbbe0d 21883+ bindex = au_ibtop(inode);
c1595e42
JR
21884+ h_path->mnt = au_sbr_mnt(sb, bindex);
21885+ h_sb = h_path->mnt->mnt_sb;
21886+ if (!force
21887+ && !au_test_fs_bad_iattr(h_sb)
21888+ && udba_none)
21889+ goto out; /* success */
1facf9fc 21890+
5afbbe0d 21891+ if (au_dbtop(dentry) == bindex)
c1595e42 21892+ h_path->dentry = au_h_dptr(dentry, bindex);
4a4d8108 21893+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c1595e42
JR
21894+ h_path->dentry = au_plink_lkup(inode, bindex);
21895+ if (IS_ERR(h_path->dentry))
21896+ /* pretending success */
21897+ h_path->dentry = NULL;
21898+ else
21899+ dput(h_path->dentry);
4a4d8108 21900+ }
c1595e42
JR
21901+
21902+out:
21903+ return err;
21904+}
21905+
521ced18
JR
21906+static int aufs_getattr(const struct path *path, struct kstat *st,
21907+ u32 request, unsigned int query)
c1595e42
JR
21908+{
21909+ int err;
21910+ unsigned char positive;
21911+ struct path h_path;
521ced18 21912+ struct dentry *dentry;
c1595e42
JR
21913+ struct inode *inode;
21914+ struct super_block *sb;
21915+
521ced18 21916+ dentry = path->dentry;
5527c038 21917+ inode = d_inode(dentry);
c1595e42
JR
21918+ sb = dentry->d_sb;
21919+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
21920+ if (unlikely(err))
21921+ goto out;
a2654f78 21922+ err = au_h_path_getattr(dentry, /*force*/0, &h_path, /*locked*/0);
c1595e42
JR
21923+ if (unlikely(err))
21924+ goto out_si;
c06a8ce3 21925+ if (unlikely(!h_path.dentry))
c1595e42 21926+ /* illegally overlapped or something */
4a4d8108
AM
21927+ goto out_fill; /* pretending success */
21928+
5527c038 21929+ positive = d_is_positive(h_path.dentry);
4a4d8108 21930+ if (positive)
521ced18
JR
21931+ /* no vfsub version */
21932+ err = vfs_getattr(&h_path, st, request, query);
4a4d8108
AM
21933+ if (!err) {
21934+ if (positive)
c06a8ce3 21935+ au_refresh_iattr(inode, st,
5527c038 21936+ d_inode(h_path.dentry)->i_nlink);
4a4d8108 21937+ goto out_fill; /* success */
1facf9fc 21938+ }
7f207e10 21939+ AuTraceErr(err);
c1595e42 21940+ goto out_di;
4a4d8108 21941+
4f0767ce 21942+out_fill:
4a4d8108 21943+ generic_fillattr(inode, st);
c1595e42 21944+out_di:
4a4d8108 21945+ di_read_unlock(dentry, AuLock_IR);
c1595e42 21946+out_si:
4a4d8108 21947+ si_read_unlock(sb);
7f207e10
AM
21948+out:
21949+ AuTraceErr(err);
4a4d8108 21950+ return err;
1facf9fc 21951+}
21952+
21953+/* ---------------------------------------------------------------------- */
21954+
febd17d6
JR
21955+static const char *aufs_get_link(struct dentry *dentry, struct inode *inode,
21956+ struct delayed_call *done)
4a4d8108 21957+{
c2c0f25c 21958+ const char *ret;
c2c0f25c 21959+ struct dentry *h_dentry;
febd17d6 21960+ struct inode *h_inode;
4a4d8108 21961+ int err;
c2c0f25c 21962+ aufs_bindex_t bindex;
1facf9fc 21963+
79b8bda9 21964+ ret = NULL; /* suppress a warning */
febd17d6
JR
21965+ err = -ECHILD;
21966+ if (!dentry)
21967+ goto out;
21968+
027c5e7a
AM
21969+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
21970+ if (unlikely(err))
c2c0f25c 21971+ goto out;
027c5e7a
AM
21972+
21973+ err = au_d_hashed_positive(dentry);
c2c0f25c
AM
21974+ if (unlikely(err))
21975+ goto out_unlock;
21976+
21977+ err = -EINVAL;
21978+ inode = d_inode(dentry);
5afbbe0d 21979+ bindex = au_ibtop(inode);
c2c0f25c 21980+ h_inode = au_h_iptr(inode, bindex);
febd17d6 21981+ if (unlikely(!h_inode->i_op->get_link))
c2c0f25c
AM
21982+ goto out_unlock;
21983+
21984+ err = -EBUSY;
21985+ h_dentry = NULL;
5afbbe0d 21986+ if (au_dbtop(dentry) <= bindex) {
c2c0f25c
AM
21987+ h_dentry = au_h_dptr(dentry, bindex);
21988+ if (h_dentry)
21989+ dget(h_dentry);
027c5e7a 21990+ }
c2c0f25c
AM
21991+ if (!h_dentry) {
21992+ h_dentry = d_find_any_alias(h_inode);
21993+ if (IS_ERR(h_dentry)) {
21994+ err = PTR_ERR(h_dentry);
febd17d6 21995+ goto out_unlock;
c2c0f25c
AM
21996+ }
21997+ }
21998+ if (unlikely(!h_dentry))
febd17d6 21999+ goto out_unlock;
1facf9fc 22000+
c2c0f25c 22001+ err = 0;
062440b3 22002+ AuDbg("%ps\n", h_inode->i_op->get_link);
c2c0f25c 22003+ AuDbgDentry(h_dentry);
f2c43d5f 22004+ ret = vfs_get_link(h_dentry, done);
c2c0f25c 22005+ dput(h_dentry);
febd17d6
JR
22006+ if (IS_ERR(ret))
22007+ err = PTR_ERR(ret);
c2c0f25c 22008+
c2c0f25c
AM
22009+out_unlock:
22010+ aufs_read_unlock(dentry, AuLock_IR);
4f0767ce 22011+out:
c2c0f25c
AM
22012+ if (unlikely(err))
22013+ ret = ERR_PTR(err);
22014+ AuTraceErrPtr(ret);
22015+ return ret;
4a4d8108 22016+}
1facf9fc 22017+
4a4d8108 22018+/* ---------------------------------------------------------------------- */
1facf9fc 22019+
e2f27e51
AM
22020+static int au_is_special(struct inode *inode)
22021+{
22022+ return (inode->i_mode & (S_IFBLK | S_IFCHR | S_IFIFO | S_IFSOCK));
22023+}
22024+
acd2b654
AM
22025+static int aufs_update_time(struct inode *inode, struct timespec64 *ts,
22026+ int flags)
4a4d8108 22027+{
0c3ec466 22028+ int err;
e2f27e51 22029+ aufs_bindex_t bindex;
0c3ec466
AM
22030+ struct super_block *sb;
22031+ struct inode *h_inode;
e2f27e51 22032+ struct vfsmount *h_mnt;
0c3ec466
AM
22033+
22034+ sb = inode->i_sb;
e2f27e51
AM
22035+ WARN_ONCE((flags & S_ATIME) && !IS_NOATIME(inode),
22036+ "unexpected s_flags 0x%lx", sb->s_flags);
22037+
0c3ec466
AM
22038+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
22039+ lockdep_off();
22040+ si_read_lock(sb, AuLock_FLUSH);
22041+ ii_write_lock_child(inode);
e2f27e51
AM
22042+
22043+ err = 0;
22044+ bindex = au_ibtop(inode);
22045+ h_inode = au_h_iptr(inode, bindex);
22046+ if (!au_test_ro(sb, bindex, inode)) {
22047+ h_mnt = au_sbr_mnt(sb, bindex);
22048+ err = vfsub_mnt_want_write(h_mnt);
22049+ if (!err) {
22050+ err = vfsub_update_time(h_inode, ts, flags);
22051+ vfsub_mnt_drop_write(h_mnt);
22052+ }
22053+ } else if (au_is_special(h_inode)) {
22054+ /*
22055+ * Never copy-up here.
22056+ * These special files may already be opened and used for
22057+ * communicating. If we copied it up, then the communication
22058+ * would be corrupted.
22059+ */
22060+ AuWarn1("timestamps for i%lu are ignored "
22061+ "since it is on readonly branch (hi%lu).\n",
22062+ inode->i_ino, h_inode->i_ino);
22063+ } else if (flags & ~S_ATIME) {
22064+ err = -EIO;
22065+ AuIOErr1("unexpected flags 0x%x\n", flags);
22066+ AuDebugOn(1);
22067+ }
22068+
38d290e6
JR
22069+ if (!err)
22070+ au_cpup_attr_timesizes(inode);
0c3ec466
AM
22071+ ii_write_unlock(inode);
22072+ si_read_unlock(sb);
22073+ lockdep_on();
38d290e6
JR
22074+
22075+ if (!err && (flags & S_VERSION))
22076+ inode_inc_iversion(inode);
22077+
0c3ec466 22078+ return err;
4a4d8108 22079+}
1facf9fc 22080+
4a4d8108 22081+/* ---------------------------------------------------------------------- */
1308ab2a 22082+
b95c5147
AM
22083+/* no getattr version will be set by module.c:aufs_init() */
22084+struct inode_operations aufs_iop_nogetattr[AuIop_Last],
22085+ aufs_iop[] = {
22086+ [AuIop_SYMLINK] = {
22087+ .permission = aufs_permission,
c1595e42 22088+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
22089+ .get_acl = aufs_get_acl,
22090+ .set_acl = aufs_set_acl, /* unsupport for symlink? */
c1595e42
JR
22091+#endif
22092+
b95c5147
AM
22093+ .setattr = aufs_setattr,
22094+ .getattr = aufs_getattr,
0c3ec466 22095+
c1595e42 22096+#ifdef CONFIG_AUFS_XATTR
b95c5147 22097+ .listxattr = aufs_listxattr,
c1595e42
JR
22098+#endif
22099+
febd17d6 22100+ .get_link = aufs_get_link,
0c3ec466 22101+
b95c5147
AM
22102+ /* .update_time = aufs_update_time */
22103+ },
22104+ [AuIop_DIR] = {
22105+ .create = aufs_create,
22106+ .lookup = aufs_lookup,
22107+ .link = aufs_link,
22108+ .unlink = aufs_unlink,
22109+ .symlink = aufs_symlink,
22110+ .mkdir = aufs_mkdir,
22111+ .rmdir = aufs_rmdir,
22112+ .mknod = aufs_mknod,
22113+ .rename = aufs_rename,
22114+
22115+ .permission = aufs_permission,
c1595e42 22116+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
22117+ .get_acl = aufs_get_acl,
22118+ .set_acl = aufs_set_acl,
c1595e42
JR
22119+#endif
22120+
b95c5147
AM
22121+ .setattr = aufs_setattr,
22122+ .getattr = aufs_getattr,
0c3ec466 22123+
c1595e42 22124+#ifdef CONFIG_AUFS_XATTR
b95c5147 22125+ .listxattr = aufs_listxattr,
c1595e42
JR
22126+#endif
22127+
b95c5147
AM
22128+ .update_time = aufs_update_time,
22129+ .atomic_open = aufs_atomic_open,
22130+ .tmpfile = aufs_tmpfile
22131+ },
22132+ [AuIop_OTHER] = {
22133+ .permission = aufs_permission,
c1595e42 22134+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
22135+ .get_acl = aufs_get_acl,
22136+ .set_acl = aufs_set_acl,
c1595e42
JR
22137+#endif
22138+
b95c5147
AM
22139+ .setattr = aufs_setattr,
22140+ .getattr = aufs_getattr,
0c3ec466 22141+
c1595e42 22142+#ifdef CONFIG_AUFS_XATTR
b95c5147 22143+ .listxattr = aufs_listxattr,
c1595e42
JR
22144+#endif
22145+
b95c5147
AM
22146+ .update_time = aufs_update_time
22147+ }
4a4d8108 22148+};
7f207e10
AM
22149diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
22150--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 22151+++ linux/fs/aufs/i_op_del.c 2018-10-23 12:33:35.599375796 +0200
062440b3 22152@@ -0,0 +1,512 @@
cd7a4cd9 22153+// SPDX-License-Identifier: GPL-2.0
1facf9fc 22154+/*
b00004a5 22155+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 22156+ *
22157+ * This program, aufs is free software; you can redistribute it and/or modify
22158+ * it under the terms of the GNU General Public License as published by
22159+ * the Free Software Foundation; either version 2 of the License, or
22160+ * (at your option) any later version.
dece6358
AM
22161+ *
22162+ * This program is distributed in the hope that it will be useful,
22163+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22164+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22165+ * GNU General Public License for more details.
22166+ *
22167+ * You should have received a copy of the GNU General Public License
523b37e3 22168+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22169+ */
22170+
22171+/*
4a4d8108 22172+ * inode operations (del entry)
1308ab2a 22173+ */
dece6358 22174+
1308ab2a 22175+#include "aufs.h"
dece6358 22176+
4a4d8108
AM
22177+/*
22178+ * decide if a new whiteout for @dentry is necessary or not.
22179+ * when it is necessary, prepare the parent dir for the upper branch whose
22180+ * branch index is @bcpup for creation. the actual creation of the whiteout will
22181+ * be done by caller.
22182+ * return value:
22183+ * 0: wh is unnecessary
22184+ * plus: wh is necessary
22185+ * minus: error
22186+ */
22187+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 22188+{
4a4d8108 22189+ int need_wh, err;
5afbbe0d 22190+ aufs_bindex_t btop;
4a4d8108 22191+ struct super_block *sb;
dece6358 22192+
4a4d8108 22193+ sb = dentry->d_sb;
5afbbe0d 22194+ btop = au_dbtop(dentry);
4a4d8108 22195+ if (*bcpup < 0) {
5afbbe0d
AM
22196+ *bcpup = btop;
22197+ if (au_test_ro(sb, btop, d_inode(dentry))) {
4a4d8108
AM
22198+ err = AuWbrCopyup(au_sbi(sb), dentry);
22199+ *bcpup = err;
22200+ if (unlikely(err < 0))
22201+ goto out;
22202+ }
22203+ } else
5afbbe0d 22204+ AuDebugOn(btop < *bcpup
5527c038 22205+ || au_test_ro(sb, *bcpup, d_inode(dentry)));
5afbbe0d 22206+ AuDbg("bcpup %d, btop %d\n", *bcpup, btop);
1308ab2a 22207+
5afbbe0d 22208+ if (*bcpup != btop) {
4a4d8108
AM
22209+ err = au_cpup_dirs(dentry, *bcpup);
22210+ if (unlikely(err))
22211+ goto out;
22212+ need_wh = 1;
22213+ } else {
027c5e7a 22214+ struct au_dinfo *dinfo, *tmp;
4a4d8108 22215+
027c5e7a
AM
22216+ need_wh = -ENOMEM;
22217+ dinfo = au_di(dentry);
22218+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
22219+ if (tmp) {
22220+ au_di_cp(tmp, dinfo);
22221+ au_di_swap(tmp, dinfo);
22222+ /* returns the number of positive dentries */
5afbbe0d
AM
22223+ need_wh = au_lkup_dentry(dentry, btop + 1,
22224+ /* AuLkup_IGNORE_PERM */ 0);
027c5e7a
AM
22225+ au_di_swap(tmp, dinfo);
22226+ au_rw_write_unlock(&tmp->di_rwsem);
22227+ au_di_free(tmp);
4a4d8108
AM
22228+ }
22229+ }
22230+ AuDbg("need_wh %d\n", need_wh);
22231+ err = need_wh;
22232+
4f0767ce 22233+out:
4a4d8108 22234+ return err;
1facf9fc 22235+}
22236+
4a4d8108
AM
22237+/*
22238+ * simple tests for the del-entry operations.
22239+ * following the checks in vfs, plus the parent-child relationship.
22240+ */
22241+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
22242+ struct dentry *h_parent, int isdir)
1facf9fc 22243+{
4a4d8108
AM
22244+ int err;
22245+ umode_t h_mode;
22246+ struct dentry *h_dentry, *h_latest;
1308ab2a 22247+ struct inode *h_inode;
1facf9fc 22248+
4a4d8108 22249+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 22250+ if (d_really_is_positive(dentry)) {
4a4d8108 22251+ err = -ENOENT;
5527c038
JR
22252+ if (unlikely(d_is_negative(h_dentry)))
22253+ goto out;
22254+ h_inode = d_inode(h_dentry);
22255+ if (unlikely(!h_inode->i_nlink))
4a4d8108 22256+ goto out;
1facf9fc 22257+
4a4d8108
AM
22258+ h_mode = h_inode->i_mode;
22259+ if (!isdir) {
22260+ err = -EISDIR;
22261+ if (unlikely(S_ISDIR(h_mode)))
22262+ goto out;
22263+ } else if (unlikely(!S_ISDIR(h_mode))) {
22264+ err = -ENOTDIR;
22265+ goto out;
22266+ }
22267+ } else {
22268+ /* rename(2) case */
22269+ err = -EIO;
5527c038 22270+ if (unlikely(d_is_positive(h_dentry)))
4a4d8108
AM
22271+ goto out;
22272+ }
1facf9fc 22273+
4a4d8108
AM
22274+ err = -ENOENT;
22275+ /* expected parent dir is locked */
22276+ if (unlikely(h_parent != h_dentry->d_parent))
22277+ goto out;
22278+ err = 0;
22279+
22280+ /*
22281+ * rmdir a dir may break the consistency on some filesystem.
22282+ * let's try heavy test.
22283+ */
22284+ err = -EACCES;
076b876e 22285+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
5527c038 22286+ && au_test_h_perm(d_inode(h_parent),
076b876e 22287+ MAY_EXEC | MAY_WRITE)))
4a4d8108
AM
22288+ goto out;
22289+
076b876e 22290+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
4a4d8108
AM
22291+ err = -EIO;
22292+ if (IS_ERR(h_latest))
22293+ goto out;
22294+ if (h_latest == h_dentry)
22295+ err = 0;
22296+ dput(h_latest);
22297+
4f0767ce 22298+out:
4a4d8108 22299+ return err;
1308ab2a 22300+}
1facf9fc 22301+
4a4d8108
AM
22302+/*
22303+ * decide the branch where we operate for @dentry. the branch index will be set
acd2b654 22304+ * @rbcpup. after deciding it, 'pin' it and store the timestamps of the parent
4a4d8108
AM
22305+ * dir for reverting.
22306+ * when a new whiteout is necessary, create it.
22307+ */
22308+static struct dentry*
22309+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
22310+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 22311+{
4a4d8108
AM
22312+ struct dentry *wh_dentry;
22313+ struct super_block *sb;
22314+ struct path h_path;
22315+ int err, need_wh;
22316+ unsigned int udba;
22317+ aufs_bindex_t bcpup;
dece6358 22318+
4a4d8108
AM
22319+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
22320+ wh_dentry = ERR_PTR(need_wh);
22321+ if (unlikely(need_wh < 0))
22322+ goto out;
22323+
22324+ sb = dentry->d_sb;
22325+ udba = au_opt_udba(sb);
22326+ bcpup = *rbcpup;
22327+ err = au_pin(pin, dentry, bcpup, udba,
22328+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
22329+ wh_dentry = ERR_PTR(err);
22330+ if (unlikely(err))
22331+ goto out;
22332+
22333+ h_path.dentry = au_pinned_h_parent(pin);
22334+ if (udba != AuOpt_UDBA_NONE
5afbbe0d 22335+ && au_dbtop(dentry) == bcpup) {
4a4d8108
AM
22336+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
22337+ wh_dentry = ERR_PTR(err);
22338+ if (unlikely(err))
22339+ goto out_unpin;
22340+ }
22341+
22342+ h_path.mnt = au_sbr_mnt(sb, bcpup);
22343+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
22344+ wh_dentry = NULL;
22345+ if (!need_wh)
22346+ goto out; /* success, no need to create whiteout */
22347+
22348+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
22349+ if (IS_ERR(wh_dentry))
22350+ goto out_unpin;
22351+
22352+ /* returns with the parent is locked and wh_dentry is dget-ed */
22353+ goto out; /* success */
22354+
4f0767ce 22355+out_unpin:
4a4d8108 22356+ au_unpin(pin);
4f0767ce 22357+out:
4a4d8108 22358+ return wh_dentry;
1facf9fc 22359+}
22360+
4a4d8108
AM
22361+/*
22362+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
22363+ * in order to be revertible and save time for removing many child whiteouts
22364+ * under the dir.
22365+ * returns 1 when there are too many child whiteout and caller should remove
22366+ * them asynchronously. returns 0 when the number of children is enough small to
22367+ * remove now or the branch fs is a remote fs.
22368+ * otherwise return an error.
22369+ */
22370+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
22371+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 22372+{
4a4d8108
AM
22373+ int rmdir_later, err, dirwh;
22374+ struct dentry *h_dentry;
22375+ struct super_block *sb;
5527c038 22376+ struct inode *inode;
4a4d8108
AM
22377+
22378+ sb = dentry->d_sb;
22379+ SiMustAnyLock(sb);
22380+ h_dentry = au_h_dptr(dentry, bindex);
22381+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
22382+ if (unlikely(err))
22383+ goto out;
22384+
22385+ /* stop monitoring */
5527c038
JR
22386+ inode = d_inode(dentry);
22387+ au_hn_free(au_hi(inode, bindex));
4a4d8108
AM
22388+
22389+ if (!au_test_fs_remote(h_dentry->d_sb)) {
22390+ dirwh = au_sbi(sb)->si_dirwh;
22391+ rmdir_later = (dirwh <= 1);
22392+ if (!rmdir_later)
22393+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
22394+ dirwh);
22395+ if (rmdir_later)
22396+ return rmdir_later;
22397+ }
1facf9fc 22398+
4a4d8108
AM
22399+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
22400+ if (unlikely(err)) {
523b37e3
AM
22401+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
22402+ h_dentry, bindex, err);
4a4d8108
AM
22403+ err = 0;
22404+ }
dece6358 22405+
4f0767ce 22406+out:
4a4d8108
AM
22407+ AuTraceErr(err);
22408+ return err;
22409+}
1308ab2a 22410+
4a4d8108
AM
22411+/*
22412+ * final procedure for deleting a entry.
22413+ * maintain dentry and iattr.
22414+ */
22415+static void epilog(struct inode *dir, struct dentry *dentry,
22416+ aufs_bindex_t bindex)
22417+{
22418+ struct inode *inode;
1308ab2a 22419+
5527c038 22420+ inode = d_inode(dentry);
4a4d8108
AM
22421+ d_drop(dentry);
22422+ inode->i_ctime = dir->i_ctime;
1308ab2a 22423+
b912730e 22424+ au_dir_ts(dir, bindex);
be118d29 22425+ inode_inc_iversion(dir);
1facf9fc 22426+}
22427+
4a4d8108
AM
22428+/*
22429+ * when an error happened, remove the created whiteout and revert everything.
22430+ */
7f207e10
AM
22431+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
22432+ aufs_bindex_t bwh, struct dentry *wh_dentry,
22433+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 22434+{
4a4d8108
AM
22435+ int rerr;
22436+ struct path h_path = {
22437+ .dentry = wh_dentry,
7f207e10 22438+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 22439+ };
dece6358 22440+
7f207e10 22441+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
22442+ if (!rerr) {
22443+ au_set_dbwh(dentry, bwh);
22444+ au_dtime_revert(dt);
22445+ return 0;
22446+ }
dece6358 22447+
523b37e3 22448+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 22449+ return -EIO;
1facf9fc 22450+}
22451+
4a4d8108 22452+/* ---------------------------------------------------------------------- */
1facf9fc 22453+
4a4d8108 22454+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 22455+{
4a4d8108 22456+ int err;
5afbbe0d 22457+ aufs_bindex_t bwh, bindex, btop;
523b37e3 22458+ struct inode *inode, *h_dir, *delegated;
4a4d8108 22459+ struct dentry *parent, *wh_dentry;
acd2b654 22460+ /* to reduce stack size */
c2b27bf2
AM
22461+ struct {
22462+ struct au_dtime dt;
22463+ struct au_pin pin;
22464+ struct path h_path;
22465+ } *a;
1facf9fc 22466+
4a4d8108 22467+ IMustLock(dir);
027c5e7a 22468+
c2b27bf2
AM
22469+ err = -ENOMEM;
22470+ a = kmalloc(sizeof(*a), GFP_NOFS);
22471+ if (unlikely(!a))
22472+ goto out;
22473+
027c5e7a
AM
22474+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
22475+ if (unlikely(err))
c2b27bf2 22476+ goto out_free;
027c5e7a
AM
22477+ err = au_d_hashed_positive(dentry);
22478+ if (unlikely(err))
22479+ goto out_unlock;
5527c038 22480+ inode = d_inode(dentry);
4a4d8108 22481+ IMustLock(inode);
027c5e7a 22482+ err = -EISDIR;
2000de60 22483+ if (unlikely(d_is_dir(dentry)))
027c5e7a 22484+ goto out_unlock; /* possible? */
1facf9fc 22485+
5afbbe0d 22486+ btop = au_dbtop(dentry);
4a4d8108
AM
22487+ bwh = au_dbwh(dentry);
22488+ bindex = -1;
027c5e7a
AM
22489+ parent = dentry->d_parent; /* dir inode is locked */
22490+ di_write_lock_parent(parent);
c2b27bf2
AM
22491+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
22492+ &a->pin);
4a4d8108
AM
22493+ err = PTR_ERR(wh_dentry);
22494+ if (IS_ERR(wh_dentry))
027c5e7a 22495+ goto out_parent;
1facf9fc 22496+
5afbbe0d
AM
22497+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, btop);
22498+ a->h_path.dentry = au_h_dptr(dentry, btop);
c2b27bf2 22499+ dget(a->h_path.dentry);
5afbbe0d 22500+ if (bindex == btop) {
c2b27bf2 22501+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
22502+ delegated = NULL;
22503+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
22504+ if (unlikely(err == -EWOULDBLOCK)) {
22505+ pr_warn("cannot retry for NFSv4 delegation"
22506+ " for an internal unlink\n");
22507+ iput(delegated);
22508+ }
4a4d8108
AM
22509+ } else {
22510+ /* dir inode is locked */
5527c038 22511+ h_dir = d_inode(wh_dentry->d_parent);
4a4d8108
AM
22512+ IMustLock(h_dir);
22513+ err = 0;
22514+ }
dece6358 22515+
4a4d8108 22516+ if (!err) {
7f207e10 22517+ vfsub_drop_nlink(inode);
4a4d8108
AM
22518+ epilog(dir, dentry, bindex);
22519+
22520+ /* update target timestamps */
5afbbe0d 22521+ if (bindex == btop) {
c2b27bf2
AM
22522+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
22523+ /*ignore*/
5527c038 22524+ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
4a4d8108
AM
22525+ } else
22526+ /* todo: this timestamp may be reverted later */
22527+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 22528+ goto out_unpin; /* success */
1facf9fc 22529+ }
22530+
4a4d8108
AM
22531+ /* revert */
22532+ if (wh_dentry) {
22533+ int rerr;
22534+
c2b27bf2
AM
22535+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
22536+ &a->dt);
4a4d8108
AM
22537+ if (rerr)
22538+ err = rerr;
dece6358 22539+ }
1facf9fc 22540+
027c5e7a 22541+out_unpin:
c2b27bf2 22542+ au_unpin(&a->pin);
4a4d8108 22543+ dput(wh_dentry);
c2b27bf2 22544+ dput(a->h_path.dentry);
027c5e7a 22545+out_parent:
4a4d8108 22546+ di_write_unlock(parent);
027c5e7a 22547+out_unlock:
4a4d8108 22548+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 22549+out_free:
1c60b727 22550+ kfree(a);
027c5e7a 22551+out:
4a4d8108 22552+ return err;
dece6358
AM
22553+}
22554+
4a4d8108 22555+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 22556+{
4a4d8108 22557+ int err, rmdir_later;
5afbbe0d 22558+ aufs_bindex_t bwh, bindex, btop;
4a4d8108
AM
22559+ struct inode *inode;
22560+ struct dentry *parent, *wh_dentry, *h_dentry;
22561+ struct au_whtmp_rmdir *args;
acd2b654 22562+ /* to reduce stack size */
c2b27bf2
AM
22563+ struct {
22564+ struct au_dtime dt;
22565+ struct au_pin pin;
22566+ } *a;
1facf9fc 22567+
4a4d8108 22568+ IMustLock(dir);
027c5e7a 22569+
c2b27bf2
AM
22570+ err = -ENOMEM;
22571+ a = kmalloc(sizeof(*a), GFP_NOFS);
22572+ if (unlikely(!a))
22573+ goto out;
22574+
027c5e7a
AM
22575+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
22576+ if (unlikely(err))
c2b27bf2 22577+ goto out_free;
53392da6
AM
22578+ err = au_alive_dir(dentry);
22579+ if (unlikely(err))
027c5e7a 22580+ goto out_unlock;
5527c038 22581+ inode = d_inode(dentry);
4a4d8108 22582+ IMustLock(inode);
027c5e7a 22583+ err = -ENOTDIR;
2000de60 22584+ if (unlikely(!d_is_dir(dentry)))
027c5e7a 22585+ goto out_unlock; /* possible? */
dece6358 22586+
4a4d8108
AM
22587+ err = -ENOMEM;
22588+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
22589+ if (unlikely(!args))
22590+ goto out_unlock;
dece6358 22591+
4a4d8108
AM
22592+ parent = dentry->d_parent; /* dir inode is locked */
22593+ di_write_lock_parent(parent);
22594+ err = au_test_empty(dentry, &args->whlist);
22595+ if (unlikely(err))
027c5e7a 22596+ goto out_parent;
1facf9fc 22597+
5afbbe0d 22598+ btop = au_dbtop(dentry);
4a4d8108
AM
22599+ bwh = au_dbwh(dentry);
22600+ bindex = -1;
c2b27bf2
AM
22601+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
22602+ &a->pin);
4a4d8108
AM
22603+ err = PTR_ERR(wh_dentry);
22604+ if (IS_ERR(wh_dentry))
027c5e7a 22605+ goto out_parent;
1facf9fc 22606+
5afbbe0d 22607+ h_dentry = au_h_dptr(dentry, btop);
4a4d8108
AM
22608+ dget(h_dentry);
22609+ rmdir_later = 0;
5afbbe0d
AM
22610+ if (bindex == btop) {
22611+ err = renwh_and_rmdir(dentry, btop, &args->whlist, dir);
4a4d8108
AM
22612+ if (err > 0) {
22613+ rmdir_later = err;
22614+ err = 0;
22615+ }
22616+ } else {
22617+ /* stop monitoring */
5afbbe0d 22618+ au_hn_free(au_hi(inode, btop));
4a4d8108
AM
22619+
22620+ /* dir inode is locked */
5527c038 22621+ IMustLock(d_inode(wh_dentry->d_parent));
1facf9fc 22622+ err = 0;
22623+ }
22624+
4a4d8108 22625+ if (!err) {
027c5e7a 22626+ vfsub_dead_dir(inode);
4a4d8108
AM
22627+ au_set_dbdiropq(dentry, -1);
22628+ epilog(dir, dentry, bindex);
1308ab2a 22629+
4a4d8108 22630+ if (rmdir_later) {
5afbbe0d 22631+ au_whtmp_kick_rmdir(dir, btop, h_dentry, args);
4a4d8108
AM
22632+ args = NULL;
22633+ }
1308ab2a 22634+
4a4d8108 22635+ goto out_unpin; /* success */
1facf9fc 22636+ }
22637+
4a4d8108
AM
22638+ /* revert */
22639+ AuLabel(revert);
22640+ if (wh_dentry) {
22641+ int rerr;
1308ab2a 22642+
c2b27bf2
AM
22643+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
22644+ &a->dt);
4a4d8108
AM
22645+ if (rerr)
22646+ err = rerr;
1facf9fc 22647+ }
22648+
4f0767ce 22649+out_unpin:
c2b27bf2 22650+ au_unpin(&a->pin);
4a4d8108
AM
22651+ dput(wh_dentry);
22652+ dput(h_dentry);
027c5e7a 22653+out_parent:
4a4d8108
AM
22654+ di_write_unlock(parent);
22655+ if (args)
22656+ au_whtmp_rmdir_free(args);
4f0767ce 22657+out_unlock:
4a4d8108 22658+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 22659+out_free:
1c60b727 22660+ kfree(a);
4f0767ce 22661+out:
4a4d8108
AM
22662+ AuTraceErr(err);
22663+ return err;
dece6358 22664+}
7f207e10
AM
22665diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
22666--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
22667+++ linux/fs/aufs/i_op_ren.c 2018-10-23 12:33:35.599375796 +0200
22668@@ -0,0 +1,1249 @@
cd7a4cd9 22669+// SPDX-License-Identifier: GPL-2.0
1facf9fc 22670+/*
b00004a5 22671+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 22672+ *
22673+ * This program, aufs is free software; you can redistribute it and/or modify
22674+ * it under the terms of the GNU General Public License as published by
22675+ * the Free Software Foundation; either version 2 of the License, or
22676+ * (at your option) any later version.
dece6358
AM
22677+ *
22678+ * This program is distributed in the hope that it will be useful,
22679+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22680+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22681+ * GNU General Public License for more details.
22682+ *
22683+ * You should have received a copy of the GNU General Public License
523b37e3 22684+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22685+ */
22686+
22687+/*
4a4d8108
AM
22688+ * inode operation (rename entry)
22689+ * todo: this is crazy monster
1facf9fc 22690+ */
22691+
22692+#include "aufs.h"
22693+
4a4d8108
AM
22694+enum { AuSRC, AuDST, AuSrcDst };
22695+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 22696+
f2c43d5f
AM
22697+#define AuRen_ISDIR_SRC 1
22698+#define AuRen_ISDIR_DST (1 << 1)
22699+#define AuRen_ISSAMEDIR (1 << 2)
22700+#define AuRen_WHSRC (1 << 3)
22701+#define AuRen_WHDST (1 << 4)
22702+#define AuRen_MNT_WRITE (1 << 5)
22703+#define AuRen_DT_DSTDIR (1 << 6)
22704+#define AuRen_DIROPQ_SRC (1 << 7)
22705+#define AuRen_DIROPQ_DST (1 << 8)
8b6a4947
AM
22706+#define AuRen_DIRREN (1 << 9)
22707+#define AuRen_DROPPED_SRC (1 << 10)
22708+#define AuRen_DROPPED_DST (1 << 11)
4a4d8108 22709+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
22710+#define au_fset_ren(flags, name) \
22711+ do { (flags) |= AuRen_##name; } while (0)
22712+#define au_fclr_ren(flags, name) \
22713+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 22714+
8b6a4947
AM
22715+#ifndef CONFIG_AUFS_DIRREN
22716+#undef AuRen_DIRREN
22717+#define AuRen_DIRREN 0
22718+#endif
22719+
4a4d8108
AM
22720+struct au_ren_args {
22721+ struct {
22722+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
22723+ *wh_dentry;
22724+ struct inode *dir, *inode;
f2c43d5f 22725+ struct au_hinode *hdir, *hinode;
4a4d8108 22726+ struct au_dtime dt[AuParentChild];
f2c43d5f 22727+ aufs_bindex_t btop, bdiropq;
4a4d8108 22728+ } sd[AuSrcDst];
1facf9fc 22729+
4a4d8108
AM
22730+#define src_dentry sd[AuSRC].dentry
22731+#define src_dir sd[AuSRC].dir
22732+#define src_inode sd[AuSRC].inode
22733+#define src_h_dentry sd[AuSRC].h_dentry
22734+#define src_parent sd[AuSRC].parent
22735+#define src_h_parent sd[AuSRC].h_parent
22736+#define src_wh_dentry sd[AuSRC].wh_dentry
22737+#define src_hdir sd[AuSRC].hdir
f2c43d5f 22738+#define src_hinode sd[AuSRC].hinode
4a4d8108
AM
22739+#define src_h_dir sd[AuSRC].hdir->hi_inode
22740+#define src_dt sd[AuSRC].dt
5afbbe0d 22741+#define src_btop sd[AuSRC].btop
f2c43d5f 22742+#define src_bdiropq sd[AuSRC].bdiropq
1facf9fc 22743+
4a4d8108
AM
22744+#define dst_dentry sd[AuDST].dentry
22745+#define dst_dir sd[AuDST].dir
22746+#define dst_inode sd[AuDST].inode
22747+#define dst_h_dentry sd[AuDST].h_dentry
22748+#define dst_parent sd[AuDST].parent
22749+#define dst_h_parent sd[AuDST].h_parent
22750+#define dst_wh_dentry sd[AuDST].wh_dentry
22751+#define dst_hdir sd[AuDST].hdir
f2c43d5f 22752+#define dst_hinode sd[AuDST].hinode
4a4d8108
AM
22753+#define dst_h_dir sd[AuDST].hdir->hi_inode
22754+#define dst_dt sd[AuDST].dt
5afbbe0d 22755+#define dst_btop sd[AuDST].btop
f2c43d5f 22756+#define dst_bdiropq sd[AuDST].bdiropq
4a4d8108
AM
22757+
22758+ struct dentry *h_trap;
22759+ struct au_branch *br;
4a4d8108
AM
22760+ struct path h_path;
22761+ struct au_nhash whlist;
f2c43d5f 22762+ aufs_bindex_t btgt, src_bwh;
1facf9fc 22763+
f2c43d5f
AM
22764+ struct {
22765+ unsigned short auren_flags;
22766+ unsigned char flags; /* syscall parameter */
22767+ unsigned char exchange;
22768+ } __packed;
1facf9fc 22769+
4a4d8108
AM
22770+ struct au_whtmp_rmdir *thargs;
22771+ struct dentry *h_dst;
8b6a4947 22772+ struct au_hinode *h_root;
4a4d8108 22773+};
1308ab2a 22774+
4a4d8108 22775+/* ---------------------------------------------------------------------- */
1308ab2a 22776+
4a4d8108
AM
22777+/*
22778+ * functions for reverting.
22779+ * when an error happened in a single rename systemcall, we should revert
79b8bda9 22780+ * everything as if nothing happened.
4a4d8108
AM
22781+ * we don't need to revert the copied-up/down the parent dir since they are
22782+ * harmless.
22783+ */
1facf9fc 22784+
4a4d8108
AM
22785+#define RevertFailure(fmt, ...) do { \
22786+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
22787+ ##__VA_ARGS__, err, rerr); \
22788+ err = -EIO; \
22789+} while (0)
1facf9fc 22790+
f2c43d5f 22791+static void au_ren_do_rev_diropq(int err, struct au_ren_args *a, int idx)
1facf9fc 22792+{
4a4d8108 22793+ int rerr;
f2c43d5f
AM
22794+ struct dentry *d;
22795+#define src_or_dst(member) a->sd[idx].member
1facf9fc 22796+
f2c43d5f
AM
22797+ d = src_or_dst(dentry); /* {src,dst}_dentry */
22798+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD);
22799+ rerr = au_diropq_remove(d, a->btgt);
22800+ au_hn_inode_unlock(src_or_dst(hinode));
22801+ au_set_dbdiropq(d, src_or_dst(bdiropq));
4a4d8108 22802+ if (rerr)
f2c43d5f
AM
22803+ RevertFailure("remove diropq %pd", d);
22804+
22805+#undef src_or_dst_
22806+}
22807+
22808+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
22809+{
22810+ if (au_ftest_ren(a->auren_flags, DIROPQ_SRC))
22811+ au_ren_do_rev_diropq(err, a, AuSRC);
22812+ if (au_ftest_ren(a->auren_flags, DIROPQ_DST))
22813+ au_ren_do_rev_diropq(err, a, AuDST);
4a4d8108 22814+}
1facf9fc 22815+
4a4d8108
AM
22816+static void au_ren_rev_rename(int err, struct au_ren_args *a)
22817+{
22818+ int rerr;
523b37e3 22819+ struct inode *delegated;
1facf9fc 22820+
b4510431
AM
22821+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
22822+ a->src_h_parent);
4a4d8108
AM
22823+ rerr = PTR_ERR(a->h_path.dentry);
22824+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 22825+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 22826+ return;
1facf9fc 22827+ }
22828+
523b37e3 22829+ delegated = NULL;
4a4d8108
AM
22830+ rerr = vfsub_rename(a->dst_h_dir,
22831+ au_h_dptr(a->src_dentry, a->btgt),
f2c43d5f 22832+ a->src_h_dir, &a->h_path, &delegated, a->flags);
523b37e3
AM
22833+ if (unlikely(rerr == -EWOULDBLOCK)) {
22834+ pr_warn("cannot retry for NFSv4 delegation"
22835+ " for an internal rename\n");
22836+ iput(delegated);
22837+ }
4a4d8108
AM
22838+ d_drop(a->h_path.dentry);
22839+ dput(a->h_path.dentry);
22840+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
22841+ if (rerr)
523b37e3 22842+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 22843+}
22844+
4a4d8108 22845+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 22846+{
4a4d8108 22847+ int rerr;
523b37e3 22848+ struct inode *delegated;
dece6358 22849+
b4510431
AM
22850+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
22851+ a->dst_h_parent);
4a4d8108
AM
22852+ rerr = PTR_ERR(a->h_path.dentry);
22853+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 22854+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
22855+ return;
22856+ }
5527c038 22857+ if (d_is_positive(a->h_path.dentry)) {
4a4d8108
AM
22858+ d_drop(a->h_path.dentry);
22859+ dput(a->h_path.dentry);
22860+ return;
dece6358
AM
22861+ }
22862+
523b37e3
AM
22863+ delegated = NULL;
22864+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
f2c43d5f 22865+ &delegated, a->flags);
523b37e3
AM
22866+ if (unlikely(rerr == -EWOULDBLOCK)) {
22867+ pr_warn("cannot retry for NFSv4 delegation"
22868+ " for an internal rename\n");
22869+ iput(delegated);
22870+ }
4a4d8108
AM
22871+ d_drop(a->h_path.dentry);
22872+ dput(a->h_path.dentry);
22873+ if (!rerr)
22874+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
22875+ else
523b37e3 22876+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 22877+}
1308ab2a 22878+
4a4d8108
AM
22879+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
22880+{
22881+ int rerr;
1308ab2a 22882+
4a4d8108
AM
22883+ a->h_path.dentry = a->src_wh_dentry;
22884+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 22885+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 22886+ if (rerr)
523b37e3 22887+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 22888+}
4a4d8108 22889+#undef RevertFailure
1facf9fc 22890+
1308ab2a 22891+/* ---------------------------------------------------------------------- */
22892+
4a4d8108
AM
22893+/*
22894+ * when we have to copyup the renaming entry, do it with the rename-target name
22895+ * in order to minimize the cost (the later actual rename is unnecessary).
22896+ * otherwise rename it on the target branch.
22897+ */
22898+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 22899+{
dece6358 22900+ int err;
4a4d8108 22901+ struct dentry *d;
523b37e3 22902+ struct inode *delegated;
1facf9fc 22903+
4a4d8108 22904+ d = a->src_dentry;
5afbbe0d 22905+ if (au_dbtop(d) == a->btgt) {
4a4d8108 22906+ a->h_path.dentry = a->dst_h_dentry;
5afbbe0d 22907+ AuDebugOn(au_dbtop(d) != a->btgt);
523b37e3 22908+ delegated = NULL;
4a4d8108 22909+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
f2c43d5f
AM
22910+ a->dst_h_dir, &a->h_path, &delegated,
22911+ a->flags);
523b37e3
AM
22912+ if (unlikely(err == -EWOULDBLOCK)) {
22913+ pr_warn("cannot retry for NFSv4 delegation"
22914+ " for an internal rename\n");
22915+ iput(delegated);
22916+ }
c2b27bf2 22917+ } else
86dc4139 22918+ BUG();
1308ab2a 22919+
027c5e7a
AM
22920+ if (!err && a->h_dst)
22921+ /* it will be set to dinfo later */
22922+ dget(a->h_dst);
1facf9fc 22923+
dece6358
AM
22924+ return err;
22925+}
1facf9fc 22926+
4a4d8108
AM
22927+/* cf. aufs_rmdir() */
22928+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 22929+{
4a4d8108
AM
22930+ int err;
22931+ struct inode *dir;
1facf9fc 22932+
4a4d8108
AM
22933+ dir = a->dst_dir;
22934+ SiMustAnyLock(dir->i_sb);
22935+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
22936+ au_sbi(dir->i_sb)->si_dirwh)
22937+ || au_test_fs_remote(a->h_dst->d_sb)) {
22938+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
22939+ if (unlikely(err))
523b37e3
AM
22940+ pr_warn("failed removing whtmp dir %pd (%d), "
22941+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
22942+ } else {
22943+ au_nhash_wh_free(&a->thargs->whlist);
22944+ a->thargs->whlist = a->whlist;
22945+ a->whlist.nh_num = 0;
22946+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
22947+ dput(a->h_dst);
22948+ a->thargs = NULL;
22949+ }
22950+
22951+ return 0;
1308ab2a 22952+}
1facf9fc 22953+
4a4d8108 22954+/* make it 'opaque' dir. */
f2c43d5f 22955+static int au_ren_do_diropq(struct au_ren_args *a, int idx)
4a4d8108
AM
22956+{
22957+ int err;
f2c43d5f
AM
22958+ struct dentry *d, *diropq;
22959+#define src_or_dst(member) a->sd[idx].member
1facf9fc 22960+
4a4d8108 22961+ err = 0;
f2c43d5f
AM
22962+ d = src_or_dst(dentry); /* {src,dst}_dentry */
22963+ src_or_dst(bdiropq) = au_dbdiropq(d);
22964+ src_or_dst(hinode) = au_hi(src_or_dst(inode), a->btgt);
22965+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD);
22966+ diropq = au_diropq_create(d, a->btgt);
22967+ au_hn_inode_unlock(src_or_dst(hinode));
4a4d8108
AM
22968+ if (IS_ERR(diropq))
22969+ err = PTR_ERR(diropq);
076b876e
AM
22970+ else
22971+ dput(diropq);
1facf9fc 22972+
f2c43d5f 22973+#undef src_or_dst_
4a4d8108
AM
22974+ return err;
22975+}
1facf9fc 22976+
f2c43d5f 22977+static int au_ren_diropq(struct au_ren_args *a)
4a4d8108
AM
22978+{
22979+ int err;
f2c43d5f
AM
22980+ unsigned char always;
22981+ struct dentry *d;
1facf9fc 22982+
f2c43d5f
AM
22983+ err = 0;
22984+ d = a->dst_dentry; /* already renamed on the branch */
22985+ always = !!au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ);
22986+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)
8b6a4947 22987+ && !au_ftest_ren(a->auren_flags, DIRREN)
f2c43d5f
AM
22988+ && a->btgt != au_dbdiropq(a->src_dentry)
22989+ && (a->dst_wh_dentry
22990+ || a->btgt <= au_dbdiropq(d)
22991+ /* hide the lower to keep xino */
22992+ /* the lowers may not be a dir, but we hide them anyway */
22993+ || a->btgt < au_dbbot(d)
22994+ || always)) {
22995+ AuDbg("here\n");
22996+ err = au_ren_do_diropq(a, AuSRC);
22997+ if (unlikely(err))
4a4d8108 22998+ goto out;
f2c43d5f 22999+ au_fset_ren(a->auren_flags, DIROPQ_SRC);
4a4d8108 23000+ }
f2c43d5f
AM
23001+ if (!a->exchange)
23002+ goto out; /* success */
1facf9fc 23003+
f2c43d5f
AM
23004+ d = a->src_dentry; /* already renamed on the branch */
23005+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)
23006+ && a->btgt != au_dbdiropq(a->dst_dentry)
23007+ && (a->btgt < au_dbdiropq(d)
23008+ || a->btgt < au_dbbot(d)
23009+ || always)) {
23010+ AuDbgDentry(a->src_dentry);
23011+ AuDbgDentry(a->dst_dentry);
23012+ err = au_ren_do_diropq(a, AuDST);
4a4d8108 23013+ if (unlikely(err))
f2c43d5f
AM
23014+ goto out_rev_src;
23015+ au_fset_ren(a->auren_flags, DIROPQ_DST);
23016+ }
23017+ goto out; /* success */
dece6358 23018+
f2c43d5f
AM
23019+out_rev_src:
23020+ AuDbg("err %d, reverting src\n", err);
23021+ au_ren_rev_diropq(err, a);
23022+out:
23023+ return err;
23024+}
23025+
23026+static int do_rename(struct au_ren_args *a)
23027+{
23028+ int err;
23029+ struct dentry *d, *h_d;
23030+
23031+ if (!a->exchange) {
23032+ /* prepare workqueue args for asynchronous rmdir */
23033+ h_d = a->dst_h_dentry;
23034+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)
8b6a4947 23035+ /* && !au_ftest_ren(a->auren_flags, DIRREN) */
f2c43d5f
AM
23036+ && d_is_positive(h_d)) {
23037+ err = -ENOMEM;
23038+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb,
23039+ GFP_NOFS);
23040+ if (unlikely(!a->thargs))
23041+ goto out;
23042+ a->h_dst = dget(h_d);
23043+ }
23044+
23045+ /* create whiteout for src_dentry */
23046+ if (au_ftest_ren(a->auren_flags, WHSRC)) {
23047+ a->src_bwh = au_dbwh(a->src_dentry);
23048+ AuDebugOn(a->src_bwh >= 0);
23049+ a->src_wh_dentry = au_wh_create(a->src_dentry, a->btgt,
23050+ a->src_h_parent);
23051+ err = PTR_ERR(a->src_wh_dentry);
23052+ if (IS_ERR(a->src_wh_dentry))
23053+ goto out_thargs;
23054+ }
23055+
23056+ /* lookup whiteout for dentry */
23057+ if (au_ftest_ren(a->auren_flags, WHDST)) {
23058+ h_d = au_wh_lkup(a->dst_h_parent,
23059+ &a->dst_dentry->d_name, a->br);
23060+ err = PTR_ERR(h_d);
23061+ if (IS_ERR(h_d))
23062+ goto out_whsrc;
23063+ if (d_is_negative(h_d))
23064+ dput(h_d);
23065+ else
23066+ a->dst_wh_dentry = h_d;
23067+ }
23068+
23069+ /* rename dentry to tmpwh */
23070+ if (a->thargs) {
23071+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
23072+ if (unlikely(err))
23073+ goto out_whdst;
23074+
23075+ d = a->dst_dentry;
23076+ au_set_h_dptr(d, a->btgt, NULL);
23077+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
23078+ if (unlikely(err))
23079+ goto out_whtmp;
23080+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
23081+ }
4a4d8108 23082+ }
1facf9fc 23083+
5afbbe0d 23084+ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_btop != a->btgt);
8b6a4947
AM
23085+#if 0
23086+ BUG_ON(!au_ftest_ren(a->auren_flags, DIRREN)
23087+ && d_is_positive(a->dst_h_dentry)
23088+ && a->src_btop != a->btgt);
23089+#endif
1facf9fc 23090+
4a4d8108 23091+ /* rename by vfs_rename or cpup */
4a4d8108
AM
23092+ err = au_ren_or_cpup(a);
23093+ if (unlikely(err))
23094+ /* leave the copied-up one */
23095+ goto out_whtmp;
1308ab2a 23096+
4a4d8108 23097+ /* make dir opaque */
f2c43d5f
AM
23098+ err = au_ren_diropq(a);
23099+ if (unlikely(err))
23100+ goto out_rename;
1308ab2a 23101+
4a4d8108 23102+ /* update target timestamps */
f2c43d5f
AM
23103+ if (a->exchange) {
23104+ AuDebugOn(au_dbtop(a->dst_dentry) != a->btgt);
23105+ a->h_path.dentry = au_h_dptr(a->dst_dentry, a->btgt);
23106+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
23107+ a->dst_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
23108+ }
5afbbe0d 23109+ AuDebugOn(au_dbtop(a->src_dentry) != a->btgt);
4a4d8108
AM
23110+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
23111+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
5527c038 23112+ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
1facf9fc 23113+
f2c43d5f
AM
23114+ if (!a->exchange) {
23115+ /* remove whiteout for dentry */
23116+ if (a->dst_wh_dentry) {
23117+ a->h_path.dentry = a->dst_wh_dentry;
23118+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
23119+ a->dst_dentry);
23120+ if (unlikely(err))
23121+ goto out_diropq;
23122+ }
1facf9fc 23123+
f2c43d5f
AM
23124+ /* remove whtmp */
23125+ if (a->thargs)
23126+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 23127+
f2c43d5f
AM
23128+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
23129+ }
4a4d8108
AM
23130+ err = 0;
23131+ goto out_success;
23132+
4f0767ce 23133+out_diropq:
f2c43d5f 23134+ au_ren_rev_diropq(err, a);
4f0767ce 23135+out_rename:
7e9cd9fe 23136+ au_ren_rev_rename(err, a);
027c5e7a 23137+ dput(a->h_dst);
4f0767ce 23138+out_whtmp:
4a4d8108
AM
23139+ if (a->thargs)
23140+ au_ren_rev_whtmp(err, a);
4f0767ce 23141+out_whdst:
4a4d8108
AM
23142+ dput(a->dst_wh_dentry);
23143+ a->dst_wh_dentry = NULL;
4f0767ce 23144+out_whsrc:
4a4d8108
AM
23145+ if (a->src_wh_dentry)
23146+ au_ren_rev_whsrc(err, a);
4f0767ce 23147+out_success:
4a4d8108
AM
23148+ dput(a->src_wh_dentry);
23149+ dput(a->dst_wh_dentry);
4f0767ce 23150+out_thargs:
4a4d8108
AM
23151+ if (a->thargs) {
23152+ dput(a->h_dst);
23153+ au_whtmp_rmdir_free(a->thargs);
23154+ a->thargs = NULL;
23155+ }
4f0767ce 23156+out:
4a4d8108 23157+ return err;
dece6358 23158+}
1facf9fc 23159+
1308ab2a 23160+/* ---------------------------------------------------------------------- */
1facf9fc 23161+
4a4d8108
AM
23162+/*
23163+ * test if @dentry dir can be rename destination or not.
23164+ * success means, it is a logically empty dir.
23165+ */
23166+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 23167+{
4a4d8108 23168+ return au_test_empty(dentry, whlist);
1308ab2a 23169+}
1facf9fc 23170+
4a4d8108 23171+/*
8b6a4947
AM
23172+ * test if @a->src_dentry dir can be rename source or not.
23173+ * if it can, return 0.
4a4d8108
AM
23174+ * success means,
23175+ * - it is a logically empty dir.
23176+ * - or, it exists on writable branch and has no children including whiteouts
8b6a4947 23177+ * on the lower branch unless DIRREN is on.
4a4d8108 23178+ */
8b6a4947 23179+static int may_rename_srcdir(struct au_ren_args *a)
4a4d8108
AM
23180+{
23181+ int err;
23182+ unsigned int rdhash;
8b6a4947
AM
23183+ aufs_bindex_t btop, btgt;
23184+ struct dentry *dentry;
23185+ struct super_block *sb;
23186+ struct au_sbinfo *sbinfo;
1facf9fc 23187+
8b6a4947
AM
23188+ dentry = a->src_dentry;
23189+ sb = dentry->d_sb;
23190+ sbinfo = au_sbi(sb);
23191+ if (au_opt_test(sbinfo->si_mntflags, DIRREN))
23192+ au_fset_ren(a->auren_flags, DIRREN);
23193+
23194+ btgt = a->btgt;
5afbbe0d
AM
23195+ btop = au_dbtop(dentry);
23196+ if (btop != btgt) {
4a4d8108 23197+ struct au_nhash whlist;
dece6358 23198+
8b6a4947
AM
23199+ SiMustAnyLock(sb);
23200+ rdhash = sbinfo->si_rdhash;
4a4d8108
AM
23201+ if (!rdhash)
23202+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
23203+ dentry));
23204+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
23205+ if (unlikely(err))
23206+ goto out;
23207+ err = au_test_empty(dentry, &whlist);
23208+ au_nhash_wh_free(&whlist);
23209+ goto out;
23210+ }
dece6358 23211+
5afbbe0d 23212+ if (btop == au_dbtaildir(dentry))
4a4d8108 23213+ return 0; /* success */
dece6358 23214+
4a4d8108 23215+ err = au_test_empty_lower(dentry);
1facf9fc 23216+
4f0767ce 23217+out:
4a4d8108 23218+ if (err == -ENOTEMPTY) {
8b6a4947
AM
23219+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23220+ err = 0;
23221+ } else {
23222+ AuWarn1("renaming dir who has child(ren) on multiple "
23223+ "branches, is not supported\n");
23224+ err = -EXDEV;
23225+ }
4a4d8108
AM
23226+ }
23227+ return err;
23228+}
1308ab2a 23229+
4a4d8108
AM
23230+/* side effect: sets whlist and h_dentry */
23231+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 23232+{
4a4d8108
AM
23233+ int err;
23234+ unsigned int rdhash;
23235+ struct dentry *d;
1facf9fc 23236+
4a4d8108
AM
23237+ d = a->dst_dentry;
23238+ SiMustAnyLock(d->d_sb);
1facf9fc 23239+
4a4d8108 23240+ err = 0;
f2c43d5f 23241+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) && a->dst_inode) {
4a4d8108
AM
23242+ rdhash = au_sbi(d->d_sb)->si_rdhash;
23243+ if (!rdhash)
23244+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
23245+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
23246+ if (unlikely(err))
23247+ goto out;
1308ab2a 23248+
f2c43d5f
AM
23249+ if (!a->exchange) {
23250+ au_set_dbtop(d, a->dst_btop);
23251+ err = may_rename_dstdir(d, &a->whlist);
23252+ au_set_dbtop(d, a->btgt);
23253+ } else
8b6a4947 23254+ err = may_rename_srcdir(a);
4a4d8108 23255+ }
5afbbe0d 23256+ a->dst_h_dentry = au_h_dptr(d, au_dbtop(d));
4a4d8108
AM
23257+ if (unlikely(err))
23258+ goto out;
23259+
23260+ d = a->src_dentry;
5afbbe0d 23261+ a->src_h_dentry = au_h_dptr(d, au_dbtop(d));
f2c43d5f 23262+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) {
8b6a4947 23263+ err = may_rename_srcdir(a);
4a4d8108
AM
23264+ if (unlikely(err)) {
23265+ au_nhash_wh_free(&a->whlist);
23266+ a->whlist.nh_num = 0;
23267+ }
23268+ }
4f0767ce 23269+out:
4a4d8108 23270+ return err;
1facf9fc 23271+}
23272+
4a4d8108 23273+/* ---------------------------------------------------------------------- */
1facf9fc 23274+
4a4d8108
AM
23275+/*
23276+ * simple tests for rename.
23277+ * following the checks in vfs, plus the parent-child relationship.
23278+ */
23279+static int au_may_ren(struct au_ren_args *a)
23280+{
23281+ int err, isdir;
23282+ struct inode *h_inode;
1facf9fc 23283+
5afbbe0d 23284+ if (a->src_btop == a->btgt) {
4a4d8108 23285+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
f2c43d5f 23286+ au_ftest_ren(a->auren_flags, ISDIR_SRC));
4a4d8108
AM
23287+ if (unlikely(err))
23288+ goto out;
23289+ err = -EINVAL;
23290+ if (unlikely(a->src_h_dentry == a->h_trap))
23291+ goto out;
23292+ }
1facf9fc 23293+
4a4d8108 23294+ err = 0;
5afbbe0d 23295+ if (a->dst_btop != a->btgt)
4a4d8108 23296+ goto out;
1facf9fc 23297+
027c5e7a
AM
23298+ err = -ENOTEMPTY;
23299+ if (unlikely(a->dst_h_dentry == a->h_trap))
23300+ goto out;
23301+
4a4d8108 23302+ err = -EIO;
f2c43d5f 23303+ isdir = !!au_ftest_ren(a->auren_flags, ISDIR_DST);
5527c038
JR
23304+ if (d_really_is_negative(a->dst_dentry)) {
23305+ if (d_is_negative(a->dst_h_dentry))
23306+ err = au_may_add(a->dst_dentry, a->btgt,
23307+ a->dst_h_parent, isdir);
4a4d8108 23308+ } else {
5527c038 23309+ if (unlikely(d_is_negative(a->dst_h_dentry)))
4a4d8108 23310+ goto out;
5527c038
JR
23311+ h_inode = d_inode(a->dst_h_dentry);
23312+ if (h_inode->i_nlink)
23313+ err = au_may_del(a->dst_dentry, a->btgt,
23314+ a->dst_h_parent, isdir);
4a4d8108 23315+ }
1facf9fc 23316+
4f0767ce 23317+out:
4a4d8108
AM
23318+ if (unlikely(err == -ENOENT || err == -EEXIST))
23319+ err = -EIO;
23320+ AuTraceErr(err);
23321+ return err;
23322+}
1facf9fc 23323+
1308ab2a 23324+/* ---------------------------------------------------------------------- */
1facf9fc 23325+
4a4d8108
AM
23326+/*
23327+ * locking order
23328+ * (VFS)
23329+ * - src_dir and dir by lock_rename()
acd2b654 23330+ * - inode if exists
4a4d8108
AM
23331+ * (aufs)
23332+ * - lock all
23333+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
23334+ * + si_read_lock
23335+ * + di_write_lock2_child()
23336+ * + di_write_lock_child()
23337+ * + ii_write_lock_child()
23338+ * + di_write_lock_child2()
23339+ * + ii_write_lock_child2()
23340+ * + src_parent and parent
23341+ * + di_write_lock_parent()
23342+ * + ii_write_lock_parent()
23343+ * + di_write_lock_parent2()
23344+ * + ii_write_lock_parent2()
23345+ * + lower src_dir and dir by vfsub_lock_rename()
23346+ * + verify the every relationships between child and parent. if any
23347+ * of them failed, unlock all and return -EBUSY.
23348+ */
23349+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 23350+{
4a4d8108
AM
23351+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
23352+ a->dst_h_parent, a->dst_hdir);
8b6a4947
AM
23353+ if (au_ftest_ren(a->auren_flags, DIRREN)
23354+ && a->h_root)
23355+ au_hn_inode_unlock(a->h_root);
f2c43d5f 23356+ if (au_ftest_ren(a->auren_flags, MNT_WRITE))
86dc4139 23357+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 23358+}
23359+
4a4d8108 23360+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 23361+{
4a4d8108
AM
23362+ int err;
23363+ unsigned int udba;
1308ab2a 23364+
4a4d8108
AM
23365+ err = 0;
23366+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
23367+ a->src_hdir = au_hi(a->src_dir, a->btgt);
23368+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
23369+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
23370+
23371+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
23372+ if (unlikely(err))
23373+ goto out;
f2c43d5f 23374+ au_fset_ren(a->auren_flags, MNT_WRITE);
8b6a4947
AM
23375+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23376+ struct dentry *root;
23377+ struct inode *dir;
23378+
23379+ /*
23380+ * sbinfo is already locked, so this ii_read_lock is
23381+ * unnecessary. but our debugging feature checks it.
23382+ */
23383+ root = a->src_inode->i_sb->s_root;
23384+ if (root != a->src_parent && root != a->dst_parent) {
23385+ dir = d_inode(root);
23386+ ii_read_lock_parent3(dir);
23387+ a->h_root = au_hi(dir, a->btgt);
23388+ ii_read_unlock(dir);
23389+ au_hn_inode_lock_nested(a->h_root, AuLsc_I_PARENT3);
23390+ }
23391+ }
4a4d8108
AM
23392+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
23393+ a->dst_h_parent, a->dst_hdir);
23394+ udba = au_opt_udba(a->src_dentry->d_sb);
5527c038
JR
23395+ if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent)
23396+ || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent)))
4a4d8108 23397+ err = au_busy_or_stale();
5afbbe0d 23398+ if (!err && au_dbtop(a->src_dentry) == a->btgt)
4a4d8108 23399+ err = au_h_verify(a->src_h_dentry, udba,
5527c038 23400+ d_inode(a->src_h_parent), a->src_h_parent,
4a4d8108 23401+ a->br);
5afbbe0d 23402+ if (!err && au_dbtop(a->dst_dentry) == a->btgt)
4a4d8108 23403+ err = au_h_verify(a->dst_h_dentry, udba,
5527c038 23404+ d_inode(a->dst_h_parent), a->dst_h_parent,
4a4d8108 23405+ a->br);
86dc4139 23406+ if (!err)
4a4d8108 23407+ goto out; /* success */
4a4d8108
AM
23408+
23409+ err = au_busy_or_stale();
4a4d8108 23410+ au_ren_unlock(a);
86dc4139 23411+
4f0767ce 23412+out:
4a4d8108 23413+ return err;
1facf9fc 23414+}
23415+
23416+/* ---------------------------------------------------------------------- */
23417+
4a4d8108 23418+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 23419+{
4a4d8108 23420+ struct inode *dir;
dece6358 23421+
4a4d8108 23422+ dir = a->dst_dir;
be118d29 23423+ inode_inc_iversion(dir);
f2c43d5f 23424+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) {
4a4d8108
AM
23425+ /* is this updating defined in POSIX? */
23426+ au_cpup_attr_timesizes(a->src_inode);
23427+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 23428+ }
b912730e 23429+ au_dir_ts(dir, a->btgt);
dece6358 23430+
f2c43d5f
AM
23431+ if (a->exchange) {
23432+ dir = a->src_dir;
be118d29 23433+ inode_inc_iversion(dir);
f2c43d5f
AM
23434+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)) {
23435+ /* is this updating defined in POSIX? */
23436+ au_cpup_attr_timesizes(a->dst_inode);
23437+ au_cpup_attr_nlink(dir, /*force*/1);
23438+ }
23439+ au_dir_ts(dir, a->btgt);
23440+ }
23441+
23442+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108 23443+ return;
dece6358 23444+
4a4d8108 23445+ dir = a->src_dir;
be118d29 23446+ inode_inc_iversion(dir);
f2c43d5f 23447+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC))
4a4d8108 23448+ au_cpup_attr_nlink(dir, /*force*/1);
b912730e 23449+ au_dir_ts(dir, a->btgt);
1facf9fc 23450+}
23451+
4a4d8108 23452+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 23453+{
5afbbe0d 23454+ aufs_bindex_t bbot, bindex;
4a4d8108
AM
23455+ struct dentry *d, *h_d;
23456+ struct inode *i, *h_i;
23457+ struct super_block *sb;
dece6358 23458+
027c5e7a
AM
23459+ d = a->dst_dentry;
23460+ d_drop(d);
23461+ if (a->h_dst)
23462+ /* already dget-ed by au_ren_or_cpup() */
23463+ au_set_h_dptr(d, a->btgt, a->h_dst);
23464+
23465+ i = a->dst_inode;
23466+ if (i) {
f2c43d5f
AM
23467+ if (!a->exchange) {
23468+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST))
23469+ vfsub_drop_nlink(i);
23470+ else {
23471+ vfsub_dead_dir(i);
23472+ au_cpup_attr_timesizes(i);
23473+ }
23474+ au_update_dbrange(d, /*do_put_zero*/1);
23475+ } else
23476+ au_cpup_attr_nlink(i, /*force*/1);
027c5e7a 23477+ } else {
5afbbe0d
AM
23478+ bbot = a->btgt;
23479+ for (bindex = au_dbtop(d); bindex < bbot; bindex++)
027c5e7a 23480+ au_set_h_dptr(d, bindex, NULL);
5afbbe0d
AM
23481+ bbot = au_dbbot(d);
23482+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++)
027c5e7a
AM
23483+ au_set_h_dptr(d, bindex, NULL);
23484+ au_update_dbrange(d, /*do_put_zero*/0);
23485+ }
23486+
8b6a4947
AM
23487+ if (a->exchange
23488+ || au_ftest_ren(a->auren_flags, DIRREN)) {
23489+ d_drop(a->src_dentry);
23490+ if (au_ftest_ren(a->auren_flags, DIRREN))
23491+ au_set_dbwh(a->src_dentry, -1);
23492+ return;
23493+ }
23494+
4a4d8108 23495+ d = a->src_dentry;
8b6a4947
AM
23496+ au_set_dbwh(d, -1);
23497+ bbot = au_dbbot(d);
23498+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) {
23499+ h_d = au_h_dptr(d, bindex);
23500+ if (h_d)
23501+ au_set_h_dptr(d, bindex, NULL);
23502+ }
23503+ au_set_dbbot(d, a->btgt);
4a4d8108 23504+
8b6a4947
AM
23505+ sb = d->d_sb;
23506+ i = a->src_inode;
23507+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
23508+ return; /* success */
4a4d8108 23509+
8b6a4947
AM
23510+ bbot = au_ibbot(i);
23511+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) {
23512+ h_i = au_h_iptr(i, bindex);
23513+ if (h_i) {
23514+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
23515+ /* ignore this error */
23516+ au_set_h_iptr(i, bindex, NULL, 0);
4a4d8108
AM
23517+ }
23518+ }
8b6a4947 23519+ au_set_ibbot(i, a->btgt);
1308ab2a 23520+}
dece6358 23521+
4a4d8108
AM
23522+/* ---------------------------------------------------------------------- */
23523+
23524+/* mainly for link(2) and rename(2) */
23525+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 23526+{
4a4d8108
AM
23527+ aufs_bindex_t bdiropq, bwh;
23528+ struct dentry *parent;
23529+ struct au_branch *br;
23530+
23531+ parent = dentry->d_parent;
5527c038 23532+ IMustLock(d_inode(parent)); /* dir is locked */
4a4d8108
AM
23533+
23534+ bdiropq = au_dbdiropq(parent);
23535+ bwh = au_dbwh(dentry);
23536+ br = au_sbr(dentry->d_sb, btgt);
23537+ if (au_br_rdonly(br)
23538+ || (0 <= bdiropq && bdiropq < btgt)
23539+ || (0 <= bwh && bwh < btgt))
23540+ btgt = -1;
23541+
23542+ AuDbg("btgt %d\n", btgt);
23543+ return btgt;
1facf9fc 23544+}
23545+
5afbbe0d 23546+/* sets src_btop, dst_btop and btgt */
4a4d8108 23547+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 23548+{
4a4d8108
AM
23549+ int err;
23550+ struct au_wr_dir_args wr_dir_args = {
23551+ /* .force_btgt = -1, */
23552+ .flags = AuWrDir_ADD_ENTRY
23553+ };
dece6358 23554+
5afbbe0d
AM
23555+ a->src_btop = au_dbtop(a->src_dentry);
23556+ a->dst_btop = au_dbtop(a->dst_dentry);
f2c43d5f
AM
23557+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)
23558+ || au_ftest_ren(a->auren_flags, ISDIR_DST))
4a4d8108 23559+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
5afbbe0d
AM
23560+ wr_dir_args.force_btgt = a->src_btop;
23561+ if (a->dst_inode && a->dst_btop < a->src_btop)
23562+ wr_dir_args.force_btgt = a->dst_btop;
4a4d8108
AM
23563+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
23564+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
23565+ a->btgt = err;
f2c43d5f
AM
23566+ if (a->exchange)
23567+ au_update_dbtop(a->dst_dentry);
dece6358 23568+
4a4d8108 23569+ return err;
1facf9fc 23570+}
23571+
4a4d8108 23572+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 23573+{
4a4d8108
AM
23574+ a->h_path.dentry = a->src_h_parent;
23575+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
f2c43d5f 23576+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) {
4a4d8108
AM
23577+ a->h_path.dentry = a->dst_h_parent;
23578+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
23579+ }
1facf9fc 23580+
f2c43d5f
AM
23581+ au_fclr_ren(a->auren_flags, DT_DSTDIR);
23582+ if (!au_ftest_ren(a->auren_flags, ISDIR_SRC)
23583+ && !a->exchange)
4a4d8108 23584+ return;
dece6358 23585+
4a4d8108
AM
23586+ a->h_path.dentry = a->src_h_dentry;
23587+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
5527c038 23588+ if (d_is_positive(a->dst_h_dentry)) {
f2c43d5f 23589+ au_fset_ren(a->auren_flags, DT_DSTDIR);
4a4d8108
AM
23590+ a->h_path.dentry = a->dst_h_dentry;
23591+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
23592+ }
1308ab2a 23593+}
dece6358 23594+
4a4d8108 23595+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 23596+{
4a4d8108 23597+ struct dentry *h_d;
febd17d6 23598+ struct inode *h_inode;
4a4d8108
AM
23599+
23600+ au_dtime_revert(a->src_dt + AuPARENT);
f2c43d5f 23601+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108
AM
23602+ au_dtime_revert(a->dst_dt + AuPARENT);
23603+
f2c43d5f 23604+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) && err != -EIO) {
4a4d8108 23605+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
febd17d6
JR
23606+ h_inode = d_inode(h_d);
23607+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 23608+ au_dtime_revert(a->src_dt + AuCHILD);
febd17d6 23609+ inode_unlock(h_inode);
4a4d8108 23610+
f2c43d5f 23611+ if (au_ftest_ren(a->auren_flags, DT_DSTDIR)) {
4a4d8108 23612+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
febd17d6
JR
23613+ h_inode = d_inode(h_d);
23614+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 23615+ au_dtime_revert(a->dst_dt + AuCHILD);
febd17d6 23616+ inode_unlock(h_inode);
1facf9fc 23617+ }
23618+ }
23619+}
23620+
4a4d8108
AM
23621+/* ---------------------------------------------------------------------- */
23622+
23623+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
f2c43d5f
AM
23624+ struct inode *_dst_dir, struct dentry *_dst_dentry,
23625+ unsigned int _flags)
1facf9fc 23626+{
f2c43d5f 23627+ int err, lock_flags;
8b6a4947 23628+ void *rev;
4a4d8108
AM
23629+ /* reduce stack space */
23630+ struct au_ren_args *a;
f2c43d5f 23631+ struct au_pin pin;
4a4d8108 23632+
f2c43d5f 23633+ AuDbg("%pd, %pd, 0x%x\n", _src_dentry, _dst_dentry, _flags);
4a4d8108
AM
23634+ IMustLock(_src_dir);
23635+ IMustLock(_dst_dir);
23636+
f2c43d5f
AM
23637+ err = -EINVAL;
23638+ if (unlikely(_flags & RENAME_WHITEOUT))
23639+ goto out;
23640+
4a4d8108
AM
23641+ err = -ENOMEM;
23642+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
23643+ a = kzalloc(sizeof(*a), GFP_NOFS);
23644+ if (unlikely(!a))
23645+ goto out;
23646+
f2c43d5f 23647+ a->flags = _flags;
acd2b654
AM
23648+ BUILD_BUG_ON(sizeof(a->exchange) == sizeof(u8)
23649+ && RENAME_EXCHANGE > U8_MAX);
f2c43d5f 23650+ a->exchange = _flags & RENAME_EXCHANGE;
4a4d8108
AM
23651+ a->src_dir = _src_dir;
23652+ a->src_dentry = _src_dentry;
5527c038
JR
23653+ a->src_inode = NULL;
23654+ if (d_really_is_positive(a->src_dentry))
23655+ a->src_inode = d_inode(a->src_dentry);
4a4d8108
AM
23656+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
23657+ a->dst_dir = _dst_dir;
23658+ a->dst_dentry = _dst_dentry;
5527c038
JR
23659+ a->dst_inode = NULL;
23660+ if (d_really_is_positive(a->dst_dentry))
23661+ a->dst_inode = d_inode(a->dst_dentry);
4a4d8108
AM
23662+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
23663+ if (a->dst_inode) {
f2c43d5f
AM
23664+ /*
23665+ * if EXCHANGE && src is non-dir && dst is dir,
23666+ * dst is not locked.
23667+ */
23668+ /* IMustLock(a->dst_inode); */
4a4d8108 23669+ au_igrab(a->dst_inode);
1facf9fc 23670+ }
1facf9fc 23671+
4a4d8108 23672+ err = -ENOTDIR;
f2c43d5f 23673+ lock_flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
2000de60 23674+ if (d_is_dir(a->src_dentry)) {
f2c43d5f
AM
23675+ au_fset_ren(a->auren_flags, ISDIR_SRC);
23676+ if (unlikely(!a->exchange
23677+ && d_really_is_positive(a->dst_dentry)
2000de60 23678+ && !d_is_dir(a->dst_dentry)))
4a4d8108 23679+ goto out_free;
f2c43d5f
AM
23680+ lock_flags |= AuLock_DIRS;
23681+ }
23682+ if (a->dst_inode && d_is_dir(a->dst_dentry)) {
23683+ au_fset_ren(a->auren_flags, ISDIR_DST);
23684+ if (unlikely(!a->exchange
23685+ && d_really_is_positive(a->src_dentry)
23686+ && !d_is_dir(a->src_dentry)))
23687+ goto out_free;
23688+ lock_flags |= AuLock_DIRS;
b95c5147 23689+ }
8b6a4947
AM
23690+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
23691+ lock_flags);
e49829fe
JR
23692+ if (unlikely(err))
23693+ goto out_free;
1facf9fc 23694+
027c5e7a
AM
23695+ err = au_d_hashed_positive(a->src_dentry);
23696+ if (unlikely(err))
23697+ goto out_unlock;
23698+ err = -ENOENT;
23699+ if (a->dst_inode) {
23700+ /*
f2c43d5f 23701+ * If it is a dir, VFS unhash it before this
027c5e7a
AM
23702+ * function. It means we cannot rely upon d_unhashed().
23703+ */
23704+ if (unlikely(!a->dst_inode->i_nlink))
23705+ goto out_unlock;
f2c43d5f 23706+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) {
027c5e7a 23707+ err = au_d_hashed_positive(a->dst_dentry);
f2c43d5f 23708+ if (unlikely(err && !a->exchange))
027c5e7a
AM
23709+ goto out_unlock;
23710+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
23711+ goto out_unlock;
23712+ } else if (unlikely(d_unhashed(a->dst_dentry)))
23713+ goto out_unlock;
23714+
7eafdf33
AM
23715+ /*
23716+ * is it possible?
79b8bda9 23717+ * yes, it happened (in linux-3.3-rcN) but I don't know why.
7eafdf33
AM
23718+ * there may exist a problem somewhere else.
23719+ */
23720+ err = -EINVAL;
5527c038 23721+ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry)))
7eafdf33
AM
23722+ goto out_unlock;
23723+
f2c43d5f 23724+ au_fset_ren(a->auren_flags, ISSAMEDIR); /* temporary */
4a4d8108 23725+ di_write_lock_parent(a->dst_parent);
1facf9fc 23726+
4a4d8108
AM
23727+ /* which branch we process */
23728+ err = au_ren_wbr(a);
23729+ if (unlikely(err < 0))
027c5e7a 23730+ goto out_parent;
4a4d8108 23731+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 23732+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 23733+
4a4d8108
AM
23734+ /* are they available to be renamed */
23735+ err = au_ren_may_dir(a);
23736+ if (unlikely(err))
23737+ goto out_children;
1facf9fc 23738+
4a4d8108 23739+ /* prepare the writable parent dir on the same branch */
5afbbe0d 23740+ if (a->dst_btop == a->btgt) {
f2c43d5f 23741+ au_fset_ren(a->auren_flags, WHDST);
4a4d8108
AM
23742+ } else {
23743+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
23744+ if (unlikely(err))
23745+ goto out_children;
23746+ }
1facf9fc 23747+
f2c43d5f
AM
23748+ err = 0;
23749+ if (!a->exchange) {
23750+ if (a->src_dir != a->dst_dir) {
23751+ /*
23752+ * this temporary unlock is safe,
23753+ * because both dir->i_mutex are locked.
23754+ */
23755+ di_write_unlock(a->dst_parent);
23756+ di_write_lock_parent(a->src_parent);
23757+ err = au_wr_dir_need_wh(a->src_dentry,
23758+ au_ftest_ren(a->auren_flags,
23759+ ISDIR_SRC),
23760+ &a->btgt);
23761+ di_write_unlock(a->src_parent);
23762+ di_write_lock2_parent(a->src_parent, a->dst_parent,
23763+ /*isdir*/1);
23764+ au_fclr_ren(a->auren_flags, ISSAMEDIR);
23765+ } else
23766+ err = au_wr_dir_need_wh(a->src_dentry,
23767+ au_ftest_ren(a->auren_flags,
23768+ ISDIR_SRC),
23769+ &a->btgt);
23770+ }
4a4d8108
AM
23771+ if (unlikely(err < 0))
23772+ goto out_children;
23773+ if (err)
f2c43d5f 23774+ au_fset_ren(a->auren_flags, WHSRC);
1facf9fc 23775+
86dc4139 23776+ /* cpup src */
5afbbe0d 23777+ if (a->src_btop != a->btgt) {
86dc4139
AM
23778+ err = au_pin(&pin, a->src_dentry, a->btgt,
23779+ au_opt_udba(a->src_dentry->d_sb),
23780+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 23781+ if (!err) {
c2b27bf2
AM
23782+ struct au_cp_generic cpg = {
23783+ .dentry = a->src_dentry,
23784+ .bdst = a->btgt,
5afbbe0d 23785+ .bsrc = a->src_btop,
c2b27bf2
AM
23786+ .len = -1,
23787+ .pin = &pin,
23788+ .flags = AuCpup_DTIME | AuCpup_HOPEN
23789+ };
5afbbe0d 23790+ AuDebugOn(au_dbtop(a->src_dentry) != a->src_btop);
c2b27bf2 23791+ err = au_sio_cpup_simple(&cpg);
367653fa 23792+ au_unpin(&pin);
86dc4139 23793+ }
86dc4139
AM
23794+ if (unlikely(err))
23795+ goto out_children;
5afbbe0d 23796+ a->src_btop = a->btgt;
86dc4139 23797+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
f2c43d5f
AM
23798+ if (!a->exchange)
23799+ au_fset_ren(a->auren_flags, WHSRC);
23800+ }
23801+
23802+ /* cpup dst */
23803+ if (a->exchange && a->dst_inode
23804+ && a->dst_btop != a->btgt) {
23805+ err = au_pin(&pin, a->dst_dentry, a->btgt,
23806+ au_opt_udba(a->dst_dentry->d_sb),
23807+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
23808+ if (!err) {
23809+ struct au_cp_generic cpg = {
23810+ .dentry = a->dst_dentry,
23811+ .bdst = a->btgt,
23812+ .bsrc = a->dst_btop,
23813+ .len = -1,
23814+ .pin = &pin,
23815+ .flags = AuCpup_DTIME | AuCpup_HOPEN
23816+ };
23817+ err = au_sio_cpup_simple(&cpg);
23818+ au_unpin(&pin);
23819+ }
23820+ if (unlikely(err))
23821+ goto out_children;
23822+ a->dst_btop = a->btgt;
23823+ a->dst_h_dentry = au_h_dptr(a->dst_dentry, a->btgt);
86dc4139
AM
23824+ }
23825+
4a4d8108
AM
23826+ /* lock them all */
23827+ err = au_ren_lock(a);
23828+ if (unlikely(err))
86dc4139 23829+ /* leave the copied-up one */
4a4d8108 23830+ goto out_children;
1facf9fc 23831+
f2c43d5f
AM
23832+ if (!a->exchange) {
23833+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
23834+ err = au_may_ren(a);
23835+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
23836+ err = -ENAMETOOLONG;
23837+ if (unlikely(err))
23838+ goto out_hdir;
23839+ }
1facf9fc 23840+
4a4d8108
AM
23841+ /* store timestamps to be revertible */
23842+ au_ren_dt(a);
1facf9fc 23843+
8b6a4947
AM
23844+ /* store dirren info */
23845+ if (au_ftest_ren(a->auren_flags, DIRREN)) {
23846+ err = au_dr_rename(a->src_dentry, a->btgt,
23847+ &a->dst_dentry->d_name, &rev);
23848+ AuTraceErr(err);
23849+ if (unlikely(err))
23850+ goto out_dt;
23851+ }
23852+
4a4d8108
AM
23853+ /* here we go */
23854+ err = do_rename(a);
23855+ if (unlikely(err))
8b6a4947
AM
23856+ goto out_dirren;
23857+
23858+ if (au_ftest_ren(a->auren_flags, DIRREN))
23859+ au_dr_rename_fin(a->src_dentry, a->btgt, rev);
4a4d8108
AM
23860+
23861+ /* update dir attributes */
23862+ au_ren_refresh_dir(a);
23863+
23864+ /* dput/iput all lower dentries */
23865+ au_ren_refresh(a);
23866+
23867+ goto out_hdir; /* success */
23868+
8b6a4947
AM
23869+out_dirren:
23870+ if (au_ftest_ren(a->auren_flags, DIRREN))
23871+ au_dr_rename_rev(a->src_dentry, a->btgt, rev);
4f0767ce 23872+out_dt:
4a4d8108 23873+ au_ren_rev_dt(err, a);
4f0767ce 23874+out_hdir:
4a4d8108 23875+ au_ren_unlock(a);
4f0767ce 23876+out_children:
4a4d8108 23877+ au_nhash_wh_free(&a->whlist);
5afbbe0d
AM
23878+ if (err && a->dst_inode && a->dst_btop != a->btgt) {
23879+ AuDbg("btop %d, btgt %d\n", a->dst_btop, a->btgt);
027c5e7a 23880+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
5afbbe0d 23881+ au_set_dbtop(a->dst_dentry, a->dst_btop);
4a4d8108 23882+ }
027c5e7a 23883+out_parent:
f2c43d5f 23884+ if (!err) {
8b6a4947
AM
23885+ if (d_unhashed(a->src_dentry))
23886+ au_fset_ren(a->auren_flags, DROPPED_SRC);
23887+ if (d_unhashed(a->dst_dentry))
23888+ au_fset_ren(a->auren_flags, DROPPED_DST);
f2c43d5f
AM
23889+ if (!a->exchange)
23890+ d_move(a->src_dentry, a->dst_dentry);
8b6a4947 23891+ else {
f2c43d5f 23892+ d_exchange(a->src_dentry, a->dst_dentry);
8b6a4947
AM
23893+ if (au_ftest_ren(a->auren_flags, DROPPED_DST))
23894+ d_drop(a->dst_dentry);
23895+ }
23896+ if (au_ftest_ren(a->auren_flags, DROPPED_SRC))
23897+ d_drop(a->src_dentry);
f2c43d5f 23898+ } else {
5afbbe0d 23899+ au_update_dbtop(a->dst_dentry);
027c5e7a
AM
23900+ if (!a->dst_inode)
23901+ d_drop(a->dst_dentry);
23902+ }
f2c43d5f 23903+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108
AM
23904+ di_write_unlock(a->dst_parent);
23905+ else
23906+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 23907+out_unlock:
4a4d8108 23908+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 23909+out_free:
4a4d8108
AM
23910+ iput(a->dst_inode);
23911+ if (a->thargs)
23912+ au_whtmp_rmdir_free(a->thargs);
1c60b727 23913+ kfree(a);
4f0767ce 23914+out:
4a4d8108
AM
23915+ AuTraceErr(err);
23916+ return err;
1308ab2a 23917+}
7f207e10
AM
23918diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
23919--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
b00004a5 23920+++ linux/fs/aufs/Kconfig 2018-06-04 09:08:09.181412645 +0200
2121bcd9
AM
23921@@ -0,0 +1,199 @@
23922+# SPDX-License-Identifier: GPL-2.0
4a4d8108
AM
23923+config AUFS_FS
23924+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
23925+ help
23926+ Aufs is a stackable unification filesystem such as Unionfs,
23927+ which unifies several directories and provides a merged single
23928+ directory.
23929+ In the early days, aufs was entirely re-designed and
23930+ re-implemented Unionfs Version 1.x series. Introducing many
23931+ original ideas, approaches and improvements, it becomes totally
23932+ different from Unionfs while keeping the basic features.
1facf9fc 23933+
4a4d8108
AM
23934+if AUFS_FS
23935+choice
23936+ prompt "Maximum number of branches"
23937+ default AUFS_BRANCH_MAX_127
23938+ help
23939+ Specifies the maximum number of branches (or member directories)
23940+ in a single aufs. The larger value consumes more system
23941+ resources and has a minor impact to performance.
23942+config AUFS_BRANCH_MAX_127
23943+ bool "127"
23944+ help
23945+ Specifies the maximum number of branches (or member directories)
23946+ in a single aufs. The larger value consumes more system
23947+ resources and has a minor impact to performance.
23948+config AUFS_BRANCH_MAX_511
23949+ bool "511"
23950+ help
23951+ Specifies the maximum number of branches (or member directories)
23952+ in a single aufs. The larger value consumes more system
23953+ resources and has a minor impact to performance.
23954+config AUFS_BRANCH_MAX_1023
23955+ bool "1023"
23956+ help
23957+ Specifies the maximum number of branches (or member directories)
23958+ in a single aufs. The larger value consumes more system
23959+ resources and has a minor impact to performance.
23960+config AUFS_BRANCH_MAX_32767
23961+ bool "32767"
23962+ help
23963+ Specifies the maximum number of branches (or member directories)
23964+ in a single aufs. The larger value consumes more system
23965+ resources and has a minor impact to performance.
23966+endchoice
1facf9fc 23967+
e49829fe
JR
23968+config AUFS_SBILIST
23969+ bool
23970+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
23971+ default y
23972+ help
23973+ Automatic configuration for internal use.
23974+ When aufs supports Magic SysRq or /proc, enabled automatically.
23975+
4a4d8108
AM
23976+config AUFS_HNOTIFY
23977+ bool "Detect direct branch access (bypassing aufs)"
23978+ help
23979+ If you want to modify files on branches directly, eg. bypassing aufs,
23980+ and want aufs to detect the changes of them fully, then enable this
23981+ option and use 'udba=notify' mount option.
7f207e10 23982+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
23983+ It will have a negative impact to the performance.
23984+ See detail in aufs.5.
dece6358 23985+
4a4d8108
AM
23986+choice
23987+ prompt "method" if AUFS_HNOTIFY
23988+ default AUFS_HFSNOTIFY
23989+config AUFS_HFSNOTIFY
23990+ bool "fsnotify"
23991+ select FSNOTIFY
4a4d8108 23992+endchoice
1facf9fc 23993+
4a4d8108
AM
23994+config AUFS_EXPORT
23995+ bool "NFS-exportable aufs"
2cbb1c4b 23996+ depends on EXPORTFS
4a4d8108
AM
23997+ help
23998+ If you want to export your mounted aufs via NFS, then enable this
23999+ option. There are several requirements for this configuration.
24000+ See detail in aufs.5.
1facf9fc 24001+
4a4d8108
AM
24002+config AUFS_INO_T_64
24003+ bool
24004+ depends on AUFS_EXPORT
24005+ depends on 64BIT && !(ALPHA || S390)
24006+ default y
24007+ help
24008+ Automatic configuration for internal use.
24009+ /* typedef unsigned long/int __kernel_ino_t */
24010+ /* alpha and s390x are int */
1facf9fc 24011+
c1595e42
JR
24012+config AUFS_XATTR
24013+ bool "support for XATTR/EA (including Security Labels)"
24014+ help
24015+ If your branch fs supports XATTR/EA and you want to make them
24016+ available in aufs too, then enable this opsion and specify the
24017+ branch attributes for EA.
24018+ See detail in aufs.5.
24019+
076b876e
AM
24020+config AUFS_FHSM
24021+ bool "File-based Hierarchical Storage Management"
24022+ help
24023+ Hierarchical Storage Management (or HSM) is a well-known feature
24024+ in the storage world. Aufs provides this feature as file-based.
24025+ with multiple branches.
24026+ These multiple branches are prioritized, ie. the topmost one
24027+ should be the fastest drive and be used heavily.
24028+
4a4d8108
AM
24029+config AUFS_RDU
24030+ bool "Readdir in userspace"
24031+ help
24032+ Aufs has two methods to provide a merged view for a directory,
24033+ by a user-space library and by kernel-space natively. The latter
24034+ is always enabled but sometimes large and slow.
24035+ If you enable this option, install the library in aufs2-util
24036+ package, and set some environment variables for your readdir(3),
24037+ then the work will be handled in user-space which generally
24038+ shows better performance in most cases.
24039+ See detail in aufs.5.
1facf9fc 24040+
8b6a4947
AM
24041+config AUFS_DIRREN
24042+ bool "Workaround for rename(2)-ing a directory"
24043+ help
24044+ By default, aufs returns EXDEV error in renameing a dir who has
24045+ his child on the lower branch, since it is a bad idea to issue
24046+ rename(2) internally for every lower branch. But user may not
24047+ accept this behaviour. So here is a workaround to allow such
24048+ rename(2) and store some extra infromation on the writable
24049+ branch. Obviously this costs high (and I don't like it).
24050+ To use this feature, you need to enable this configuration AND
24051+ to specify the mount option `dirren.'
24052+ See details in aufs.5 and the design documents.
24053+
4a4d8108
AM
24054+config AUFS_SHWH
24055+ bool "Show whiteouts"
24056+ help
24057+ If you want to make the whiteouts in aufs visible, then enable
24058+ this option and specify 'shwh' mount option. Although it may
24059+ sounds like philosophy or something, but in technically it
24060+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 24061+
4a4d8108
AM
24062+config AUFS_BR_RAMFS
24063+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
24064+ help
24065+ If you want to use ramfs as an aufs branch fs, then enable this
24066+ option. Generally tmpfs is recommended.
24067+ Aufs prohibited them to be a branch fs by default, because
24068+ initramfs becomes unusable after switch_root or something
24069+ generally. If you sets initramfs as an aufs branch and boot your
24070+ system by switch_root, you will meet a problem easily since the
24071+ files in initramfs may be inaccessible.
24072+ Unless you are going to use ramfs as an aufs branch fs without
24073+ switch_root or something, leave it N.
1facf9fc 24074+
4a4d8108
AM
24075+config AUFS_BR_FUSE
24076+ bool "Fuse fs as an aufs branch"
24077+ depends on FUSE_FS
24078+ select AUFS_POLL
24079+ help
24080+ If you want to use fuse-based userspace filesystem as an aufs
24081+ branch fs, then enable this option.
24082+ It implements the internal poll(2) operation which is
24083+ implemented by fuse only (curretnly).
1facf9fc 24084+
4a4d8108
AM
24085+config AUFS_POLL
24086+ bool
24087+ help
24088+ Automatic configuration for internal use.
1facf9fc 24089+
4a4d8108
AM
24090+config AUFS_BR_HFSPLUS
24091+ bool "Hfsplus as an aufs branch"
24092+ depends on HFSPLUS_FS
24093+ default y
24094+ help
24095+ If you want to use hfsplus fs as an aufs branch fs, then enable
24096+ this option. This option introduces a small overhead at
24097+ copying-up a file on hfsplus.
1facf9fc 24098+
4a4d8108
AM
24099+config AUFS_BDEV_LOOP
24100+ bool
24101+ depends on BLK_DEV_LOOP
24102+ default y
24103+ help
24104+ Automatic configuration for internal use.
24105+ Convert =[ym] into =y.
1308ab2a 24106+
4a4d8108
AM
24107+config AUFS_DEBUG
24108+ bool "Debug aufs"
24109+ help
24110+ Enable this to compile aufs internal debug code.
24111+ It will have a negative impact to the performance.
24112+
24113+config AUFS_MAGIC_SYSRQ
24114+ bool
24115+ depends on AUFS_DEBUG && MAGIC_SYSRQ
24116+ default y
24117+ help
24118+ Automatic configuration for internal use.
24119+ When aufs supports Magic SysRq, enabled automatically.
24120+endif
acd2b654
AM
24121diff -urN /usr/share/empty/fs/aufs/lcnt.h linux/fs/aufs/lcnt.h
24122--- /usr/share/empty/fs/aufs/lcnt.h 1970-01-01 01:00:00.000000000 +0100
24123+++ linux/fs/aufs/lcnt.h 2018-10-23 12:33:35.599375796 +0200
24124@@ -0,0 +1,186 @@
24125+/* SPDX-License-Identifier: GPL-2.0 */
24126+/*
24127+ * Copyright (C) 2018 Junjiro R. Okajima
24128+ *
24129+ * This program, aufs is free software; you can redistribute it and/or modify
24130+ * it under the terms of the GNU General Public License as published by
24131+ * the Free Software Foundation; either version 2 of the License, or
24132+ * (at your option) any later version.
24133+ *
24134+ * This program is distributed in the hope that it will be useful,
24135+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24136+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24137+ * GNU General Public License for more details.
24138+ *
24139+ * You should have received a copy of the GNU General Public License
24140+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24141+ */
24142+
24143+/*
24144+ * simple long counter wrapper
24145+ */
24146+
24147+#ifndef __AUFS_LCNT_H__
24148+#define __AUFS_LCNT_H__
24149+
24150+#ifdef __KERNEL__
24151+
24152+#include "debug.h"
24153+
24154+#define AuLCntATOMIC 1
24155+#define AuLCntPCPUCNT 2
24156+/*
24157+ * why does percpu_refcount require extra synchronize_rcu()s in
24158+ * au_br_do_free()
24159+ */
24160+#define AuLCntPCPUREF 3
24161+
24162+/* #define AuLCntChosen AuLCntATOMIC */
24163+#define AuLCntChosen AuLCntPCPUCNT
24164+/* #define AuLCntChosen AuLCntPCPUREF */
24165+
24166+#if AuLCntChosen == AuLCntATOMIC
24167+#include <linux/atomic.h>
24168+
24169+typedef atomic_long_t au_lcnt_t;
24170+
24171+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused)
24172+{
24173+ atomic_long_set(cnt, 0);
24174+ return 0;
24175+}
24176+
24177+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused)
24178+{
24179+ /* empty */
24180+}
24181+
24182+static inline void au_lcnt_fin(au_lcnt_t *cnt __maybe_unused,
24183+ int do_sync __maybe_unused)
24184+{
24185+ /* empty */
24186+}
24187+
24188+static inline void au_lcnt_inc(au_lcnt_t *cnt)
24189+{
24190+ atomic_long_inc(cnt);
24191+}
24192+
24193+static inline void au_lcnt_dec(au_lcnt_t *cnt)
24194+{
24195+ atomic_long_dec(cnt);
24196+}
24197+
24198+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused)
24199+{
24200+ return atomic_long_read(cnt);
24201+}
24202+#endif
24203+
24204+#if AuLCntChosen == AuLCntPCPUCNT
24205+#include <linux/percpu_counter.h>
24206+
24207+typedef struct percpu_counter au_lcnt_t;
24208+
24209+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused)
24210+{
24211+ return percpu_counter_init(cnt, 0, GFP_NOFS);
24212+}
24213+
24214+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused)
24215+{
24216+ /* empty */
24217+}
24218+
24219+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync __maybe_unused)
24220+{
24221+ percpu_counter_destroy(cnt);
24222+}
24223+
24224+static inline void au_lcnt_inc(au_lcnt_t *cnt)
24225+{
24226+ percpu_counter_inc(cnt);
24227+}
24228+
24229+static inline void au_lcnt_dec(au_lcnt_t *cnt)
24230+{
24231+ percpu_counter_dec(cnt);
24232+}
24233+
24234+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused)
24235+{
24236+ s64 n;
24237+
24238+ n = percpu_counter_sum(cnt);
24239+ BUG_ON(n < 0);
24240+ if (LONG_MAX != LLONG_MAX
24241+ && n > LONG_MAX)
24242+ AuWarn1("%s\n", "wrap-around");
24243+
24244+ return n;
24245+}
24246+#endif
24247+
24248+#if AuLCntChosen == AuLCntPCPUREF
24249+#include <linux/percpu-refcount.h>
24250+
24251+typedef struct percpu_ref au_lcnt_t;
24252+
24253+static inline int au_lcnt_init(au_lcnt_t *cnt, percpu_ref_func_t *release)
24254+{
24255+ if (!release)
24256+ release = percpu_ref_exit;
24257+ return percpu_ref_init(cnt, release, /*percpu mode*/0, GFP_NOFS);
24258+}
24259+
24260+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused)
24261+{
24262+ synchronize_rcu();
24263+}
24264+
24265+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync)
24266+{
24267+ percpu_ref_kill(cnt);
24268+ if (do_sync)
24269+ au_lcnt_wait_for_fin(cnt);
24270+}
24271+
24272+static inline void au_lcnt_inc(au_lcnt_t *cnt)
24273+{
24274+ percpu_ref_get(cnt);
24275+}
24276+
24277+static inline void au_lcnt_dec(au_lcnt_t *cnt)
24278+{
24279+ percpu_ref_put(cnt);
24280+}
24281+
24282+/*
24283+ * avoid calling this func as possible.
24284+ */
24285+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev)
24286+{
24287+ long l;
24288+
24289+ percpu_ref_switch_to_atomic_sync(cnt);
24290+ l = atomic_long_read(&cnt->count);
24291+ if (do_rev)
24292+ percpu_ref_switch_to_percpu(cnt);
24293+
24294+ /* percpu_ref is initialized by 1 instead of 0 */
24295+ return l - 1;
24296+}
24297+#endif
24298+
24299+#ifdef CONFIG_AUFS_DEBUG
24300+#define AuLCntZero(val) do { \
24301+ long l = val; \
24302+ if (l) \
24303+ AuDbg("%s = %ld\n", #val, l); \
24304+} while (0)
24305+#else
24306+#define AuLCntZero(val) do {} while (0)
24307+#endif
24308+
24309+#endif /* __KERNEL__ */
24310+#endif /* __AUFS_LCNT_H__ */
7f207e10
AM
24311diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
24312--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 24313+++ linux/fs/aufs/loop.c 2018-08-12 23:43:05.460124736 +0200
062440b3 24314@@ -0,0 +1,148 @@
cd7a4cd9 24315+// SPDX-License-Identifier: GPL-2.0
1facf9fc 24316+/*
b00004a5 24317+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 24318+ *
24319+ * This program, aufs is free software; you can redistribute it and/or modify
24320+ * it under the terms of the GNU General Public License as published by
24321+ * the Free Software Foundation; either version 2 of the License, or
24322+ * (at your option) any later version.
dece6358
AM
24323+ *
24324+ * This program is distributed in the hope that it will be useful,
24325+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24326+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24327+ * GNU General Public License for more details.
24328+ *
24329+ * You should have received a copy of the GNU General Public License
523b37e3 24330+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24331+ */
24332+
24333+/*
24334+ * support for loopback block device as a branch
24335+ */
24336+
1facf9fc 24337+#include "aufs.h"
24338+
392086de
AM
24339+/* added into drivers/block/loop.c */
24340+static struct file *(*backing_file_func)(struct super_block *sb);
24341+
1facf9fc 24342+/*
24343+ * test if two lower dentries have overlapping branches.
24344+ */
b752ccd1 24345+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 24346+{
b752ccd1 24347+ struct super_block *h_sb;
392086de
AM
24348+ struct file *backing_file;
24349+
24350+ if (unlikely(!backing_file_func)) {
24351+ /* don't load "loop" module here */
24352+ backing_file_func = symbol_get(loop_backing_file);
24353+ if (unlikely(!backing_file_func))
24354+ /* "loop" module is not loaded */
24355+ return 0;
24356+ }
1facf9fc 24357+
b752ccd1 24358+ h_sb = h_adding->d_sb;
392086de
AM
24359+ backing_file = backing_file_func(h_sb);
24360+ if (!backing_file)
1facf9fc 24361+ return 0;
24362+
2000de60 24363+ h_adding = backing_file->f_path.dentry;
b752ccd1
AM
24364+ /*
24365+ * h_adding can be local NFS.
24366+ * in this case aufs cannot detect the loop.
24367+ */
24368+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 24369+ return 1;
b752ccd1 24370+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 24371+}
24372+
24373+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
24374+int au_test_loopback_kthread(void)
24375+{
b752ccd1
AM
24376+ int ret;
24377+ struct task_struct *tsk = current;
a2a7ad62 24378+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
24379+
24380+ ret = 0;
24381+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
24382+ get_task_comm(comm, tsk);
24383+ c = comm[4];
b752ccd1 24384+ ret = ('0' <= c && c <= '9'
a2a7ad62 24385+ && !strncmp(comm, "loop", 4));
b752ccd1 24386+ }
1facf9fc 24387+
b752ccd1 24388+ return ret;
1facf9fc 24389+}
87a755f4
AM
24390+
24391+/* ---------------------------------------------------------------------- */
24392+
24393+#define au_warn_loopback_step 16
24394+static int au_warn_loopback_nelem = au_warn_loopback_step;
24395+static unsigned long *au_warn_loopback_array;
24396+
24397+void au_warn_loopback(struct super_block *h_sb)
24398+{
24399+ int i, new_nelem;
24400+ unsigned long *a, magic;
24401+ static DEFINE_SPINLOCK(spin);
24402+
24403+ magic = h_sb->s_magic;
24404+ spin_lock(&spin);
24405+ a = au_warn_loopback_array;
24406+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
24407+ if (a[i] == magic) {
24408+ spin_unlock(&spin);
24409+ return;
24410+ }
24411+
24412+ /* h_sb is new to us, print it */
24413+ if (i < au_warn_loopback_nelem) {
24414+ a[i] = magic;
24415+ goto pr;
24416+ }
24417+
24418+ /* expand the array */
24419+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
24420+ a = au_kzrealloc(au_warn_loopback_array,
24421+ au_warn_loopback_nelem * sizeof(unsigned long),
e2f27e51
AM
24422+ new_nelem * sizeof(unsigned long), GFP_ATOMIC,
24423+ /*may_shrink*/0);
87a755f4
AM
24424+ if (a) {
24425+ au_warn_loopback_nelem = new_nelem;
24426+ au_warn_loopback_array = a;
24427+ a[i] = magic;
24428+ goto pr;
24429+ }
24430+
24431+ spin_unlock(&spin);
24432+ AuWarn1("realloc failed, ignored\n");
24433+ return;
24434+
24435+pr:
24436+ spin_unlock(&spin);
0c3ec466
AM
24437+ pr_warn("you may want to try another patch for loopback file "
24438+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
24439+}
24440+
24441+int au_loopback_init(void)
24442+{
24443+ int err;
24444+ struct super_block *sb __maybe_unused;
24445+
79b8bda9 24446+ BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(unsigned long));
87a755f4
AM
24447+
24448+ err = 0;
24449+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
24450+ sizeof(unsigned long), GFP_NOFS);
24451+ if (unlikely(!au_warn_loopback_array))
24452+ err = -ENOMEM;
24453+
24454+ return err;
24455+}
24456+
24457+void au_loopback_fin(void)
24458+{
79b8bda9
AM
24459+ if (backing_file_func)
24460+ symbol_put(loop_backing_file);
1c60b727 24461+ kfree(au_warn_loopback_array);
87a755f4 24462+}
7f207e10
AM
24463diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
24464--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 24465+++ linux/fs/aufs/loop.h 2018-08-12 23:43:05.460124736 +0200
062440b3
AM
24466@@ -0,0 +1,53 @@
24467+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 24468+/*
b00004a5 24469+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 24470+ *
24471+ * This program, aufs is free software; you can redistribute it and/or modify
24472+ * it under the terms of the GNU General Public License as published by
24473+ * the Free Software Foundation; either version 2 of the License, or
24474+ * (at your option) any later version.
dece6358
AM
24475+ *
24476+ * This program is distributed in the hope that it will be useful,
24477+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24478+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24479+ * GNU General Public License for more details.
24480+ *
24481+ * You should have received a copy of the GNU General Public License
523b37e3 24482+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24483+ */
24484+
24485+/*
24486+ * support for loopback mount as a branch
24487+ */
24488+
24489+#ifndef __AUFS_LOOP_H__
24490+#define __AUFS_LOOP_H__
24491+
24492+#ifdef __KERNEL__
24493+
dece6358
AM
24494+struct dentry;
24495+struct super_block;
1facf9fc 24496+
24497+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
24498+/* drivers/block/loop.c */
24499+struct file *loop_backing_file(struct super_block *sb);
24500+
1facf9fc 24501+/* loop.c */
b752ccd1 24502+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 24503+int au_test_loopback_kthread(void);
87a755f4
AM
24504+void au_warn_loopback(struct super_block *h_sb);
24505+
24506+int au_loopback_init(void);
24507+void au_loopback_fin(void);
1facf9fc 24508+#else
4a4d8108 24509+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 24510+ struct dentry *h_adding)
4a4d8108 24511+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
24512+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
24513+
24514+AuStubInt0(au_loopback_init, void)
24515+AuStubVoid(au_loopback_fin, void)
1facf9fc 24516+#endif /* BLK_DEV_LOOP */
24517+
24518+#endif /* __KERNEL__ */
24519+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
24520diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
24521--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
b00004a5 24522+++ linux/fs/aufs/magic.mk 2018-06-04 09:08:09.188079511 +0200
2121bcd9
AM
24523@@ -0,0 +1,31 @@
24524+# SPDX-License-Identifier: GPL-2.0
1facf9fc 24525+
24526+# defined in ${srctree}/fs/fuse/inode.c
24527+# tristate
24528+ifdef CONFIG_FUSE_FS
24529+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
24530+endif
24531+
1facf9fc 24532+# defined in ${srctree}/fs/xfs/xfs_sb.h
24533+# tristate
24534+ifdef CONFIG_XFS_FS
24535+ccflags-y += -DXFS_SB_MAGIC=0x58465342
24536+endif
24537+
24538+# defined in ${srctree}/fs/configfs/mount.c
24539+# tristate
24540+ifdef CONFIG_CONFIGFS_FS
24541+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
24542+endif
24543+
1facf9fc 24544+# defined in ${srctree}/fs/ubifs/ubifs.h
24545+# tristate
24546+ifdef CONFIG_UBIFS_FS
24547+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
24548+endif
4a4d8108
AM
24549+
24550+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
24551+# tristate
24552+ifdef CONFIG_HFSPLUS_FS
24553+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
24554+endif
7f207e10
AM
24555diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
24556--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
b00004a5 24557+++ linux/fs/aufs/Makefile 2018-06-04 09:08:09.181412645 +0200
2121bcd9
AM
24558@@ -0,0 +1,46 @@
24559+# SPDX-License-Identifier: GPL-2.0
4a4d8108
AM
24560+
24561+include ${src}/magic.mk
24562+ifeq (${CONFIG_AUFS_FS},m)
24563+include ${src}/conf.mk
24564+endif
24565+-include ${src}/priv_def.mk
24566+
24567+# cf. include/linux/kernel.h
24568+# enable pr_debug
24569+ccflags-y += -DDEBUG
f6c5ef8b
AM
24570+# sparse requires the full pathname
24571+ifdef M
523b37e3 24572+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 24573+else
523b37e3 24574+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 24575+endif
4a4d8108
AM
24576+
24577+obj-$(CONFIG_AUFS_FS) += aufs.o
24578+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
24579+ wkq.o vfsub.o dcsub.o \
e49829fe 24580+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
24581+ dinfo.o dentry.o \
24582+ dynop.o \
24583+ finfo.o file.o f_op.o \
24584+ dir.o vdir.o \
24585+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 24586+ mvdown.o ioctl.o
4a4d8108
AM
24587+
24588+# all are boolean
e49829fe 24589+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
24590+aufs-$(CONFIG_SYSFS) += sysfs.o
24591+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
24592+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
24593+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
24594+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108 24595+aufs-$(CONFIG_AUFS_EXPORT) += export.o
c1595e42
JR
24596+aufs-$(CONFIG_AUFS_XATTR) += xattr.o
24597+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
8b6a4947 24598+aufs-$(CONFIG_AUFS_DIRREN) += dirren.o
076b876e 24599+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
4a4d8108
AM
24600+aufs-$(CONFIG_AUFS_POLL) += poll.o
24601+aufs-$(CONFIG_AUFS_RDU) += rdu.o
4a4d8108
AM
24602+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
24603+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
24604+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
24605diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
24606--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 24607+++ linux/fs/aufs/module.c 2018-08-12 23:43:05.460124736 +0200
062440b3 24608@@ -0,0 +1,273 @@
cd7a4cd9 24609+// SPDX-License-Identifier: GPL-2.0
1facf9fc 24610+/*
b00004a5 24611+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 24612+ *
24613+ * This program, aufs is free software; you can redistribute it and/or modify
24614+ * it under the terms of the GNU General Public License as published by
24615+ * the Free Software Foundation; either version 2 of the License, or
24616+ * (at your option) any later version.
dece6358
AM
24617+ *
24618+ * This program is distributed in the hope that it will be useful,
24619+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24620+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24621+ * GNU General Public License for more details.
24622+ *
24623+ * You should have received a copy of the GNU General Public License
523b37e3 24624+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24625+ */
24626+
24627+/*
24628+ * module global variables and operations
24629+ */
24630+
24631+#include <linux/module.h>
24632+#include <linux/seq_file.h>
24633+#include "aufs.h"
24634+
e2f27e51
AM
24635+/* shrinkable realloc */
24636+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink)
1facf9fc 24637+{
e2f27e51
AM
24638+ size_t sz;
24639+ int diff;
1facf9fc 24640+
e2f27e51
AM
24641+ sz = 0;
24642+ diff = -1;
24643+ if (p) {
24644+#if 0 /* unused */
24645+ if (!new_sz) {
1c60b727 24646+ kfree(p);
e2f27e51
AM
24647+ p = NULL;
24648+ goto out;
24649+ }
24650+#else
24651+ AuDebugOn(!new_sz);
24652+#endif
24653+ sz = ksize(p);
24654+ diff = au_kmidx_sub(sz, new_sz);
24655+ }
24656+ if (sz && !diff)
24657+ goto out;
24658+
24659+ if (sz < new_sz)
24660+ /* expand or SLOB */
24661+ p = krealloc(p, new_sz, gfp);
24662+ else if (new_sz < sz && may_shrink) {
24663+ /* shrink */
24664+ void *q;
24665+
24666+ q = kmalloc(new_sz, gfp);
24667+ if (q) {
24668+ if (p) {
24669+ memcpy(q, p, new_sz);
1c60b727 24670+ kfree(p);
e2f27e51
AM
24671+ }
24672+ p = q;
24673+ } else
24674+ p = NULL;
24675+ }
24676+
24677+out:
24678+ return p;
24679+}
24680+
24681+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
24682+ int may_shrink)
24683+{
24684+ p = au_krealloc(p, new_sz, gfp, may_shrink);
24685+ if (p && new_sz > nused)
1facf9fc 24686+ memset(p + nused, 0, new_sz - nused);
24687+ return p;
24688+}
24689+
24690+/* ---------------------------------------------------------------------- */
1facf9fc 24691+/*
24692+ * aufs caches
24693+ */
1c60b727 24694+struct kmem_cache *au_cache[AuCache_Last];
5afbbe0d
AM
24695+
24696+static void au_cache_fin(void)
24697+{
24698+ int i;
24699+
24700+ /*
24701+ * Make sure all delayed rcu free inodes are flushed before we
24702+ * destroy cache.
24703+ */
24704+ rcu_barrier();
24705+
24706+ /* excluding AuCache_HNOTIFY */
24707+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
24708+ for (i = 0; i < AuCache_HNOTIFY; i++) {
1c60b727
AM
24709+ kmem_cache_destroy(au_cache[i]);
24710+ au_cache[i] = NULL;
5afbbe0d
AM
24711+ }
24712+}
24713+
1facf9fc 24714+static int __init au_cache_init(void)
24715+{
1c60b727
AM
24716+ au_cache[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
24717+ if (au_cache[AuCache_DINFO])
027c5e7a 24718+ /* SLAB_DESTROY_BY_RCU */
1c60b727 24719+ au_cache[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
f0c0a007 24720+ au_icntnr_init_once);
1c60b727
AM
24721+ if (au_cache[AuCache_ICNTNR])
24722+ au_cache[AuCache_FINFO] = AuCacheCtor(au_finfo,
f0c0a007 24723+ au_fi_init_once);
1c60b727
AM
24724+ if (au_cache[AuCache_FINFO])
24725+ au_cache[AuCache_VDIR] = AuCache(au_vdir);
24726+ if (au_cache[AuCache_VDIR])
24727+ au_cache[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
24728+ if (au_cache[AuCache_DEHSTR])
1facf9fc 24729+ return 0;
24730+
5afbbe0d 24731+ au_cache_fin();
1facf9fc 24732+ return -ENOMEM;
24733+}
24734+
1facf9fc 24735+/* ---------------------------------------------------------------------- */
24736+
24737+int au_dir_roflags;
24738+
e49829fe 24739+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
24740+/*
24741+ * iterate_supers_type() doesn't protect us from
24742+ * remounting (branch management)
24743+ */
8b6a4947 24744+struct hlist_bl_head au_sbilist;
e49829fe
JR
24745+#endif
24746+
1facf9fc 24747+/*
24748+ * functions for module interface.
24749+ */
24750+MODULE_LICENSE("GPL");
24751+/* MODULE_LICENSE("GPL v2"); */
dece6358 24752+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 24753+MODULE_DESCRIPTION(AUFS_NAME
24754+ " -- Advanced multi layered unification filesystem");
24755+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 24756+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 24757+
1facf9fc 24758+/* this module parameter has no meaning when SYSFS is disabled */
24759+int sysaufs_brs = 1;
24760+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
cd7a4cd9 24761+module_param_named(brs, sysaufs_brs, int, 0444);
1facf9fc 24762+
076b876e 24763+/* this module parameter has no meaning when USER_NS is disabled */
8cdd5066 24764+bool au_userns;
076b876e 24765+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
cd7a4cd9 24766+module_param_named(allow_userns, au_userns, bool, 0444);
076b876e 24767+
1facf9fc 24768+/* ---------------------------------------------------------------------- */
24769+
24770+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
24771+
24772+int au_seq_path(struct seq_file *seq, struct path *path)
24773+{
79b8bda9
AM
24774+ int err;
24775+
24776+ err = seq_path(seq, path, au_esc_chars);
1c60b727 24777+ if (err >= 0)
79b8bda9 24778+ err = 0;
1c60b727 24779+ else
79b8bda9
AM
24780+ err = -ENOMEM;
24781+
24782+ return err;
1facf9fc 24783+}
24784+
24785+/* ---------------------------------------------------------------------- */
24786+
24787+static int __init aufs_init(void)
24788+{
24789+ int err, i;
24790+ char *p;
24791+
24792+ p = au_esc_chars;
24793+ for (i = 1; i <= ' '; i++)
24794+ *p++ = i;
24795+ *p++ = '\\';
24796+ *p++ = '\x7f';
24797+ *p = 0;
24798+
24799+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
24800+
b95c5147
AM
24801+ memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop));
24802+ for (i = 0; i < AuIop_Last; i++)
24803+ aufs_iop_nogetattr[i].getattr = NULL;
24804+
1c60b727 24805+ memset(au_cache, 0, sizeof(au_cache)); /* including hnotify */
f0c0a007 24806+
e49829fe 24807+ au_sbilist_init();
1facf9fc 24808+ sysaufs_brs_init();
24809+ au_debug_init();
4a4d8108 24810+ au_dy_init();
1facf9fc 24811+ err = sysaufs_init();
24812+ if (unlikely(err))
24813+ goto out;
062440b3 24814+ err = dbgaufs_init();
4f0767ce 24815+ if (unlikely(err))
953406b4 24816+ goto out_sysaufs;
062440b3
AM
24817+ err = au_procfs_init();
24818+ if (unlikely(err))
24819+ goto out_dbgaufs;
e49829fe
JR
24820+ err = au_wkq_init();
24821+ if (unlikely(err))
24822+ goto out_procfs;
87a755f4 24823+ err = au_loopback_init();
1facf9fc 24824+ if (unlikely(err))
24825+ goto out_wkq;
87a755f4
AM
24826+ err = au_hnotify_init();
24827+ if (unlikely(err))
24828+ goto out_loopback;
1facf9fc 24829+ err = au_sysrq_init();
24830+ if (unlikely(err))
24831+ goto out_hin;
24832+ err = au_cache_init();
24833+ if (unlikely(err))
24834+ goto out_sysrq;
076b876e
AM
24835+
24836+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
1facf9fc 24837+ err = register_filesystem(&aufs_fs_type);
24838+ if (unlikely(err))
24839+ goto out_cache;
076b876e 24840+
4a4d8108
AM
24841+ /* since we define pr_fmt, call printk directly */
24842+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 24843+ goto out; /* success */
24844+
4f0767ce 24845+out_cache:
1facf9fc 24846+ au_cache_fin();
4f0767ce 24847+out_sysrq:
1facf9fc 24848+ au_sysrq_fin();
4f0767ce 24849+out_hin:
4a4d8108 24850+ au_hnotify_fin();
87a755f4
AM
24851+out_loopback:
24852+ au_loopback_fin();
4f0767ce 24853+out_wkq:
1facf9fc 24854+ au_wkq_fin();
e49829fe
JR
24855+out_procfs:
24856+ au_procfs_fin();
062440b3
AM
24857+out_dbgaufs:
24858+ dbgaufs_fin();
4f0767ce 24859+out_sysaufs:
1facf9fc 24860+ sysaufs_fin();
4a4d8108 24861+ au_dy_fin();
4f0767ce 24862+out:
1facf9fc 24863+ return err;
24864+}
24865+
24866+static void __exit aufs_exit(void)
24867+{
24868+ unregister_filesystem(&aufs_fs_type);
24869+ au_cache_fin();
24870+ au_sysrq_fin();
4a4d8108 24871+ au_hnotify_fin();
87a755f4 24872+ au_loopback_fin();
1facf9fc 24873+ au_wkq_fin();
e49829fe 24874+ au_procfs_fin();
062440b3 24875+ dbgaufs_fin();
1facf9fc 24876+ sysaufs_fin();
4a4d8108 24877+ au_dy_fin();
1facf9fc 24878+}
24879+
24880+module_init(aufs_init);
24881+module_exit(aufs_exit);
7f207e10
AM
24882diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
24883--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 24884+++ linux/fs/aufs/module.h 2018-08-12 23:43:05.460124736 +0200
062440b3
AM
24885@@ -0,0 +1,102 @@
24886+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 24887+/*
b00004a5 24888+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 24889+ *
24890+ * This program, aufs is free software; you can redistribute it and/or modify
24891+ * it under the terms of the GNU General Public License as published by
24892+ * the Free Software Foundation; either version 2 of the License, or
24893+ * (at your option) any later version.
dece6358
AM
24894+ *
24895+ * This program is distributed in the hope that it will be useful,
24896+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24897+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24898+ * GNU General Public License for more details.
24899+ *
24900+ * You should have received a copy of the GNU General Public License
523b37e3 24901+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24902+ */
24903+
24904+/*
24905+ * module initialization and module-global
24906+ */
24907+
24908+#ifndef __AUFS_MODULE_H__
24909+#define __AUFS_MODULE_H__
24910+
24911+#ifdef __KERNEL__
24912+
24913+#include <linux/slab.h>
24914+
dece6358
AM
24915+struct path;
24916+struct seq_file;
24917+
1facf9fc 24918+/* module parameters */
1facf9fc 24919+extern int sysaufs_brs;
8cdd5066 24920+extern bool au_userns;
1facf9fc 24921+
24922+/* ---------------------------------------------------------------------- */
24923+
24924+extern int au_dir_roflags;
24925+
e2f27e51
AM
24926+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink);
24927+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
24928+ int may_shrink);
24929+
24930+static inline int au_kmidx_sub(size_t sz, size_t new_sz)
24931+{
24932+#ifndef CONFIG_SLOB
24933+ return kmalloc_index(sz) - kmalloc_index(new_sz);
24934+#else
24935+ return -1; /* SLOB is untested */
24936+#endif
24937+}
24938+
1facf9fc 24939+int au_seq_path(struct seq_file *seq, struct path *path);
24940+
e49829fe
JR
24941+#ifdef CONFIG_PROC_FS
24942+/* procfs.c */
24943+int __init au_procfs_init(void);
24944+void au_procfs_fin(void);
24945+#else
24946+AuStubInt0(au_procfs_init, void);
24947+AuStubVoid(au_procfs_fin, void);
24948+#endif
24949+
4f0767ce
JR
24950+/* ---------------------------------------------------------------------- */
24951+
1c60b727 24952+/* kmem cache */
1facf9fc 24953+enum {
24954+ AuCache_DINFO,
24955+ AuCache_ICNTNR,
24956+ AuCache_FINFO,
24957+ AuCache_VDIR,
24958+ AuCache_DEHSTR,
7eafdf33 24959+ AuCache_HNOTIFY, /* must be last */
1facf9fc 24960+ AuCache_Last
24961+};
24962+
1c60b727 24963+extern struct kmem_cache *au_cache[AuCache_Last];
f0c0a007 24964+
4a4d8108
AM
24965+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
24966+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
24967+#define AuCacheCtor(type, ctor) \
24968+ kmem_cache_create(#type, sizeof(struct type), \
24969+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 24970+
1facf9fc 24971+#define AuCacheFuncs(name, index) \
4a4d8108 24972+static inline struct au_##name *au_cache_alloc_##name(void) \
1c60b727 24973+{ return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \
4a4d8108 24974+static inline void au_cache_free_##name(struct au_##name *p) \
1c60b727 24975+{ kmem_cache_free(au_cache[AuCache_##index], p); }
1facf9fc 24976+
24977+AuCacheFuncs(dinfo, DINFO);
24978+AuCacheFuncs(icntnr, ICNTNR);
24979+AuCacheFuncs(finfo, FINFO);
24980+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
24981+AuCacheFuncs(vdir_dehstr, DEHSTR);
24982+#ifdef CONFIG_AUFS_HNOTIFY
24983+AuCacheFuncs(hnotify, HNOTIFY);
24984+#endif
1facf9fc 24985+
4a4d8108
AM
24986+#endif /* __KERNEL__ */
24987+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
24988diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
24989--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 24990+++ linux/fs/aufs/mvdown.c 2018-08-12 23:43:05.460124736 +0200
062440b3 24991@@ -0,0 +1,705 @@
cd7a4cd9 24992+// SPDX-License-Identifier: GPL-2.0
c2b27bf2 24993+/*
b00004a5 24994+ * Copyright (C) 2011-2018 Junjiro R. Okajima
c2b27bf2
AM
24995+ *
24996+ * This program, aufs is free software; you can redistribute it and/or modify
24997+ * it under the terms of the GNU General Public License as published by
24998+ * the Free Software Foundation; either version 2 of the License, or
24999+ * (at your option) any later version.
25000+ *
25001+ * This program is distributed in the hope that it will be useful,
25002+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25003+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25004+ * GNU General Public License for more details.
25005+ *
25006+ * You should have received a copy of the GNU General Public License
523b37e3
AM
25007+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
25008+ */
25009+
25010+/*
25011+ * move-down, opposite of copy-up
c2b27bf2
AM
25012+ */
25013+
25014+#include "aufs.h"
25015+
c2b27bf2
AM
25016+struct au_mvd_args {
25017+ struct {
c2b27bf2
AM
25018+ struct super_block *h_sb;
25019+ struct dentry *h_parent;
25020+ struct au_hinode *hdir;
392086de 25021+ struct inode *h_dir, *h_inode;
c1595e42 25022+ struct au_pin pin;
c2b27bf2
AM
25023+ } info[AUFS_MVDOWN_NARRAY];
25024+
25025+ struct aufs_mvdown mvdown;
25026+ struct dentry *dentry, *parent;
25027+ struct inode *inode, *dir;
25028+ struct super_block *sb;
25029+ aufs_bindex_t bopq, bwh, bfound;
25030+ unsigned char rename_lock;
c2b27bf2
AM
25031+};
25032+
392086de 25033+#define mvd_errno mvdown.au_errno
076b876e
AM
25034+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
25035+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid
25036+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
25037+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid
c2b27bf2 25038+
392086de
AM
25039+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
25040+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
25041+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
25042+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
25043+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
c1595e42 25044+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin
392086de
AM
25045+
25046+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
25047+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
25048+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
25049+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
25050+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c1595e42 25051+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin
c2b27bf2
AM
25052+
25053+#define AU_MVD_PR(flag, ...) do { \
25054+ if (flag) \
25055+ pr_err(__VA_ARGS__); \
25056+ } while (0)
25057+
076b876e
AM
25058+static int find_lower_writable(struct au_mvd_args *a)
25059+{
25060+ struct super_block *sb;
5afbbe0d 25061+ aufs_bindex_t bindex, bbot;
076b876e
AM
25062+ struct au_branch *br;
25063+
25064+ sb = a->sb;
25065+ bindex = a->mvd_bsrc;
5afbbe0d 25066+ bbot = au_sbbot(sb);
076b876e 25067+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
5afbbe0d 25068+ for (bindex++; bindex <= bbot; bindex++) {
076b876e
AM
25069+ br = au_sbr(sb, bindex);
25070+ if (au_br_fhsm(br->br_perm)
8b6a4947 25071+ && !sb_rdonly(au_br_sb(br)))
076b876e
AM
25072+ return bindex;
25073+ }
25074+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
5afbbe0d 25075+ for (bindex++; bindex <= bbot; bindex++) {
076b876e
AM
25076+ br = au_sbr(sb, bindex);
25077+ if (!au_br_rdonly(br))
25078+ return bindex;
25079+ }
25080+ else
5afbbe0d 25081+ for (bindex++; bindex <= bbot; bindex++) {
076b876e 25082+ br = au_sbr(sb, bindex);
8b6a4947 25083+ if (!sb_rdonly(au_br_sb(br))) {
076b876e
AM
25084+ if (au_br_rdonly(br))
25085+ a->mvdown.flags
25086+ |= AUFS_MVDOWN_ROLOWER_R;
25087+ return bindex;
25088+ }
25089+ }
25090+
25091+ return -1;
25092+}
25093+
c2b27bf2 25094+/* make the parent dir on bdst */
392086de 25095+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25096+{
25097+ int err;
25098+
25099+ err = 0;
25100+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
25101+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
25102+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
25103+ a->mvd_h_dst_parent = NULL;
5afbbe0d 25104+ if (au_dbbot(a->parent) >= a->mvd_bdst)
c2b27bf2
AM
25105+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
25106+ if (!a->mvd_h_dst_parent) {
25107+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
25108+ if (unlikely(err)) {
392086de 25109+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
25110+ goto out;
25111+ }
25112+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
25113+ }
25114+
25115+out:
25116+ AuTraceErr(err);
25117+ return err;
25118+}
25119+
25120+/* lock them all */
392086de 25121+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25122+{
25123+ int err;
25124+ struct dentry *h_trap;
25125+
25126+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
25127+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
c1595e42
JR
25128+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst,
25129+ au_opt_udba(a->sb),
25130+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
25131+ AuTraceErr(err);
25132+ if (unlikely(err)) {
25133+ AU_MVD_PR(dmsg, "pin_dst failed\n");
25134+ goto out;
25135+ }
25136+
c2b27bf2
AM
25137+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
25138+ a->rename_lock = 0;
c1595e42
JR
25139+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
25140+ AuLsc_DI_PARENT, AuLsc_I_PARENT3,
25141+ au_opt_udba(a->sb),
25142+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
25143+ err = au_do_pin(&a->mvd_pin_src);
25144+ AuTraceErr(err);
5527c038 25145+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
c1595e42
JR
25146+ if (unlikely(err)) {
25147+ AU_MVD_PR(dmsg, "pin_src failed\n");
25148+ goto out_dst;
25149+ }
25150+ goto out; /* success */
c2b27bf2
AM
25151+ }
25152+
c2b27bf2 25153+ a->rename_lock = 1;
c1595e42
JR
25154+ au_pin_hdir_unlock(&a->mvd_pin_dst);
25155+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
25156+ au_opt_udba(a->sb),
25157+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
25158+ AuTraceErr(err);
5527c038 25159+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
c1595e42
JR
25160+ if (unlikely(err)) {
25161+ AU_MVD_PR(dmsg, "pin_src failed\n");
25162+ au_pin_hdir_lock(&a->mvd_pin_dst);
25163+ goto out_dst;
25164+ }
25165+ au_pin_hdir_unlock(&a->mvd_pin_src);
c2b27bf2
AM
25166+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
25167+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
25168+ if (h_trap) {
25169+ err = (h_trap != a->mvd_h_src_parent);
25170+ if (err)
25171+ err = (h_trap != a->mvd_h_dst_parent);
25172+ }
25173+ BUG_ON(err); /* it should never happen */
c1595e42
JR
25174+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) {
25175+ err = -EBUSY;
25176+ AuTraceErr(err);
25177+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
25178+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
25179+ au_pin_hdir_lock(&a->mvd_pin_src);
25180+ au_unpin(&a->mvd_pin_src);
25181+ au_pin_hdir_lock(&a->mvd_pin_dst);
25182+ goto out_dst;
25183+ }
25184+ goto out; /* success */
c2b27bf2 25185+
c1595e42
JR
25186+out_dst:
25187+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
25188+out:
25189+ AuTraceErr(err);
25190+ return err;
25191+}
25192+
392086de 25193+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2 25194+{
c1595e42
JR
25195+ if (!a->rename_lock)
25196+ au_unpin(&a->mvd_pin_src);
25197+ else {
c2b27bf2
AM
25198+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
25199+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
c1595e42
JR
25200+ au_pin_hdir_lock(&a->mvd_pin_src);
25201+ au_unpin(&a->mvd_pin_src);
25202+ au_pin_hdir_lock(&a->mvd_pin_dst);
25203+ }
25204+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
25205+}
25206+
25207+/* copy-down the file */
392086de 25208+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25209+{
25210+ int err;
25211+ struct au_cp_generic cpg = {
25212+ .dentry = a->dentry,
25213+ .bdst = a->mvd_bdst,
25214+ .bsrc = a->mvd_bsrc,
25215+ .len = -1,
c1595e42 25216+ .pin = &a->mvd_pin_dst,
c2b27bf2
AM
25217+ .flags = AuCpup_DTIME | AuCpup_HOPEN
25218+ };
25219+
25220+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
25221+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
25222+ au_fset_cpup(cpg.flags, OVERWRITE);
25223+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
25224+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
25225+ err = au_sio_cpdown_simple(&cpg);
25226+ if (unlikely(err))
392086de 25227+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
25228+
25229+ AuTraceErr(err);
25230+ return err;
25231+}
25232+
25233+/*
25234+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
25235+ * were sleeping
25236+ */
392086de 25237+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25238+{
25239+ int err;
25240+ struct path h_path;
25241+ struct au_branch *br;
523b37e3 25242+ struct inode *delegated;
c2b27bf2
AM
25243+
25244+ br = au_sbr(a->sb, a->mvd_bdst);
25245+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
25246+ err = PTR_ERR(h_path.dentry);
25247+ if (IS_ERR(h_path.dentry)) {
392086de 25248+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
25249+ goto out;
25250+ }
25251+
25252+ err = 0;
5527c038 25253+ if (d_is_positive(h_path.dentry)) {
c2b27bf2 25254+ h_path.mnt = au_br_mnt(br);
523b37e3 25255+ delegated = NULL;
5527c038 25256+ err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path,
523b37e3
AM
25257+ &delegated, /*force*/0);
25258+ if (unlikely(err == -EWOULDBLOCK)) {
25259+ pr_warn("cannot retry for NFSv4 delegation"
25260+ " for an internal unlink\n");
25261+ iput(delegated);
25262+ }
c2b27bf2 25263+ if (unlikely(err))
392086de 25264+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
25265+ }
25266+ dput(h_path.dentry);
25267+
25268+out:
25269+ AuTraceErr(err);
25270+ return err;
25271+}
25272+
25273+/*
25274+ * unlink the topmost h_dentry
c2b27bf2 25275+ */
392086de 25276+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25277+{
25278+ int err;
25279+ struct path h_path;
523b37e3 25280+ struct inode *delegated;
c2b27bf2
AM
25281+
25282+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
25283+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
25284+ delegated = NULL;
25285+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
25286+ if (unlikely(err == -EWOULDBLOCK)) {
25287+ pr_warn("cannot retry for NFSv4 delegation"
25288+ " for an internal unlink\n");
25289+ iput(delegated);
25290+ }
c2b27bf2 25291+ if (unlikely(err))
392086de 25292+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
25293+
25294+ AuTraceErr(err);
25295+ return err;
25296+}
25297+
076b876e
AM
25298+/* Since mvdown succeeded, we ignore an error of this function */
25299+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
25300+{
25301+ int err;
25302+ struct au_branch *br;
25303+
25304+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
25305+ br = au_sbr(a->sb, a->mvd_bsrc);
25306+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
25307+ if (!err) {
25308+ br = au_sbr(a->sb, a->mvd_bdst);
25309+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
25310+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
25311+ }
25312+ if (!err)
25313+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
25314+ else
25315+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
25316+}
25317+
c2b27bf2
AM
25318+/*
25319+ * copy-down the file and unlink the bsrc file.
25320+ * - unlink the bdst whout if exist
25321+ * - copy-down the file (with whtmp name and rename)
25322+ * - unlink the bsrc file
25323+ */
392086de 25324+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25325+{
25326+ int err;
25327+
392086de 25328+ err = au_do_mkdir(dmsg, a);
c2b27bf2 25329+ if (!err)
392086de 25330+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
25331+ if (unlikely(err))
25332+ goto out;
25333+
25334+ /*
25335+ * do not revert the activities we made on bdst since they should be
25336+ * harmless in aufs.
25337+ */
25338+
392086de 25339+ err = au_do_cpdown(dmsg, a);
c2b27bf2 25340+ if (!err)
392086de
AM
25341+ err = au_do_unlink_wh(dmsg, a);
25342+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
25343+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
25344+ if (unlikely(err))
25345+ goto out_unlock;
25346+
c1595e42
JR
25347+ AuDbg("%pd2, 0x%x, %d --> %d\n",
25348+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst);
076b876e
AM
25349+ if (find_lower_writable(a) < 0)
25350+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
25351+
25352+ if (a->mvdown.flags & AUFS_MVDOWN_STFS)
25353+ au_do_stfs(dmsg, a);
25354+
c2b27bf2 25355+ /* maintain internal array */
392086de
AM
25356+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
25357+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
5afbbe0d 25358+ au_set_dbtop(a->dentry, a->mvd_bdst);
392086de 25359+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
5afbbe0d 25360+ au_set_ibtop(a->inode, a->mvd_bdst);
79b8bda9
AM
25361+ } else {
25362+ /* hide the lower */
25363+ au_set_h_dptr(a->dentry, a->mvd_bdst, NULL);
5afbbe0d 25364+ au_set_dbbot(a->dentry, a->mvd_bsrc);
79b8bda9 25365+ au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0);
5afbbe0d 25366+ au_set_ibbot(a->inode, a->mvd_bsrc);
392086de 25367+ }
5afbbe0d
AM
25368+ if (au_dbbot(a->dentry) < a->mvd_bdst)
25369+ au_set_dbbot(a->dentry, a->mvd_bdst);
25370+ if (au_ibbot(a->inode) < a->mvd_bdst)
25371+ au_set_ibbot(a->inode, a->mvd_bdst);
c2b27bf2
AM
25372+
25373+out_unlock:
392086de 25374+ au_do_unlock(dmsg, a);
c2b27bf2
AM
25375+out:
25376+ AuTraceErr(err);
25377+ return err;
25378+}
25379+
25380+/* ---------------------------------------------------------------------- */
25381+
c2b27bf2 25382+/* make sure the file is idle */
392086de 25383+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25384+{
25385+ int err, plinked;
c2b27bf2
AM
25386+
25387+ err = 0;
c2b27bf2 25388+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
5afbbe0d 25389+ if (au_dbtop(a->dentry) == a->mvd_bsrc
c1595e42 25390+ && au_dcount(a->dentry) == 1
c2b27bf2 25391+ && atomic_read(&a->inode->i_count) == 1
392086de 25392+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
25393+ && (!plinked || !au_plink_test(a->inode))
25394+ && a->inode->i_nlink == 1)
25395+ goto out;
25396+
25397+ err = -EBUSY;
392086de 25398+ AU_MVD_PR(dmsg,
c1595e42 25399+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
5afbbe0d 25400+ a->mvd_bsrc, au_dbtop(a->dentry), au_dcount(a->dentry),
c2b27bf2 25401+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 25402+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
25403+ plinked, plinked ? au_plink_test(a->inode) : 0);
25404+
25405+out:
25406+ AuTraceErr(err);
25407+ return err;
25408+}
25409+
25410+/* make sure the parent dir is fine */
392086de 25411+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
25412+ struct au_mvd_args *a)
25413+{
25414+ int err;
25415+ aufs_bindex_t bindex;
25416+
25417+ err = 0;
25418+ if (unlikely(au_alive_dir(a->parent))) {
25419+ err = -ENOENT;
392086de 25420+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
25421+ goto out;
25422+ }
25423+
25424+ a->bopq = au_dbdiropq(a->parent);
25425+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
25426+ AuDbg("b%d\n", bindex);
25427+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
25428+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
25429+ err = -EINVAL;
392086de
AM
25430+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
25431+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
25432+ a->bopq, a->mvd_bdst);
25433+ }
25434+
25435+out:
25436+ AuTraceErr(err);
25437+ return err;
25438+}
25439+
392086de 25440+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
25441+ struct au_mvd_args *a)
25442+{
25443+ int err;
25444+ struct au_dinfo *dinfo, *tmp;
25445+
25446+ /* lookup the next lower positive entry */
25447+ err = -ENOMEM;
25448+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
25449+ if (unlikely(!tmp))
25450+ goto out;
25451+
25452+ a->bfound = -1;
25453+ a->bwh = -1;
25454+ dinfo = au_di(a->dentry);
25455+ au_di_cp(tmp, dinfo);
25456+ au_di_swap(tmp, dinfo);
25457+
25458+ /* returns the number of positive dentries */
5afbbe0d
AM
25459+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1,
25460+ /* AuLkup_IGNORE_PERM */ 0);
c2b27bf2
AM
25461+ if (!err)
25462+ a->bwh = au_dbwh(a->dentry);
25463+ else if (err > 0)
5afbbe0d 25464+ a->bfound = au_dbtop(a->dentry);
c2b27bf2
AM
25465+
25466+ au_di_swap(tmp, dinfo);
25467+ au_rw_write_unlock(&tmp->di_rwsem);
25468+ au_di_free(tmp);
25469+ if (unlikely(err < 0))
392086de 25470+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
25471+
25472+ /*
25473+ * here, we have these cases.
25474+ * bfound == -1
25475+ * no positive dentry under bsrc. there are more sub-cases.
25476+ * bwh < 0
25477+ * there no whiteout, we can safely move-down.
25478+ * bwh <= bsrc
25479+ * impossible
25480+ * bsrc < bwh && bwh < bdst
25481+ * there is a whiteout on RO branch. cannot proceed.
25482+ * bwh == bdst
25483+ * there is a whiteout on the RW target branch. it should
25484+ * be removed.
25485+ * bdst < bwh
25486+ * there is a whiteout somewhere unrelated branch.
25487+ * -1 < bfound && bfound <= bsrc
25488+ * impossible.
25489+ * bfound < bdst
25490+ * found, but it is on RO branch between bsrc and bdst. cannot
25491+ * proceed.
25492+ * bfound == bdst
25493+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
25494+ * error.
25495+ * bdst < bfound
25496+ * found, after we create the file on bdst, it will be hidden.
25497+ */
25498+
25499+ AuDebugOn(a->bfound == -1
25500+ && a->bwh != -1
25501+ && a->bwh <= a->mvd_bsrc);
25502+ AuDebugOn(-1 < a->bfound
25503+ && a->bfound <= a->mvd_bsrc);
25504+
25505+ err = -EINVAL;
25506+ if (a->bfound == -1
25507+ && a->mvd_bsrc < a->bwh
25508+ && a->bwh != -1
25509+ && a->bwh < a->mvd_bdst) {
392086de
AM
25510+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
25511+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
25512+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
25513+ goto out;
25514+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
25515+ a->mvd_errno = EAU_MVDOWN_UPPER;
25516+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
25517+ a->mvd_bdst, a->bfound);
25518+ goto out;
25519+ }
25520+
25521+ err = 0; /* success */
25522+
25523+out:
25524+ AuTraceErr(err);
25525+ return err;
25526+}
25527+
392086de 25528+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25529+{
25530+ int err;
25531+
392086de
AM
25532+ err = 0;
25533+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
25534+ && a->bfound == a->mvd_bdst)
25535+ err = -EEXIST;
c2b27bf2
AM
25536+ AuTraceErr(err);
25537+ return err;
25538+}
25539+
392086de 25540+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
25541+{
25542+ int err;
25543+ struct au_branch *br;
25544+
25545+ err = -EISDIR;
25546+ if (unlikely(S_ISDIR(a->inode->i_mode)))
25547+ goto out;
25548+
25549+ err = -EINVAL;
392086de 25550+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
5afbbe0d 25551+ a->mvd_bsrc = au_ibtop(a->inode);
392086de
AM
25552+ else {
25553+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
25554+ if (unlikely(a->mvd_bsrc < 0
5afbbe0d
AM
25555+ || (a->mvd_bsrc < au_dbtop(a->dentry)
25556+ || au_dbbot(a->dentry) < a->mvd_bsrc
392086de 25557+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
5afbbe0d
AM
25558+ || (a->mvd_bsrc < au_ibtop(a->inode)
25559+ || au_ibbot(a->inode) < a->mvd_bsrc
392086de
AM
25560+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
25561+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
25562+ AU_MVD_PR(dmsg, "no upper\n");
25563+ goto out;
25564+ }
25565+ }
5afbbe0d 25566+ if (unlikely(a->mvd_bsrc == au_sbbot(a->sb))) {
392086de
AM
25567+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
25568+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
25569+ goto out;
25570+ }
392086de 25571+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
25572+ br = au_sbr(a->sb, a->mvd_bsrc);
25573+ err = au_br_rdonly(br);
392086de
AM
25574+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
25575+ if (unlikely(err))
25576+ goto out;
25577+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
25578+ || IS_APPEND(a->mvd_h_src_inode))) {
25579+ if (err)
25580+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
25581+ /* go on */
25582+ } else
c2b27bf2
AM
25583+ goto out;
25584+
25585+ err = -EINVAL;
392086de
AM
25586+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
25587+ a->mvd_bdst = find_lower_writable(a);
25588+ if (unlikely(a->mvd_bdst < 0)) {
25589+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
25590+ AU_MVD_PR(dmsg, "no writable lower branch\n");
25591+ goto out;
25592+ }
25593+ } else {
25594+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
25595+ if (unlikely(a->mvd_bdst < 0
5afbbe0d 25596+ || au_sbbot(a->sb) < a->mvd_bdst)) {
392086de
AM
25597+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
25598+ AU_MVD_PR(dmsg, "no lower brid\n");
25599+ goto out;
25600+ }
c2b27bf2
AM
25601+ }
25602+
392086de 25603+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 25604+ if (!err)
392086de 25605+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 25606+ if (!err)
392086de 25607+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 25608+ if (!err)
392086de 25609+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
25610+ if (!err)
25611+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
25612+
25613+out:
25614+ AuTraceErr(err);
25615+ return err;
25616+}
25617+
25618+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
25619+{
392086de
AM
25620+ int err, e;
25621+ unsigned char dmsg;
25622+ struct au_mvd_args *args;
79b8bda9 25623+ struct inode *inode;
c2b27bf2 25624+
79b8bda9 25625+ inode = d_inode(dentry);
c2b27bf2
AM
25626+ err = -EPERM;
25627+ if (unlikely(!capable(CAP_SYS_ADMIN)))
25628+ goto out;
25629+
392086de
AM
25630+ err = -ENOMEM;
25631+ args = kmalloc(sizeof(*args), GFP_NOFS);
25632+ if (unlikely(!args))
25633+ goto out;
25634+
25635+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
25636+ if (!err)
25637+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
25638+ if (unlikely(err)) {
25639+ err = -EFAULT;
392086de
AM
25640+ AuTraceErr(err);
25641+ goto out_free;
c2b27bf2 25642+ }
392086de
AM
25643+ AuDbg("flags 0x%x\n", args->mvdown.flags);
25644+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
25645+ args->mvdown.au_errno = 0;
25646+ args->dentry = dentry;
79b8bda9 25647+ args->inode = inode;
392086de 25648+ args->sb = dentry->d_sb;
c2b27bf2 25649+
392086de
AM
25650+ err = -ENOENT;
25651+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
25652+ args->parent = dget_parent(dentry);
5527c038 25653+ args->dir = d_inode(args->parent);
febd17d6 25654+ inode_lock_nested(args->dir, I_MUTEX_PARENT);
392086de
AM
25655+ dput(args->parent);
25656+ if (unlikely(args->parent != dentry->d_parent)) {
25657+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
25658+ goto out_dir;
25659+ }
25660+
febd17d6 25661+ inode_lock_nested(inode, I_MUTEX_CHILD);
b95c5147 25662+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW);
c2b27bf2
AM
25663+ if (unlikely(err))
25664+ goto out_inode;
25665+
392086de
AM
25666+ di_write_lock_parent(args->parent);
25667+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
25668+ if (unlikely(err))
25669+ goto out_parent;
25670+
392086de 25671+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
25672+ if (unlikely(err))
25673+ goto out_parent;
c2b27bf2 25674+
392086de 25675+ au_cpup_attr_timesizes(args->dir);
79b8bda9
AM
25676+ au_cpup_attr_timesizes(inode);
25677+ if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER))
25678+ au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst));
c2b27bf2
AM
25679+ /* au_digen_dec(dentry); */
25680+
25681+out_parent:
392086de 25682+ di_write_unlock(args->parent);
c2b27bf2
AM
25683+ aufs_read_unlock(dentry, AuLock_DW);
25684+out_inode:
febd17d6 25685+ inode_unlock(inode);
c2b27bf2 25686+out_dir:
febd17d6 25687+ inode_unlock(args->dir);
392086de
AM
25688+out_free:
25689+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
25690+ if (unlikely(e))
25691+ err = -EFAULT;
1c60b727 25692+ kfree(args);
c2b27bf2
AM
25693+out:
25694+ AuTraceErr(err);
25695+ return err;
25696+}
25697diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
25698--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
25699+++ linux/fs/aufs/opts.c 2018-10-23 12:33:35.599375796 +0200
25700@@ -0,0 +1,1877 @@
cd7a4cd9 25701+// SPDX-License-Identifier: GPL-2.0
1facf9fc 25702+/*
b00004a5 25703+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 25704+ *
25705+ * This program, aufs is free software; you can redistribute it and/or modify
25706+ * it under the terms of the GNU General Public License as published by
25707+ * the Free Software Foundation; either version 2 of the License, or
25708+ * (at your option) any later version.
dece6358
AM
25709+ *
25710+ * This program is distributed in the hope that it will be useful,
25711+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25712+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25713+ * GNU General Public License for more details.
25714+ *
25715+ * You should have received a copy of the GNU General Public License
523b37e3 25716+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25717+ */
25718+
25719+/*
25720+ * mount options/flags
25721+ */
25722+
dece6358 25723+#include <linux/namei.h>
1facf9fc 25724+#include <linux/types.h> /* a distribution requires */
25725+#include <linux/parser.h>
25726+#include "aufs.h"
25727+
25728+/* ---------------------------------------------------------------------- */
25729+
25730+enum {
25731+ Opt_br,
7e9cd9fe
AM
25732+ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
25733+ Opt_idel, Opt_imod,
25734+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
dece6358 25735+ Opt_rdblk_def, Opt_rdhash_def,
7e9cd9fe 25736+ Opt_xino, Opt_noxino,
1facf9fc 25737+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
25738+ Opt_trunc_xino_path, Opt_itrunc_xino,
25739+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 25740+ Opt_shwh, Opt_noshwh,
1facf9fc 25741+ Opt_plink, Opt_noplink, Opt_list_plink,
25742+ Opt_udba,
4a4d8108 25743+ Opt_dio, Opt_nodio,
1facf9fc 25744+ Opt_diropq_a, Opt_diropq_w,
25745+ Opt_warn_perm, Opt_nowarn_perm,
25746+ Opt_wbr_copyup, Opt_wbr_create,
076b876e 25747+ Opt_fhsm_sec,
1facf9fc 25748+ Opt_verbose, Opt_noverbose,
25749+ Opt_sum, Opt_nosum, Opt_wsum,
076b876e 25750+ Opt_dirperm1, Opt_nodirperm1,
8b6a4947 25751+ Opt_dirren, Opt_nodirren,
c1595e42 25752+ Opt_acl, Opt_noacl,
1facf9fc 25753+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
25754+};
25755+
25756+static match_table_t options = {
25757+ {Opt_br, "br=%s"},
25758+ {Opt_br, "br:%s"},
25759+
25760+ {Opt_add, "add=%d:%s"},
25761+ {Opt_add, "add:%d:%s"},
25762+ {Opt_add, "ins=%d:%s"},
25763+ {Opt_add, "ins:%d:%s"},
25764+ {Opt_append, "append=%s"},
25765+ {Opt_append, "append:%s"},
25766+ {Opt_prepend, "prepend=%s"},
25767+ {Opt_prepend, "prepend:%s"},
25768+
25769+ {Opt_del, "del=%s"},
25770+ {Opt_del, "del:%s"},
25771+ /* {Opt_idel, "idel:%d"}, */
25772+ {Opt_mod, "mod=%s"},
25773+ {Opt_mod, "mod:%s"},
25774+ /* {Opt_imod, "imod:%d:%s"}, */
25775+
25776+ {Opt_dirwh, "dirwh=%d"},
25777+
25778+ {Opt_xino, "xino=%s"},
25779+ {Opt_noxino, "noxino"},
25780+ {Opt_trunc_xino, "trunc_xino"},
25781+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
25782+ {Opt_notrunc_xino, "notrunc_xino"},
25783+ {Opt_trunc_xino_path, "trunc_xino=%s"},
25784+ {Opt_itrunc_xino, "itrunc_xino=%d"},
25785+ /* {Opt_zxino, "zxino=%s"}, */
25786+ {Opt_trunc_xib, "trunc_xib"},
25787+ {Opt_notrunc_xib, "notrunc_xib"},
25788+
e49829fe 25789+#ifdef CONFIG_PROC_FS
1facf9fc 25790+ {Opt_plink, "plink"},
e49829fe
JR
25791+#else
25792+ {Opt_ignore_silent, "plink"},
25793+#endif
25794+
1facf9fc 25795+ {Opt_noplink, "noplink"},
e49829fe 25796+
1facf9fc 25797+#ifdef CONFIG_AUFS_DEBUG
25798+ {Opt_list_plink, "list_plink"},
25799+#endif
25800+
25801+ {Opt_udba, "udba=%s"},
25802+
4a4d8108
AM
25803+ {Opt_dio, "dio"},
25804+ {Opt_nodio, "nodio"},
25805+
8b6a4947
AM
25806+#ifdef CONFIG_AUFS_DIRREN
25807+ {Opt_dirren, "dirren"},
25808+ {Opt_nodirren, "nodirren"},
25809+#else
25810+ {Opt_ignore, "dirren"},
25811+ {Opt_ignore_silent, "nodirren"},
25812+#endif
25813+
076b876e
AM
25814+#ifdef CONFIG_AUFS_FHSM
25815+ {Opt_fhsm_sec, "fhsm_sec=%d"},
25816+#else
8b6a4947 25817+ {Opt_ignore, "fhsm_sec=%d"},
076b876e
AM
25818+#endif
25819+
1facf9fc 25820+ {Opt_diropq_a, "diropq=always"},
25821+ {Opt_diropq_a, "diropq=a"},
25822+ {Opt_diropq_w, "diropq=whiteouted"},
25823+ {Opt_diropq_w, "diropq=w"},
25824+
25825+ {Opt_warn_perm, "warn_perm"},
25826+ {Opt_nowarn_perm, "nowarn_perm"},
25827+
25828+ /* keep them temporary */
1facf9fc 25829+ {Opt_ignore_silent, "nodlgt"},
8b6a4947 25830+ {Opt_ignore, "clean_plink"},
1facf9fc 25831+
dece6358
AM
25832+#ifdef CONFIG_AUFS_SHWH
25833+ {Opt_shwh, "shwh"},
25834+#endif
25835+ {Opt_noshwh, "noshwh"},
25836+
076b876e
AM
25837+ {Opt_dirperm1, "dirperm1"},
25838+ {Opt_nodirperm1, "nodirperm1"},
25839+
1facf9fc 25840+ {Opt_verbose, "verbose"},
25841+ {Opt_verbose, "v"},
25842+ {Opt_noverbose, "noverbose"},
25843+ {Opt_noverbose, "quiet"},
25844+ {Opt_noverbose, "q"},
25845+ {Opt_noverbose, "silent"},
25846+
25847+ {Opt_sum, "sum"},
25848+ {Opt_nosum, "nosum"},
25849+ {Opt_wsum, "wsum"},
25850+
25851+ {Opt_rdcache, "rdcache=%d"},
25852+ {Opt_rdblk, "rdblk=%d"},
dece6358 25853+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 25854+ {Opt_rdhash, "rdhash=%d"},
dece6358 25855+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 25856+
25857+ {Opt_wbr_create, "create=%s"},
25858+ {Opt_wbr_create, "create_policy=%s"},
25859+ {Opt_wbr_copyup, "cpup=%s"},
25860+ {Opt_wbr_copyup, "copyup=%s"},
25861+ {Opt_wbr_copyup, "copyup_policy=%s"},
25862+
c1595e42
JR
25863+ /* generic VFS flag */
25864+#ifdef CONFIG_FS_POSIX_ACL
25865+ {Opt_acl, "acl"},
25866+ {Opt_noacl, "noacl"},
25867+#else
8b6a4947 25868+ {Opt_ignore, "acl"},
c1595e42
JR
25869+ {Opt_ignore_silent, "noacl"},
25870+#endif
25871+
1facf9fc 25872+ /* internal use for the scripts */
25873+ {Opt_ignore_silent, "si=%s"},
25874+
25875+ {Opt_br, "dirs=%s"},
25876+ {Opt_ignore, "debug=%d"},
25877+ {Opt_ignore, "delete=whiteout"},
25878+ {Opt_ignore, "delete=all"},
25879+ {Opt_ignore, "imap=%s"},
25880+
1308ab2a 25881+ /* temporary workaround, due to old mount(8)? */
25882+ {Opt_ignore_silent, "relatime"},
25883+
1facf9fc 25884+ {Opt_err, NULL}
25885+};
25886+
25887+/* ---------------------------------------------------------------------- */
25888+
076b876e 25889+static const char *au_parser_pattern(int val, match_table_t tbl)
1facf9fc 25890+{
076b876e
AM
25891+ struct match_token *p;
25892+
25893+ p = tbl;
25894+ while (p->pattern) {
25895+ if (p->token == val)
25896+ return p->pattern;
25897+ p++;
1facf9fc 25898+ }
25899+ BUG();
25900+ return "??";
25901+}
25902+
076b876e
AM
25903+static const char *au_optstr(int *val, match_table_t tbl)
25904+{
25905+ struct match_token *p;
25906+ int v;
25907+
25908+ v = *val;
2000de60
JR
25909+ if (!v)
25910+ goto out;
076b876e 25911+ p = tbl;
2000de60
JR
25912+ while (p->pattern) {
25913+ if (p->token
25914+ && (v & p->token) == p->token) {
076b876e
AM
25915+ *val &= ~p->token;
25916+ return p->pattern;
25917+ }
25918+ p++;
25919+ }
2000de60
JR
25920+
25921+out:
076b876e
AM
25922+ return NULL;
25923+}
25924+
1facf9fc 25925+/* ---------------------------------------------------------------------- */
25926+
1e00d052 25927+static match_table_t brperm = {
1facf9fc 25928+ {AuBrPerm_RO, AUFS_BRPERM_RO},
25929+ {AuBrPerm_RR, AUFS_BRPERM_RR},
25930+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
25931+ {0, NULL}
25932+};
1facf9fc 25933+
86dc4139 25934+static match_table_t brattr = {
076b876e
AM
25935+ /* general */
25936+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
25937+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
c1595e42 25938+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
86dc4139 25939+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
2000de60 25940+#ifdef CONFIG_AUFS_FHSM
076b876e 25941+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
2000de60
JR
25942+#endif
25943+#ifdef CONFIG_AUFS_XATTR
c1595e42
JR
25944+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
25945+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
25946+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
25947+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
25948+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
25949+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
2000de60 25950+#endif
076b876e
AM
25951+
25952+ /* ro/rr branch */
1e00d052 25953+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
076b876e
AM
25954+
25955+ /* rw branch */
25956+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
1e00d052 25957+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
076b876e 25958+
1e00d052 25959+ {0, NULL}
1facf9fc 25960+};
25961+
1e00d052
AM
25962+static int br_attr_val(char *str, match_table_t table, substring_t args[])
25963+{
25964+ int attr, v;
25965+ char *p;
25966+
25967+ attr = 0;
25968+ do {
25969+ p = strchr(str, '+');
25970+ if (p)
25971+ *p = 0;
25972+ v = match_token(str, table, args);
076b876e
AM
25973+ if (v) {
25974+ if (v & AuBrAttr_CMOO_Mask)
25975+ attr &= ~AuBrAttr_CMOO_Mask;
1e00d052 25976+ attr |= v;
076b876e 25977+ } else {
1e00d052
AM
25978+ if (p)
25979+ *p = '+';
0c3ec466 25980+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
25981+ break;
25982+ }
25983+ if (p)
25984+ str = p + 1;
25985+ } while (p);
25986+
25987+ return attr;
25988+}
25989+
076b876e
AM
25990+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
25991+{
25992+ int sz;
25993+ const char *p;
25994+ char *q;
25995+
076b876e
AM
25996+ q = str->a;
25997+ *q = 0;
25998+ p = au_optstr(&perm, brattr);
25999+ if (p) {
26000+ sz = strlen(p);
26001+ memcpy(q, p, sz + 1);
26002+ q += sz;
26003+ } else
26004+ goto out;
26005+
26006+ do {
26007+ p = au_optstr(&perm, brattr);
26008+ if (p) {
26009+ *q++ = '+';
26010+ sz = strlen(p);
26011+ memcpy(q, p, sz + 1);
26012+ q += sz;
26013+ }
26014+ } while (p);
26015+
26016+out:
c1595e42 26017+ return q - str->a;
076b876e
AM
26018+}
26019+
4a4d8108 26020+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 26021+{
076b876e
AM
26022+ int val, bad, sz;
26023+ char *p;
1facf9fc 26024+ substring_t args[MAX_OPT_ARGS];
076b876e 26025+ au_br_perm_str_t attr;
1facf9fc 26026+
1e00d052
AM
26027+ p = strchr(perm, '+');
26028+ if (p)
26029+ *p = 0;
26030+ val = match_token(perm, brperm, args);
26031+ if (!val) {
26032+ if (p)
26033+ *p = '+';
0c3ec466 26034+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
26035+ val = AuBrPerm_RO;
26036+ goto out;
26037+ }
26038+ if (!p)
26039+ goto out;
26040+
076b876e
AM
26041+ val |= br_attr_val(p + 1, brattr, args);
26042+
26043+ bad = 0;
86dc4139 26044+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
26045+ case AuBrPerm_RO:
26046+ case AuBrPerm_RR:
076b876e
AM
26047+ bad = val & AuBrWAttr_Mask;
26048+ val &= ~AuBrWAttr_Mask;
1e00d052
AM
26049+ break;
26050+ case AuBrPerm_RW:
076b876e
AM
26051+ bad = val & AuBrRAttr_Mask;
26052+ val &= ~AuBrRAttr_Mask;
1e00d052
AM
26053+ break;
26054+ }
c1595e42
JR
26055+
26056+ /*
26057+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
26058+ * does not treat it as an error, just warning.
26059+ * this is a tiny guard for the user operation.
26060+ */
26061+ if (val & AuBrAttr_UNPIN) {
26062+ bad |= AuBrAttr_UNPIN;
26063+ val &= ~AuBrAttr_UNPIN;
26064+ }
26065+
076b876e
AM
26066+ if (unlikely(bad)) {
26067+ sz = au_do_optstr_br_attr(&attr, bad);
26068+ AuDebugOn(!sz);
26069+ pr_warn("ignored branch attribute %s\n", attr.a);
26070+ }
1e00d052
AM
26071+
26072+out:
1facf9fc 26073+ return val;
26074+}
26075+
076b876e 26076+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
1facf9fc 26077+{
076b876e
AM
26078+ au_br_perm_str_t attr;
26079+ const char *p;
26080+ char *q;
1e00d052
AM
26081+ int sz;
26082+
076b876e
AM
26083+ q = str->a;
26084+ p = au_optstr(&perm, brperm);
26085+ AuDebugOn(!p || !*p);
26086+ sz = strlen(p);
26087+ memcpy(q, p, sz + 1);
26088+ q += sz;
1e00d052 26089+
076b876e
AM
26090+ sz = au_do_optstr_br_attr(&attr, perm);
26091+ if (sz) {
26092+ *q++ = '+';
26093+ memcpy(q, attr.a, sz + 1);
1e00d052
AM
26094+ }
26095+
076b876e 26096+ AuDebugOn(strlen(str->a) >= sizeof(str->a));
1facf9fc 26097+}
26098+
26099+/* ---------------------------------------------------------------------- */
26100+
26101+static match_table_t udbalevel = {
26102+ {AuOpt_UDBA_REVAL, "reval"},
26103+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
26104+#ifdef CONFIG_AUFS_HNOTIFY
26105+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
26106+#ifdef CONFIG_AUFS_HFSNOTIFY
26107+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 26108+#endif
1facf9fc 26109+#endif
26110+ {-1, NULL}
26111+};
26112+
4a4d8108 26113+static int noinline_for_stack udba_val(char *str)
1facf9fc 26114+{
26115+ substring_t args[MAX_OPT_ARGS];
26116+
7f207e10 26117+ return match_token(str, udbalevel, args);
1facf9fc 26118+}
26119+
26120+const char *au_optstr_udba(int udba)
26121+{
076b876e 26122+ return au_parser_pattern(udba, udbalevel);
1facf9fc 26123+}
26124+
26125+/* ---------------------------------------------------------------------- */
26126+
26127+static match_table_t au_wbr_create_policy = {
26128+ {AuWbrCreate_TDP, "tdp"},
26129+ {AuWbrCreate_TDP, "top-down-parent"},
26130+ {AuWbrCreate_RR, "rr"},
26131+ {AuWbrCreate_RR, "round-robin"},
26132+ {AuWbrCreate_MFS, "mfs"},
26133+ {AuWbrCreate_MFS, "most-free-space"},
26134+ {AuWbrCreate_MFSV, "mfs:%d"},
26135+ {AuWbrCreate_MFSV, "most-free-space:%d"},
26136+
f2c43d5f
AM
26137+ /* top-down regardless the parent, and then mfs */
26138+ {AuWbrCreate_TDMFS, "tdmfs:%d"},
26139+ {AuWbrCreate_TDMFSV, "tdmfs:%d:%d"},
26140+
1facf9fc 26141+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
26142+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
26143+ {AuWbrCreate_PMFS, "pmfs"},
26144+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
26145+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
26146+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 26147+
26148+ {-1, NULL}
26149+};
26150+
1facf9fc 26151+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
26152+ struct au_opt_wbr_create *create)
26153+{
26154+ int err;
26155+ unsigned long long ull;
26156+
26157+ err = 0;
a2654f78 26158+ if (!match_u64(arg, &ull))
1facf9fc 26159+ create->mfsrr_watermark = ull;
26160+ else {
4a4d8108 26161+ pr_err("bad integer in %s\n", str);
1facf9fc 26162+ err = -EINVAL;
26163+ }
26164+
26165+ return err;
26166+}
26167+
26168+static int au_wbr_mfs_sec(substring_t *arg, char *str,
26169+ struct au_opt_wbr_create *create)
26170+{
26171+ int n, err;
26172+
26173+ err = 0;
027c5e7a 26174+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 26175+ create->mfs_second = n;
26176+ else {
4a4d8108 26177+ pr_err("bad integer in %s\n", str);
1facf9fc 26178+ err = -EINVAL;
26179+ }
26180+
26181+ return err;
26182+}
26183+
4a4d8108
AM
26184+static int noinline_for_stack
26185+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 26186+{
26187+ int err, e;
26188+ substring_t args[MAX_OPT_ARGS];
26189+
26190+ err = match_token(str, au_wbr_create_policy, args);
26191+ create->wbr_create = err;
26192+ switch (err) {
26193+ case AuWbrCreate_MFSRRV:
f2c43d5f 26194+ case AuWbrCreate_TDMFSV:
392086de 26195+ case AuWbrCreate_PMFSRRV:
1facf9fc 26196+ e = au_wbr_mfs_wmark(&args[0], str, create);
26197+ if (!e)
26198+ e = au_wbr_mfs_sec(&args[1], str, create);
26199+ if (unlikely(e))
26200+ err = e;
26201+ break;
26202+ case AuWbrCreate_MFSRR:
f2c43d5f 26203+ case AuWbrCreate_TDMFS:
392086de 26204+ case AuWbrCreate_PMFSRR:
1facf9fc 26205+ e = au_wbr_mfs_wmark(&args[0], str, create);
26206+ if (unlikely(e)) {
26207+ err = e;
26208+ break;
26209+ }
26210+ /*FALLTHROUGH*/
26211+ case AuWbrCreate_MFS:
26212+ case AuWbrCreate_PMFS:
027c5e7a 26213+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 26214+ break;
26215+ case AuWbrCreate_MFSV:
26216+ case AuWbrCreate_PMFSV:
26217+ e = au_wbr_mfs_sec(&args[0], str, create);
26218+ if (unlikely(e))
26219+ err = e;
26220+ break;
26221+ }
26222+
26223+ return err;
26224+}
26225+
26226+const char *au_optstr_wbr_create(int wbr_create)
26227+{
076b876e 26228+ return au_parser_pattern(wbr_create, au_wbr_create_policy);
1facf9fc 26229+}
26230+
26231+static match_table_t au_wbr_copyup_policy = {
26232+ {AuWbrCopyup_TDP, "tdp"},
26233+ {AuWbrCopyup_TDP, "top-down-parent"},
26234+ {AuWbrCopyup_BUP, "bup"},
26235+ {AuWbrCopyup_BUP, "bottom-up-parent"},
26236+ {AuWbrCopyup_BU, "bu"},
26237+ {AuWbrCopyup_BU, "bottom-up"},
26238+ {-1, NULL}
26239+};
26240+
4a4d8108 26241+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 26242+{
26243+ substring_t args[MAX_OPT_ARGS];
26244+
26245+ return match_token(str, au_wbr_copyup_policy, args);
26246+}
26247+
26248+const char *au_optstr_wbr_copyup(int wbr_copyup)
26249+{
076b876e 26250+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
1facf9fc 26251+}
26252+
26253+/* ---------------------------------------------------------------------- */
26254+
26255+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
26256+
26257+static void dump_opts(struct au_opts *opts)
26258+{
26259+#ifdef CONFIG_AUFS_DEBUG
26260+ /* reduce stack space */
26261+ union {
26262+ struct au_opt_add *add;
26263+ struct au_opt_del *del;
26264+ struct au_opt_mod *mod;
26265+ struct au_opt_xino *xino;
26266+ struct au_opt_xino_itrunc *xino_itrunc;
26267+ struct au_opt_wbr_create *create;
26268+ } u;
26269+ struct au_opt *opt;
26270+
26271+ opt = opts->opt;
26272+ while (opt->type != Opt_tail) {
26273+ switch (opt->type) {
26274+ case Opt_add:
26275+ u.add = &opt->add;
26276+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
26277+ u.add->bindex, u.add->pathname, u.add->perm,
26278+ u.add->path.dentry);
26279+ break;
26280+ case Opt_del:
26281+ case Opt_idel:
26282+ u.del = &opt->del;
26283+ AuDbg("del {%s, %p}\n",
26284+ u.del->pathname, u.del->h_path.dentry);
26285+ break;
26286+ case Opt_mod:
26287+ case Opt_imod:
26288+ u.mod = &opt->mod;
26289+ AuDbg("mod {%s, 0x%x, %p}\n",
26290+ u.mod->path, u.mod->perm, u.mod->h_root);
26291+ break;
26292+ case Opt_append:
26293+ u.add = &opt->add;
26294+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
26295+ u.add->bindex, u.add->pathname, u.add->perm,
26296+ u.add->path.dentry);
26297+ break;
26298+ case Opt_prepend:
26299+ u.add = &opt->add;
26300+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
26301+ u.add->bindex, u.add->pathname, u.add->perm,
26302+ u.add->path.dentry);
26303+ break;
26304+ case Opt_dirwh:
26305+ AuDbg("dirwh %d\n", opt->dirwh);
26306+ break;
26307+ case Opt_rdcache:
26308+ AuDbg("rdcache %d\n", opt->rdcache);
26309+ break;
26310+ case Opt_rdblk:
26311+ AuDbg("rdblk %u\n", opt->rdblk);
26312+ break;
dece6358
AM
26313+ case Opt_rdblk_def:
26314+ AuDbg("rdblk_def\n");
26315+ break;
1facf9fc 26316+ case Opt_rdhash:
26317+ AuDbg("rdhash %u\n", opt->rdhash);
26318+ break;
dece6358
AM
26319+ case Opt_rdhash_def:
26320+ AuDbg("rdhash_def\n");
26321+ break;
1facf9fc 26322+ case Opt_xino:
26323+ u.xino = &opt->xino;
523b37e3 26324+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 26325+ break;
26326+ case Opt_trunc_xino:
26327+ AuLabel(trunc_xino);
26328+ break;
26329+ case Opt_notrunc_xino:
26330+ AuLabel(notrunc_xino);
26331+ break;
26332+ case Opt_trunc_xino_path:
26333+ case Opt_itrunc_xino:
26334+ u.xino_itrunc = &opt->xino_itrunc;
26335+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
26336+ break;
1facf9fc 26337+ case Opt_noxino:
26338+ AuLabel(noxino);
26339+ break;
26340+ case Opt_trunc_xib:
26341+ AuLabel(trunc_xib);
26342+ break;
26343+ case Opt_notrunc_xib:
26344+ AuLabel(notrunc_xib);
26345+ break;
dece6358
AM
26346+ case Opt_shwh:
26347+ AuLabel(shwh);
26348+ break;
26349+ case Opt_noshwh:
26350+ AuLabel(noshwh);
26351+ break;
076b876e
AM
26352+ case Opt_dirperm1:
26353+ AuLabel(dirperm1);
26354+ break;
26355+ case Opt_nodirperm1:
26356+ AuLabel(nodirperm1);
26357+ break;
1facf9fc 26358+ case Opt_plink:
26359+ AuLabel(plink);
26360+ break;
26361+ case Opt_noplink:
26362+ AuLabel(noplink);
26363+ break;
26364+ case Opt_list_plink:
26365+ AuLabel(list_plink);
26366+ break;
26367+ case Opt_udba:
26368+ AuDbg("udba %d, %s\n",
26369+ opt->udba, au_optstr_udba(opt->udba));
26370+ break;
4a4d8108
AM
26371+ case Opt_dio:
26372+ AuLabel(dio);
26373+ break;
26374+ case Opt_nodio:
26375+ AuLabel(nodio);
26376+ break;
1facf9fc 26377+ case Opt_diropq_a:
26378+ AuLabel(diropq_a);
26379+ break;
26380+ case Opt_diropq_w:
26381+ AuLabel(diropq_w);
26382+ break;
26383+ case Opt_warn_perm:
26384+ AuLabel(warn_perm);
26385+ break;
26386+ case Opt_nowarn_perm:
26387+ AuLabel(nowarn_perm);
26388+ break;
1facf9fc 26389+ case Opt_verbose:
26390+ AuLabel(verbose);
26391+ break;
26392+ case Opt_noverbose:
26393+ AuLabel(noverbose);
26394+ break;
26395+ case Opt_sum:
26396+ AuLabel(sum);
26397+ break;
26398+ case Opt_nosum:
26399+ AuLabel(nosum);
26400+ break;
26401+ case Opt_wsum:
26402+ AuLabel(wsum);
26403+ break;
26404+ case Opt_wbr_create:
26405+ u.create = &opt->wbr_create;
26406+ AuDbg("create %d, %s\n", u.create->wbr_create,
26407+ au_optstr_wbr_create(u.create->wbr_create));
26408+ switch (u.create->wbr_create) {
26409+ case AuWbrCreate_MFSV:
26410+ case AuWbrCreate_PMFSV:
26411+ AuDbg("%d sec\n", u.create->mfs_second);
26412+ break;
26413+ case AuWbrCreate_MFSRR:
f2c43d5f 26414+ case AuWbrCreate_TDMFS:
1facf9fc 26415+ AuDbg("%llu watermark\n",
26416+ u.create->mfsrr_watermark);
26417+ break;
26418+ case AuWbrCreate_MFSRRV:
f2c43d5f 26419+ case AuWbrCreate_TDMFSV:
392086de 26420+ case AuWbrCreate_PMFSRRV:
1facf9fc 26421+ AuDbg("%llu watermark, %d sec\n",
26422+ u.create->mfsrr_watermark,
26423+ u.create->mfs_second);
26424+ break;
26425+ }
26426+ break;
26427+ case Opt_wbr_copyup:
26428+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
26429+ au_optstr_wbr_copyup(opt->wbr_copyup));
26430+ break;
076b876e
AM
26431+ case Opt_fhsm_sec:
26432+ AuDbg("fhsm_sec %u\n", opt->fhsm_second);
26433+ break;
8b6a4947
AM
26434+ case Opt_dirren:
26435+ AuLabel(dirren);
26436+ break;
26437+ case Opt_nodirren:
26438+ AuLabel(nodirren);
26439+ break;
c1595e42
JR
26440+ case Opt_acl:
26441+ AuLabel(acl);
26442+ break;
26443+ case Opt_noacl:
26444+ AuLabel(noacl);
26445+ break;
1facf9fc 26446+ default:
26447+ BUG();
26448+ }
26449+ opt++;
26450+ }
26451+#endif
26452+}
26453+
26454+void au_opts_free(struct au_opts *opts)
26455+{
26456+ struct au_opt *opt;
26457+
26458+ opt = opts->opt;
26459+ while (opt->type != Opt_tail) {
26460+ switch (opt->type) {
26461+ case Opt_add:
26462+ case Opt_append:
26463+ case Opt_prepend:
26464+ path_put(&opt->add.path);
26465+ break;
26466+ case Opt_del:
26467+ case Opt_idel:
26468+ path_put(&opt->del.h_path);
26469+ break;
26470+ case Opt_mod:
26471+ case Opt_imod:
26472+ dput(opt->mod.h_root);
26473+ break;
26474+ case Opt_xino:
26475+ fput(opt->xino.file);
26476+ break;
26477+ }
26478+ opt++;
26479+ }
26480+}
26481+
26482+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
26483+ aufs_bindex_t bindex)
26484+{
26485+ int err;
26486+ struct au_opt_add *add = &opt->add;
26487+ char *p;
26488+
26489+ add->bindex = bindex;
1e00d052 26490+ add->perm = AuBrPerm_RO;
1facf9fc 26491+ add->pathname = opt_str;
26492+ p = strchr(opt_str, '=');
26493+ if (p) {
26494+ *p++ = 0;
26495+ if (*p)
26496+ add->perm = br_perm_val(p);
26497+ }
26498+
26499+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
26500+ if (!err) {
26501+ if (!p) {
26502+ add->perm = AuBrPerm_RO;
26503+ if (au_test_fs_rr(add->path.dentry->d_sb))
26504+ add->perm = AuBrPerm_RR;
2121bcd9 26505+ else if (!bindex && !(sb_flags & SB_RDONLY))
1facf9fc 26506+ add->perm = AuBrPerm_RW;
26507+ }
26508+ opt->type = Opt_add;
26509+ goto out;
26510+ }
4a4d8108 26511+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 26512+ err = -EINVAL;
26513+
4f0767ce 26514+out:
1facf9fc 26515+ return err;
26516+}
26517+
26518+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
26519+{
26520+ int err;
26521+
26522+ del->pathname = args[0].from;
26523+ AuDbg("del path %s\n", del->pathname);
26524+
26525+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
26526+ if (unlikely(err))
4a4d8108 26527+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 26528+
26529+ return err;
26530+}
26531+
26532+#if 0 /* reserved for future use */
26533+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
26534+ struct au_opt_del *del, substring_t args[])
26535+{
26536+ int err;
26537+ struct dentry *root;
26538+
26539+ err = -EINVAL;
26540+ root = sb->s_root;
26541+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 26542+ if (bindex < 0 || au_sbbot(sb) < bindex) {
4a4d8108 26543+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 26544+ goto out;
26545+ }
26546+
26547+ err = 0;
26548+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
26549+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
26550+
4f0767ce 26551+out:
1facf9fc 26552+ aufs_read_unlock(root, !AuLock_IR);
26553+ return err;
26554+}
26555+#endif
26556+
4a4d8108
AM
26557+static int noinline_for_stack
26558+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 26559+{
26560+ int err;
26561+ struct path path;
26562+ char *p;
26563+
26564+ err = -EINVAL;
26565+ mod->path = args[0].from;
26566+ p = strchr(mod->path, '=');
26567+ if (unlikely(!p)) {
acd2b654 26568+ pr_err("no permission %s\n", args[0].from);
1facf9fc 26569+ goto out;
26570+ }
26571+
26572+ *p++ = 0;
26573+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
26574+ if (unlikely(err)) {
4a4d8108 26575+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 26576+ goto out;
26577+ }
26578+
26579+ mod->perm = br_perm_val(p);
26580+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
26581+ mod->h_root = dget(path.dentry);
26582+ path_put(&path);
26583+
4f0767ce 26584+out:
1facf9fc 26585+ return err;
26586+}
26587+
26588+#if 0 /* reserved for future use */
26589+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
26590+ struct au_opt_mod *mod, substring_t args[])
26591+{
26592+ int err;
26593+ struct dentry *root;
26594+
26595+ err = -EINVAL;
26596+ root = sb->s_root;
26597+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 26598+ if (bindex < 0 || au_sbbot(sb) < bindex) {
4a4d8108 26599+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 26600+ goto out;
26601+ }
26602+
26603+ err = 0;
26604+ mod->perm = br_perm_val(args[1].from);
26605+ AuDbg("mod path %s, perm 0x%x, %s\n",
26606+ mod->path, mod->perm, args[1].from);
26607+ mod->h_root = dget(au_h_dptr(root, bindex));
26608+
4f0767ce 26609+out:
1facf9fc 26610+ aufs_read_unlock(root, !AuLock_IR);
26611+ return err;
26612+}
26613+#endif
26614+
26615+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
26616+ substring_t args[])
26617+{
26618+ int err;
26619+ struct file *file;
26620+
26621+ file = au_xino_create(sb, args[0].from, /*silent*/0);
26622+ err = PTR_ERR(file);
26623+ if (IS_ERR(file))
26624+ goto out;
26625+
26626+ err = -EINVAL;
2000de60 26627+ if (unlikely(file->f_path.dentry->d_sb == sb)) {
1facf9fc 26628+ fput(file);
4a4d8108 26629+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 26630+ goto out;
26631+ }
26632+
26633+ err = 0;
26634+ xino->file = file;
26635+ xino->path = args[0].from;
26636+
4f0767ce 26637+out:
1facf9fc 26638+ return err;
26639+}
26640+
4a4d8108
AM
26641+static int noinline_for_stack
26642+au_opts_parse_xino_itrunc_path(struct super_block *sb,
26643+ struct au_opt_xino_itrunc *xino_itrunc,
26644+ substring_t args[])
1facf9fc 26645+{
26646+ int err;
5afbbe0d 26647+ aufs_bindex_t bbot, bindex;
1facf9fc 26648+ struct path path;
26649+ struct dentry *root;
26650+
26651+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
26652+ if (unlikely(err)) {
4a4d8108 26653+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 26654+ goto out;
26655+ }
26656+
26657+ xino_itrunc->bindex = -1;
26658+ root = sb->s_root;
26659+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d
AM
26660+ bbot = au_sbbot(sb);
26661+ for (bindex = 0; bindex <= bbot; bindex++) {
1facf9fc 26662+ if (au_h_dptr(root, bindex) == path.dentry) {
26663+ xino_itrunc->bindex = bindex;
26664+ break;
26665+ }
26666+ }
26667+ aufs_read_unlock(root, !AuLock_IR);
26668+ path_put(&path);
26669+
26670+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 26671+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 26672+ err = -EINVAL;
26673+ }
26674+
4f0767ce 26675+out:
1facf9fc 26676+ return err;
26677+}
26678+
26679+/* called without aufs lock */
26680+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
26681+{
26682+ int err, n, token;
26683+ aufs_bindex_t bindex;
26684+ unsigned char skipped;
26685+ struct dentry *root;
26686+ struct au_opt *opt, *opt_tail;
26687+ char *opt_str;
26688+ /* reduce the stack space */
26689+ union {
26690+ struct au_opt_xino_itrunc *xino_itrunc;
26691+ struct au_opt_wbr_create *create;
26692+ } u;
26693+ struct {
26694+ substring_t args[MAX_OPT_ARGS];
26695+ } *a;
26696+
26697+ err = -ENOMEM;
26698+ a = kmalloc(sizeof(*a), GFP_NOFS);
26699+ if (unlikely(!a))
26700+ goto out;
26701+
26702+ root = sb->s_root;
26703+ err = 0;
26704+ bindex = 0;
26705+ opt = opts->opt;
26706+ opt_tail = opt + opts->max_opt - 1;
26707+ opt->type = Opt_tail;
26708+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
26709+ err = -EINVAL;
26710+ skipped = 0;
26711+ token = match_token(opt_str, options, a->args);
26712+ switch (token) {
26713+ case Opt_br:
26714+ err = 0;
26715+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
26716+ && *opt_str) {
26717+ err = opt_add(opt, opt_str, opts->sb_flags,
26718+ bindex++);
26719+ if (unlikely(!err && ++opt > opt_tail)) {
26720+ err = -E2BIG;
26721+ break;
26722+ }
26723+ opt->type = Opt_tail;
26724+ skipped = 1;
26725+ }
26726+ break;
26727+ case Opt_add:
26728+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 26729+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26730+ break;
26731+ }
26732+ bindex = n;
26733+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
26734+ bindex);
26735+ if (!err)
26736+ opt->type = token;
26737+ break;
26738+ case Opt_append:
26739+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
26740+ /*dummy bindex*/1);
26741+ if (!err)
26742+ opt->type = token;
26743+ break;
26744+ case Opt_prepend:
26745+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
26746+ /*bindex*/0);
26747+ if (!err)
26748+ opt->type = token;
26749+ break;
26750+ case Opt_del:
26751+ err = au_opts_parse_del(&opt->del, a->args);
26752+ if (!err)
26753+ opt->type = token;
26754+ break;
26755+#if 0 /* reserved for future use */
26756+ case Opt_idel:
26757+ del->pathname = "(indexed)";
26758+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 26759+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26760+ break;
26761+ }
26762+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
26763+ if (!err)
26764+ opt->type = token;
26765+ break;
26766+#endif
26767+ case Opt_mod:
26768+ err = au_opts_parse_mod(&opt->mod, a->args);
26769+ if (!err)
26770+ opt->type = token;
26771+ break;
26772+#ifdef IMOD /* reserved for future use */
26773+ case Opt_imod:
26774+ u.mod->path = "(indexed)";
26775+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 26776+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26777+ break;
26778+ }
26779+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
26780+ if (!err)
26781+ opt->type = token;
26782+ break;
26783+#endif
26784+ case Opt_xino:
26785+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
26786+ if (!err)
26787+ opt->type = token;
26788+ break;
26789+
26790+ case Opt_trunc_xino_path:
26791+ err = au_opts_parse_xino_itrunc_path
26792+ (sb, &opt->xino_itrunc, a->args);
26793+ if (!err)
26794+ opt->type = token;
26795+ break;
26796+
26797+ case Opt_itrunc_xino:
26798+ u.xino_itrunc = &opt->xino_itrunc;
26799+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 26800+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26801+ break;
26802+ }
26803+ u.xino_itrunc->bindex = n;
26804+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 26805+ if (n < 0 || au_sbbot(sb) < n) {
4a4d8108 26806+ pr_err("out of bounds, %d\n", n);
1facf9fc 26807+ aufs_read_unlock(root, !AuLock_IR);
26808+ break;
26809+ }
26810+ aufs_read_unlock(root, !AuLock_IR);
26811+ err = 0;
26812+ opt->type = token;
26813+ break;
26814+
26815+ case Opt_dirwh:
26816+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
26817+ break;
26818+ err = 0;
26819+ opt->type = token;
26820+ break;
26821+
26822+ case Opt_rdcache:
027c5e7a
AM
26823+ if (unlikely(match_int(&a->args[0], &n))) {
26824+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26825+ break;
027c5e7a
AM
26826+ }
26827+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
26828+ pr_err("rdcache must be smaller than %d\n",
26829+ AUFS_RDCACHE_MAX);
26830+ break;
26831+ }
26832+ opt->rdcache = n;
1facf9fc 26833+ err = 0;
26834+ opt->type = token;
26835+ break;
26836+ case Opt_rdblk:
26837+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 26838+ || n < 0
1facf9fc 26839+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 26840+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26841+ break;
26842+ }
1308ab2a 26843+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
26844+ pr_err("rdblk must be larger than %d\n",
26845+ NAME_MAX);
1facf9fc 26846+ break;
26847+ }
26848+ opt->rdblk = n;
26849+ err = 0;
26850+ opt->type = token;
26851+ break;
26852+ case Opt_rdhash:
26853+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 26854+ || n < 0
1facf9fc 26855+ || n * sizeof(struct hlist_head)
26856+ > KMALLOC_MAX_SIZE)) {
4a4d8108 26857+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 26858+ break;
26859+ }
26860+ opt->rdhash = n;
26861+ err = 0;
26862+ opt->type = token;
26863+ break;
26864+
26865+ case Opt_trunc_xino:
26866+ case Opt_notrunc_xino:
26867+ case Opt_noxino:
26868+ case Opt_trunc_xib:
26869+ case Opt_notrunc_xib:
dece6358
AM
26870+ case Opt_shwh:
26871+ case Opt_noshwh:
076b876e
AM
26872+ case Opt_dirperm1:
26873+ case Opt_nodirperm1:
1facf9fc 26874+ case Opt_plink:
26875+ case Opt_noplink:
26876+ case Opt_list_plink:
4a4d8108
AM
26877+ case Opt_dio:
26878+ case Opt_nodio:
1facf9fc 26879+ case Opt_diropq_a:
26880+ case Opt_diropq_w:
26881+ case Opt_warn_perm:
26882+ case Opt_nowarn_perm:
1facf9fc 26883+ case Opt_verbose:
26884+ case Opt_noverbose:
26885+ case Opt_sum:
26886+ case Opt_nosum:
26887+ case Opt_wsum:
dece6358
AM
26888+ case Opt_rdblk_def:
26889+ case Opt_rdhash_def:
8b6a4947
AM
26890+ case Opt_dirren:
26891+ case Opt_nodirren:
c1595e42
JR
26892+ case Opt_acl:
26893+ case Opt_noacl:
1facf9fc 26894+ err = 0;
26895+ opt->type = token;
26896+ break;
26897+
26898+ case Opt_udba:
26899+ opt->udba = udba_val(a->args[0].from);
26900+ if (opt->udba >= 0) {
26901+ err = 0;
26902+ opt->type = token;
26903+ } else
4a4d8108 26904+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 26905+ break;
26906+
26907+ case Opt_wbr_create:
26908+ u.create = &opt->wbr_create;
26909+ u.create->wbr_create
26910+ = au_wbr_create_val(a->args[0].from, u.create);
26911+ if (u.create->wbr_create >= 0) {
26912+ err = 0;
26913+ opt->type = token;
26914+ } else
4a4d8108 26915+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 26916+ break;
26917+ case Opt_wbr_copyup:
26918+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
26919+ if (opt->wbr_copyup >= 0) {
26920+ err = 0;
26921+ opt->type = token;
26922+ } else
4a4d8108 26923+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 26924+ break;
26925+
076b876e
AM
26926+ case Opt_fhsm_sec:
26927+ if (unlikely(match_int(&a->args[0], &n)
26928+ || n < 0)) {
26929+ pr_err("bad integer in %s\n", opt_str);
26930+ break;
26931+ }
26932+ if (sysaufs_brs) {
26933+ opt->fhsm_second = n;
26934+ opt->type = token;
26935+ } else
26936+ pr_warn("ignored %s\n", opt_str);
26937+ err = 0;
26938+ break;
26939+
1facf9fc 26940+ case Opt_ignore:
0c3ec466 26941+ pr_warn("ignored %s\n", opt_str);
1facf9fc 26942+ /*FALLTHROUGH*/
26943+ case Opt_ignore_silent:
26944+ skipped = 1;
26945+ err = 0;
26946+ break;
26947+ case Opt_err:
4a4d8108 26948+ pr_err("unknown option %s\n", opt_str);
1facf9fc 26949+ break;
26950+ }
26951+
26952+ if (!err && !skipped) {
26953+ if (unlikely(++opt > opt_tail)) {
26954+ err = -E2BIG;
26955+ opt--;
26956+ opt->type = Opt_tail;
26957+ break;
26958+ }
26959+ opt->type = Opt_tail;
26960+ }
26961+ }
26962+
1c60b727 26963+ kfree(a);
1facf9fc 26964+ dump_opts(opts);
26965+ if (unlikely(err))
26966+ au_opts_free(opts);
26967+
4f0767ce 26968+out:
1facf9fc 26969+ return err;
26970+}
26971+
26972+static int au_opt_wbr_create(struct super_block *sb,
26973+ struct au_opt_wbr_create *create)
26974+{
26975+ int err;
26976+ struct au_sbinfo *sbinfo;
26977+
dece6358
AM
26978+ SiMustWriteLock(sb);
26979+
1facf9fc 26980+ err = 1; /* handled */
26981+ sbinfo = au_sbi(sb);
26982+ if (sbinfo->si_wbr_create_ops->fin) {
26983+ err = sbinfo->si_wbr_create_ops->fin(sb);
26984+ if (!err)
26985+ err = 1;
26986+ }
26987+
26988+ sbinfo->si_wbr_create = create->wbr_create;
26989+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
26990+ switch (create->wbr_create) {
26991+ case AuWbrCreate_MFSRRV:
26992+ case AuWbrCreate_MFSRR:
f2c43d5f
AM
26993+ case AuWbrCreate_TDMFS:
26994+ case AuWbrCreate_TDMFSV:
392086de
AM
26995+ case AuWbrCreate_PMFSRR:
26996+ case AuWbrCreate_PMFSRRV:
1facf9fc 26997+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
26998+ /*FALLTHROUGH*/
26999+ case AuWbrCreate_MFS:
27000+ case AuWbrCreate_MFSV:
27001+ case AuWbrCreate_PMFS:
27002+ case AuWbrCreate_PMFSV:
e49829fe
JR
27003+ sbinfo->si_wbr_mfs.mfs_expire
27004+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 27005+ break;
27006+ }
27007+
27008+ if (sbinfo->si_wbr_create_ops->init)
27009+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
27010+
27011+ return err;
27012+}
27013+
27014+/*
27015+ * returns,
27016+ * plus: processed without an error
27017+ * zero: unprocessed
27018+ */
27019+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
27020+ struct au_opts *opts)
27021+{
27022+ int err;
27023+ struct au_sbinfo *sbinfo;
27024+
dece6358
AM
27025+ SiMustWriteLock(sb);
27026+
1facf9fc 27027+ err = 1; /* handled */
27028+ sbinfo = au_sbi(sb);
27029+ switch (opt->type) {
27030+ case Opt_udba:
27031+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
27032+ sbinfo->si_mntflags |= opt->udba;
27033+ opts->given_udba |= opt->udba;
27034+ break;
27035+
27036+ case Opt_plink:
27037+ au_opt_set(sbinfo->si_mntflags, PLINK);
27038+ break;
27039+ case Opt_noplink:
27040+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 27041+ au_plink_put(sb, /*verbose*/1);
1facf9fc 27042+ au_opt_clr(sbinfo->si_mntflags, PLINK);
27043+ break;
27044+ case Opt_list_plink:
27045+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
27046+ au_plink_list(sb);
27047+ break;
27048+
4a4d8108
AM
27049+ case Opt_dio:
27050+ au_opt_set(sbinfo->si_mntflags, DIO);
27051+ au_fset_opts(opts->flags, REFRESH_DYAOP);
27052+ break;
27053+ case Opt_nodio:
27054+ au_opt_clr(sbinfo->si_mntflags, DIO);
27055+ au_fset_opts(opts->flags, REFRESH_DYAOP);
27056+ break;
27057+
076b876e
AM
27058+ case Opt_fhsm_sec:
27059+ au_fhsm_set(sbinfo, opt->fhsm_second);
27060+ break;
27061+
1facf9fc 27062+ case Opt_diropq_a:
27063+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
27064+ break;
27065+ case Opt_diropq_w:
27066+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
27067+ break;
27068+
27069+ case Opt_warn_perm:
27070+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
27071+ break;
27072+ case Opt_nowarn_perm:
27073+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
27074+ break;
27075+
1facf9fc 27076+ case Opt_verbose:
27077+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
27078+ break;
27079+ case Opt_noverbose:
27080+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
27081+ break;
27082+
27083+ case Opt_sum:
27084+ au_opt_set(sbinfo->si_mntflags, SUM);
27085+ break;
27086+ case Opt_wsum:
27087+ au_opt_clr(sbinfo->si_mntflags, SUM);
27088+ au_opt_set(sbinfo->si_mntflags, SUM_W);
27089+ case Opt_nosum:
27090+ au_opt_clr(sbinfo->si_mntflags, SUM);
27091+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
27092+ break;
27093+
27094+ case Opt_wbr_create:
27095+ err = au_opt_wbr_create(sb, &opt->wbr_create);
27096+ break;
27097+ case Opt_wbr_copyup:
27098+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
27099+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
27100+ break;
27101+
27102+ case Opt_dirwh:
27103+ sbinfo->si_dirwh = opt->dirwh;
27104+ break;
27105+
27106+ case Opt_rdcache:
e49829fe
JR
27107+ sbinfo->si_rdcache
27108+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 27109+ break;
27110+ case Opt_rdblk:
27111+ sbinfo->si_rdblk = opt->rdblk;
27112+ break;
dece6358
AM
27113+ case Opt_rdblk_def:
27114+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
27115+ break;
1facf9fc 27116+ case Opt_rdhash:
27117+ sbinfo->si_rdhash = opt->rdhash;
27118+ break;
dece6358
AM
27119+ case Opt_rdhash_def:
27120+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
27121+ break;
27122+
27123+ case Opt_shwh:
27124+ au_opt_set(sbinfo->si_mntflags, SHWH);
27125+ break;
27126+ case Opt_noshwh:
27127+ au_opt_clr(sbinfo->si_mntflags, SHWH);
27128+ break;
1facf9fc 27129+
076b876e
AM
27130+ case Opt_dirperm1:
27131+ au_opt_set(sbinfo->si_mntflags, DIRPERM1);
27132+ break;
27133+ case Opt_nodirperm1:
27134+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
27135+ break;
27136+
1facf9fc 27137+ case Opt_trunc_xino:
27138+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
27139+ break;
27140+ case Opt_notrunc_xino:
27141+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
27142+ break;
27143+
27144+ case Opt_trunc_xino_path:
27145+ case Opt_itrunc_xino:
acd2b654
AM
27146+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex,
27147+ /*idx_begin*/0);
1facf9fc 27148+ if (!err)
27149+ err = 1;
27150+ break;
27151+
27152+ case Opt_trunc_xib:
27153+ au_fset_opts(opts->flags, TRUNC_XIB);
27154+ break;
27155+ case Opt_notrunc_xib:
27156+ au_fclr_opts(opts->flags, TRUNC_XIB);
27157+ break;
27158+
8b6a4947
AM
27159+ case Opt_dirren:
27160+ err = 1;
27161+ if (!au_opt_test(sbinfo->si_mntflags, DIRREN)) {
27162+ err = au_dr_opt_set(sb);
27163+ if (!err)
27164+ err = 1;
27165+ }
27166+ if (err == 1)
27167+ au_opt_set(sbinfo->si_mntflags, DIRREN);
27168+ break;
27169+ case Opt_nodirren:
27170+ err = 1;
27171+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) {
27172+ err = au_dr_opt_clr(sb, au_ftest_opts(opts->flags,
27173+ DR_FLUSHED));
27174+ if (!err)
27175+ err = 1;
27176+ }
27177+ if (err == 1)
27178+ au_opt_clr(sbinfo->si_mntflags, DIRREN);
27179+ break;
27180+
c1595e42 27181+ case Opt_acl:
2121bcd9 27182+ sb->s_flags |= SB_POSIXACL;
c1595e42
JR
27183+ break;
27184+ case Opt_noacl:
2121bcd9 27185+ sb->s_flags &= ~SB_POSIXACL;
c1595e42
JR
27186+ break;
27187+
1facf9fc 27188+ default:
27189+ err = 0;
27190+ break;
27191+ }
27192+
27193+ return err;
27194+}
27195+
27196+/*
27197+ * returns tri-state.
27198+ * plus: processed without an error
27199+ * zero: unprocessed
27200+ * minus: error
27201+ */
27202+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
27203+ struct au_opts *opts)
27204+{
27205+ int err, do_refresh;
27206+
27207+ err = 0;
27208+ switch (opt->type) {
27209+ case Opt_append:
5afbbe0d 27210+ opt->add.bindex = au_sbbot(sb) + 1;
1facf9fc 27211+ if (opt->add.bindex < 0)
27212+ opt->add.bindex = 0;
27213+ goto add;
27214+ case Opt_prepend:
27215+ opt->add.bindex = 0;
f6b6e03d 27216+ add: /* indented label */
1facf9fc 27217+ case Opt_add:
27218+ err = au_br_add(sb, &opt->add,
27219+ au_ftest_opts(opts->flags, REMOUNT));
27220+ if (!err) {
27221+ err = 1;
027c5e7a 27222+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 27223+ }
27224+ break;
27225+
27226+ case Opt_del:
27227+ case Opt_idel:
27228+ err = au_br_del(sb, &opt->del,
27229+ au_ftest_opts(opts->flags, REMOUNT));
27230+ if (!err) {
27231+ err = 1;
27232+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 27233+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 27234+ }
27235+ break;
27236+
27237+ case Opt_mod:
27238+ case Opt_imod:
27239+ err = au_br_mod(sb, &opt->mod,
27240+ au_ftest_opts(opts->flags, REMOUNT),
27241+ &do_refresh);
27242+ if (!err) {
27243+ err = 1;
027c5e7a
AM
27244+ if (do_refresh)
27245+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 27246+ }
27247+ break;
27248+ }
1facf9fc 27249+ return err;
27250+}
27251+
27252+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
27253+ struct au_opt_xino **opt_xino,
27254+ struct au_opts *opts)
27255+{
27256+ int err;
1facf9fc 27257+
27258+ err = 0;
27259+ switch (opt->type) {
27260+ case Opt_xino:
062440b3
AM
27261+ err = au_xino_set(sb, &opt->xino,
27262+ !!au_ftest_opts(opts->flags, REMOUNT));
27263+ if (unlikely(err))
27264+ break;
27265+
27266+ *opt_xino = &opt->xino;
1facf9fc 27267+ break;
27268+
27269+ case Opt_noxino:
27270+ au_xino_clr(sb);
1facf9fc 27271+ *opt_xino = (void *)-1;
27272+ break;
27273+ }
27274+
27275+ return err;
27276+}
27277+
27278+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
27279+ unsigned int pending)
27280+{
076b876e 27281+ int err, fhsm;
5afbbe0d 27282+ aufs_bindex_t bindex, bbot;
79b8bda9 27283+ unsigned char do_plink, skip, do_free, can_no_dreval;
1facf9fc 27284+ struct au_branch *br;
27285+ struct au_wbr *wbr;
79b8bda9 27286+ struct dentry *root, *dentry;
1facf9fc 27287+ struct inode *dir, *h_dir;
27288+ struct au_sbinfo *sbinfo;
27289+ struct au_hinode *hdir;
27290+
dece6358
AM
27291+ SiMustAnyLock(sb);
27292+
1facf9fc 27293+ sbinfo = au_sbi(sb);
27294+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
27295+
2121bcd9 27296+ if (!(sb_flags & SB_RDONLY)) {
dece6358 27297+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 27298+ pr_warn("first branch should be rw\n");
dece6358 27299+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
febd17d6 27300+ pr_warn_once("shwh should be used with ro\n");
dece6358 27301+ }
1facf9fc 27302+
4a4d8108 27303+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 27304+ && !au_opt_test(sbinfo->si_mntflags, XINO))
febd17d6 27305+ pr_warn_once("udba=*notify requires xino\n");
1facf9fc 27306+
076b876e 27307+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
febd17d6
JR
27308+ pr_warn_once("dirperm1 breaks the protection"
27309+ " by the permission bits on the lower branch\n");
076b876e 27310+
1facf9fc 27311+ err = 0;
076b876e 27312+ fhsm = 0;
1facf9fc 27313+ root = sb->s_root;
5527c038 27314+ dir = d_inode(root);
1facf9fc 27315+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
79b8bda9
AM
27316+ can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending),
27317+ UDBA_NONE);
5afbbe0d
AM
27318+ bbot = au_sbbot(sb);
27319+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
1facf9fc 27320+ skip = 0;
27321+ h_dir = au_h_iptr(dir, bindex);
27322+ br = au_sbr(sb, bindex);
1facf9fc 27323+
c1595e42
JR
27324+ if ((br->br_perm & AuBrAttr_ICEX)
27325+ && !h_dir->i_op->listxattr)
27326+ br->br_perm &= ~AuBrAttr_ICEX;
27327+#if 0
27328+ if ((br->br_perm & AuBrAttr_ICEX_SEC)
2121bcd9 27329+ && (au_br_sb(br)->s_flags & SB_NOSEC))
c1595e42
JR
27330+ br->br_perm &= ~AuBrAttr_ICEX_SEC;
27331+#endif
27332+
27333+ do_free = 0;
1facf9fc 27334+ wbr = br->br_wbr;
27335+ if (wbr)
27336+ wbr_wh_read_lock(wbr);
27337+
1e00d052 27338+ if (!au_br_writable(br->br_perm)) {
1facf9fc 27339+ do_free = !!wbr;
27340+ skip = (!wbr
27341+ || (!wbr->wbr_whbase
27342+ && !wbr->wbr_plink
27343+ && !wbr->wbr_orph));
1e00d052 27344+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 27345+ /* skip = (!br->br_whbase && !br->br_orph); */
27346+ skip = (!wbr || !wbr->wbr_whbase);
27347+ if (skip && wbr) {
27348+ if (do_plink)
27349+ skip = !!wbr->wbr_plink;
27350+ else
27351+ skip = !wbr->wbr_plink;
27352+ }
1e00d052 27353+ } else {
1facf9fc 27354+ /* skip = (br->br_whbase && br->br_ohph); */
27355+ skip = (wbr && wbr->wbr_whbase);
27356+ if (skip) {
27357+ if (do_plink)
27358+ skip = !!wbr->wbr_plink;
27359+ else
27360+ skip = !wbr->wbr_plink;
27361+ }
1facf9fc 27362+ }
27363+ if (wbr)
27364+ wbr_wh_read_unlock(wbr);
27365+
79b8bda9
AM
27366+ if (can_no_dreval) {
27367+ dentry = br->br_path.dentry;
27368+ spin_lock(&dentry->d_lock);
27369+ if (dentry->d_flags &
27370+ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE))
27371+ can_no_dreval = 0;
27372+ spin_unlock(&dentry->d_lock);
27373+ }
27374+
076b876e
AM
27375+ if (au_br_fhsm(br->br_perm)) {
27376+ fhsm++;
27377+ AuDebugOn(!br->br_fhsm);
27378+ }
27379+
1facf9fc 27380+ if (skip)
27381+ continue;
27382+
27383+ hdir = au_hi(dir, bindex);
5afbbe0d 27384+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 27385+ if (wbr)
27386+ wbr_wh_write_lock(wbr);
86dc4139 27387+ err = au_wh_init(br, sb);
1facf9fc 27388+ if (wbr)
27389+ wbr_wh_write_unlock(wbr);
5afbbe0d 27390+ au_hn_inode_unlock(hdir);
1facf9fc 27391+
27392+ if (!err && do_free) {
1c60b727 27393+ kfree(wbr);
1facf9fc 27394+ br->br_wbr = NULL;
27395+ }
27396+ }
27397+
79b8bda9
AM
27398+ if (can_no_dreval)
27399+ au_fset_si(sbinfo, NO_DREVAL);
27400+ else
27401+ au_fclr_si(sbinfo, NO_DREVAL);
27402+
c1595e42 27403+ if (fhsm >= 2) {
076b876e 27404+ au_fset_si(sbinfo, FHSM);
5afbbe0d 27405+ for (bindex = bbot; bindex >= 0; bindex--) {
c1595e42
JR
27406+ br = au_sbr(sb, bindex);
27407+ if (au_br_fhsm(br->br_perm)) {
27408+ au_fhsm_set_bottom(sb, bindex);
27409+ break;
27410+ }
27411+ }
27412+ } else {
076b876e 27413+ au_fclr_si(sbinfo, FHSM);
c1595e42
JR
27414+ au_fhsm_set_bottom(sb, -1);
27415+ }
076b876e 27416+
1facf9fc 27417+ return err;
27418+}
27419+
27420+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
27421+{
27422+ int err;
27423+ unsigned int tmp;
5afbbe0d 27424+ aufs_bindex_t bindex, bbot;
1facf9fc 27425+ struct au_opt *opt;
27426+ struct au_opt_xino *opt_xino, xino;
27427+ struct au_sbinfo *sbinfo;
027c5e7a 27428+ struct au_branch *br;
076b876e 27429+ struct inode *dir;
1facf9fc 27430+
dece6358
AM
27431+ SiMustWriteLock(sb);
27432+
1facf9fc 27433+ err = 0;
27434+ opt_xino = NULL;
27435+ opt = opts->opt;
27436+ while (err >= 0 && opt->type != Opt_tail)
27437+ err = au_opt_simple(sb, opt++, opts);
27438+ if (err > 0)
27439+ err = 0;
27440+ else if (unlikely(err < 0))
27441+ goto out;
27442+
27443+ /* disable xino and udba temporary */
27444+ sbinfo = au_sbi(sb);
27445+ tmp = sbinfo->si_mntflags;
27446+ au_opt_clr(sbinfo->si_mntflags, XINO);
27447+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
27448+
27449+ opt = opts->opt;
27450+ while (err >= 0 && opt->type != Opt_tail)
27451+ err = au_opt_br(sb, opt++, opts);
27452+ if (err > 0)
27453+ err = 0;
27454+ else if (unlikely(err < 0))
27455+ goto out;
27456+
5afbbe0d
AM
27457+ bbot = au_sbbot(sb);
27458+ if (unlikely(bbot < 0)) {
1facf9fc 27459+ err = -EINVAL;
4a4d8108 27460+ pr_err("no branches\n");
1facf9fc 27461+ goto out;
27462+ }
27463+
27464+ if (au_opt_test(tmp, XINO))
27465+ au_opt_set(sbinfo->si_mntflags, XINO);
27466+ opt = opts->opt;
27467+ while (!err && opt->type != Opt_tail)
27468+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
27469+ if (unlikely(err))
27470+ goto out;
27471+
27472+ err = au_opts_verify(sb, sb->s_flags, tmp);
27473+ if (unlikely(err))
27474+ goto out;
27475+
27476+ /* restore xino */
27477+ if (au_opt_test(tmp, XINO) && !opt_xino) {
27478+ xino.file = au_xino_def(sb);
27479+ err = PTR_ERR(xino.file);
27480+ if (IS_ERR(xino.file))
27481+ goto out;
27482+
27483+ err = au_xino_set(sb, &xino, /*remount*/0);
27484+ fput(xino.file);
27485+ if (unlikely(err))
27486+ goto out;
27487+ }
27488+
27489+ /* restore udba */
027c5e7a 27490+ tmp &= AuOptMask_UDBA;
1facf9fc 27491+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a 27492+ sbinfo->si_mntflags |= tmp;
5afbbe0d
AM
27493+ bbot = au_sbbot(sb);
27494+ for (bindex = 0; bindex <= bbot; bindex++) {
027c5e7a
AM
27495+ br = au_sbr(sb, bindex);
27496+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
27497+ if (unlikely(err))
27498+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
27499+ bindex, err);
27500+ /* go on even if err */
27501+ }
4a4d8108 27502+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
5527c038 27503+ dir = d_inode(sb->s_root);
4a4d8108 27504+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 27505+ }
27506+
4f0767ce 27507+out:
1facf9fc 27508+ return err;
27509+}
27510+
27511+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
27512+{
27513+ int err, rerr;
79b8bda9 27514+ unsigned char no_dreval;
1facf9fc 27515+ struct inode *dir;
27516+ struct au_opt_xino *opt_xino;
27517+ struct au_opt *opt;
27518+ struct au_sbinfo *sbinfo;
27519+
dece6358
AM
27520+ SiMustWriteLock(sb);
27521+
8b6a4947
AM
27522+ err = au_dr_opt_flush(sb);
27523+ if (unlikely(err))
27524+ goto out;
27525+ au_fset_opts(opts->flags, DR_FLUSHED);
27526+
5527c038 27527+ dir = d_inode(sb->s_root);
1facf9fc 27528+ sbinfo = au_sbi(sb);
1facf9fc 27529+ opt_xino = NULL;
27530+ opt = opts->opt;
27531+ while (err >= 0 && opt->type != Opt_tail) {
27532+ err = au_opt_simple(sb, opt, opts);
27533+ if (!err)
27534+ err = au_opt_br(sb, opt, opts);
27535+ if (!err)
27536+ err = au_opt_xino(sb, opt, &opt_xino, opts);
27537+ opt++;
27538+ }
27539+ if (err > 0)
27540+ err = 0;
27541+ AuTraceErr(err);
27542+ /* go on even err */
27543+
79b8bda9 27544+ no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
1facf9fc 27545+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
27546+ if (unlikely(rerr && !err))
27547+ err = rerr;
27548+
79b8bda9 27549+ if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
b95c5147 27550+ au_fset_opts(opts->flags, REFRESH_IDOP);
79b8bda9 27551+
1facf9fc 27552+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
27553+ rerr = au_xib_trunc(sb);
27554+ if (unlikely(rerr && !err))
27555+ err = rerr;
27556+ }
27557+
27558+ /* will be handled by the caller */
027c5e7a 27559+ if (!au_ftest_opts(opts->flags, REFRESH)
79b8bda9
AM
27560+ && (opts->given_udba
27561+ || au_opt_test(sbinfo->si_mntflags, XINO)
b95c5147 27562+ || au_ftest_opts(opts->flags, REFRESH_IDOP)
79b8bda9 27563+ ))
027c5e7a 27564+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 27565+
27566+ AuDbg("status 0x%x\n", opts->flags);
8b6a4947
AM
27567+
27568+out:
1facf9fc 27569+ return err;
27570+}
27571+
27572+/* ---------------------------------------------------------------------- */
27573+
27574+unsigned int au_opt_udba(struct super_block *sb)
27575+{
27576+ return au_mntflags(sb) & AuOptMask_UDBA;
27577+}
7f207e10
AM
27578diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
27579--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 27580+++ linux/fs/aufs/opts.h 2018-08-12 23:43:05.460124736 +0200
062440b3
AM
27581@@ -0,0 +1,225 @@
27582+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 27583+/*
b00004a5 27584+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 27585+ *
27586+ * This program, aufs is free software; you can redistribute it and/or modify
27587+ * it under the terms of the GNU General Public License as published by
27588+ * the Free Software Foundation; either version 2 of the License, or
27589+ * (at your option) any later version.
dece6358
AM
27590+ *
27591+ * This program is distributed in the hope that it will be useful,
27592+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27593+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27594+ * GNU General Public License for more details.
27595+ *
27596+ * You should have received a copy of the GNU General Public License
523b37e3 27597+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27598+ */
27599+
27600+/*
27601+ * mount options/flags
27602+ */
27603+
27604+#ifndef __AUFS_OPTS_H__
27605+#define __AUFS_OPTS_H__
27606+
27607+#ifdef __KERNEL__
27608+
dece6358 27609+#include <linux/path.h>
1facf9fc 27610+
dece6358 27611+struct file;
dece6358 27612+
1facf9fc 27613+/* ---------------------------------------------------------------------- */
27614+
27615+/* mount flags */
27616+#define AuOpt_XINO 1 /* external inode number bitmap
27617+ and translation table */
27618+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
27619+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
27620+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 27621+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
27622+#define AuOpt_SHWH (1 << 5) /* show whiteout */
27623+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
076b876e
AM
27624+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
27625+ bits */
dece6358
AM
27626+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
27627+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
27628+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
27629+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
27630+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 27631+#define AuOpt_DIO (1 << 14) /* direct io */
8b6a4947 27632+#define AuOpt_DIRREN (1 << 15) /* directory rename */
1facf9fc 27633+
4a4d8108
AM
27634+#ifndef CONFIG_AUFS_HNOTIFY
27635+#undef AuOpt_UDBA_HNOTIFY
27636+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 27637+#endif
8b6a4947
AM
27638+#ifndef CONFIG_AUFS_DIRREN
27639+#undef AuOpt_DIRREN
27640+#define AuOpt_DIRREN 0
27641+#endif
dece6358
AM
27642+#ifndef CONFIG_AUFS_SHWH
27643+#undef AuOpt_SHWH
27644+#define AuOpt_SHWH 0
27645+#endif
1facf9fc 27646+
27647+#define AuOpt_Def (AuOpt_XINO \
27648+ | AuOpt_UDBA_REVAL \
27649+ | AuOpt_PLINK \
27650+ /* | AuOpt_DIRPERM1 */ \
27651+ | AuOpt_WARN_PERM)
27652+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
27653+ | AuOpt_UDBA_REVAL \
4a4d8108 27654+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 27655+
27656+#define au_opt_test(flags, name) (flags & AuOpt_##name)
27657+#define au_opt_set(flags, name) do { \
27658+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
27659+ ((flags) |= AuOpt_##name); \
27660+} while (0)
27661+#define au_opt_set_udba(flags, name) do { \
27662+ (flags) &= ~AuOptMask_UDBA; \
27663+ ((flags) |= AuOpt_##name); \
27664+} while (0)
7f207e10
AM
27665+#define au_opt_clr(flags, name) do { \
27666+ ((flags) &= ~AuOpt_##name); \
27667+} while (0)
1facf9fc 27668+
e49829fe
JR
27669+static inline unsigned int au_opts_plink(unsigned int mntflags)
27670+{
27671+#ifdef CONFIG_PROC_FS
27672+ return mntflags;
27673+#else
27674+ return mntflags & ~AuOpt_PLINK;
27675+#endif
27676+}
27677+
1facf9fc 27678+/* ---------------------------------------------------------------------- */
27679+
27680+/* policies to select one among multiple writable branches */
27681+enum {
27682+ AuWbrCreate_TDP, /* top down parent */
27683+ AuWbrCreate_RR, /* round robin */
27684+ AuWbrCreate_MFS, /* most free space */
27685+ AuWbrCreate_MFSV, /* mfs with seconds */
27686+ AuWbrCreate_MFSRR, /* mfs then rr */
27687+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
f2c43d5f
AM
27688+ AuWbrCreate_TDMFS, /* top down regardless parent and mfs */
27689+ AuWbrCreate_TDMFSV, /* top down regardless parent and mfs */
1facf9fc 27690+ AuWbrCreate_PMFS, /* parent and mfs */
27691+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
27692+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
27693+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 27694+
27695+ AuWbrCreate_Def = AuWbrCreate_TDP
27696+};
27697+
27698+enum {
27699+ AuWbrCopyup_TDP, /* top down parent */
27700+ AuWbrCopyup_BUP, /* bottom up parent */
27701+ AuWbrCopyup_BU, /* bottom up */
27702+
27703+ AuWbrCopyup_Def = AuWbrCopyup_TDP
27704+};
27705+
27706+/* ---------------------------------------------------------------------- */
27707+
27708+struct au_opt_add {
27709+ aufs_bindex_t bindex;
27710+ char *pathname;
27711+ int perm;
27712+ struct path path;
27713+};
27714+
27715+struct au_opt_del {
27716+ char *pathname;
27717+ struct path h_path;
27718+};
27719+
27720+struct au_opt_mod {
27721+ char *path;
27722+ int perm;
27723+ struct dentry *h_root;
27724+};
27725+
27726+struct au_opt_xino {
27727+ char *path;
27728+ struct file *file;
27729+};
27730+
27731+struct au_opt_xino_itrunc {
27732+ aufs_bindex_t bindex;
27733+};
27734+
27735+struct au_opt_wbr_create {
27736+ int wbr_create;
27737+ int mfs_second;
27738+ unsigned long long mfsrr_watermark;
27739+};
27740+
27741+struct au_opt {
27742+ int type;
27743+ union {
27744+ struct au_opt_xino xino;
27745+ struct au_opt_xino_itrunc xino_itrunc;
27746+ struct au_opt_add add;
27747+ struct au_opt_del del;
27748+ struct au_opt_mod mod;
27749+ int dirwh;
27750+ int rdcache;
27751+ unsigned int rdblk;
27752+ unsigned int rdhash;
27753+ int udba;
27754+ struct au_opt_wbr_create wbr_create;
27755+ int wbr_copyup;
076b876e 27756+ unsigned int fhsm_second;
1facf9fc 27757+ };
27758+};
27759+
27760+/* opts flags */
27761+#define AuOpts_REMOUNT 1
027c5e7a
AM
27762+#define AuOpts_REFRESH (1 << 1)
27763+#define AuOpts_TRUNC_XIB (1 << 2)
27764+#define AuOpts_REFRESH_DYAOP (1 << 3)
b95c5147 27765+#define AuOpts_REFRESH_IDOP (1 << 4)
8b6a4947 27766+#define AuOpts_DR_FLUSHED (1 << 5)
1facf9fc 27767+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
27768+#define au_fset_opts(flags, name) \
27769+ do { (flags) |= AuOpts_##name; } while (0)
27770+#define au_fclr_opts(flags, name) \
27771+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 27772+
8b6a4947
AM
27773+#ifndef CONFIG_AUFS_DIRREN
27774+#undef AuOpts_DR_FLUSHED
27775+#define AuOpts_DR_FLUSHED 0
27776+#endif
27777+
1facf9fc 27778+struct au_opts {
27779+ struct au_opt *opt;
27780+ int max_opt;
27781+
27782+ unsigned int given_udba;
27783+ unsigned int flags;
27784+ unsigned long sb_flags;
27785+};
27786+
27787+/* ---------------------------------------------------------------------- */
27788+
7e9cd9fe 27789+/* opts.c */
076b876e 27790+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
1facf9fc 27791+const char *au_optstr_udba(int udba);
27792+const char *au_optstr_wbr_copyup(int wbr_copyup);
27793+const char *au_optstr_wbr_create(int wbr_create);
27794+
27795+void au_opts_free(struct au_opts *opts);
3c1bdaff 27796+struct super_block;
1facf9fc 27797+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
27798+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
27799+ unsigned int pending);
27800+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
27801+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
27802+
27803+unsigned int au_opt_udba(struct super_block *sb);
27804+
1facf9fc 27805+#endif /* __KERNEL__ */
27806+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
27807diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
27808--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 27809+++ linux/fs/aufs/plink.c 2018-10-23 12:33:35.599375796 +0200
062440b3 27810@@ -0,0 +1,516 @@
cd7a4cd9 27811+// SPDX-License-Identifier: GPL-2.0
1facf9fc 27812+/*
b00004a5 27813+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 27814+ *
27815+ * This program, aufs is free software; you can redistribute it and/or modify
27816+ * it under the terms of the GNU General Public License as published by
27817+ * the Free Software Foundation; either version 2 of the License, or
27818+ * (at your option) any later version.
dece6358
AM
27819+ *
27820+ * This program is distributed in the hope that it will be useful,
27821+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27822+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27823+ * GNU General Public License for more details.
27824+ *
27825+ * You should have received a copy of the GNU General Public License
523b37e3 27826+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27827+ */
27828+
27829+/*
27830+ * pseudo-link
27831+ */
27832+
27833+#include "aufs.h"
27834+
27835+/*
e49829fe 27836+ * the pseudo-link maintenance mode.
1facf9fc 27837+ * during a user process maintains the pseudo-links,
27838+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
27839+ *
27840+ * Flags
27841+ * NOPLM:
27842+ * For entry functions which will handle plink, and i_mutex is already held
27843+ * in VFS.
27844+ * They cannot wait and should return an error at once.
27845+ * Callers has to check the error.
27846+ * NOPLMW:
27847+ * For entry functions which will handle plink, but i_mutex is not held
27848+ * in VFS.
27849+ * They can wait the plink maintenance mode to finish.
27850+ *
27851+ * They behave like F_SETLK and F_SETLKW.
27852+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 27853+ */
e49829fe
JR
27854+
27855+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 27856+{
e49829fe
JR
27857+ int err;
27858+ pid_t pid, ppid;
f0c0a007 27859+ struct task_struct *parent, *prev;
e49829fe 27860+ struct au_sbinfo *sbi;
dece6358
AM
27861+
27862+ SiMustAnyLock(sb);
27863+
e49829fe
JR
27864+ err = 0;
27865+ if (!au_opt_test(au_mntflags(sb), PLINK))
27866+ goto out;
27867+
27868+ sbi = au_sbi(sb);
27869+ pid = sbi->si_plink_maint_pid;
27870+ if (!pid || pid == current->pid)
27871+ goto out;
27872+
27873+ /* todo: it highly depends upon /sbin/mount.aufs */
f0c0a007
AM
27874+ prev = NULL;
27875+ parent = current;
27876+ ppid = 0;
e49829fe 27877+ rcu_read_lock();
f0c0a007
AM
27878+ while (1) {
27879+ parent = rcu_dereference(parent->real_parent);
27880+ if (parent == prev)
27881+ break;
27882+ ppid = task_pid_vnr(parent);
27883+ if (pid == ppid) {
27884+ rcu_read_unlock();
27885+ goto out;
27886+ }
27887+ prev = parent;
27888+ }
e49829fe 27889+ rcu_read_unlock();
e49829fe
JR
27890+
27891+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
27892+ /* if there is no i_mutex lock in VFS, we don't need to wait */
27893+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
27894+ while (sbi->si_plink_maint_pid) {
27895+ si_read_unlock(sb);
27896+ /* gave up wake_up_bit() */
27897+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
27898+
27899+ if (au_ftest_lock(flags, FLUSH))
27900+ au_nwt_flush(&sbi->si_nowait);
27901+ si_noflush_read_lock(sb);
27902+ }
27903+ } else if (au_ftest_lock(flags, NOPLM)) {
27904+ AuDbg("ppid %d, pid %d\n", ppid, pid);
27905+ err = -EAGAIN;
27906+ }
27907+
27908+out:
27909+ return err;
4a4d8108
AM
27910+}
27911+
e49829fe 27912+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 27913+{
4a4d8108 27914+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 27915+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 27916+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 27917+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
27918+}
27919+
e49829fe 27920+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
27921+{
27922+ int err;
4a4d8108
AM
27923+ struct au_sbinfo *sbinfo;
27924+
27925+ err = 0;
4a4d8108
AM
27926+ sbinfo = au_sbi(sb);
27927+ /* make sure i am the only one in this fs */
e49829fe
JR
27928+ si_write_lock(sb, AuLock_FLUSH);
27929+ if (au_opt_test(au_mntflags(sb), PLINK)) {
27930+ spin_lock(&sbinfo->si_plink_maint_lock);
27931+ if (!sbinfo->si_plink_maint_pid)
27932+ sbinfo->si_plink_maint_pid = current->pid;
27933+ else
27934+ err = -EBUSY;
27935+ spin_unlock(&sbinfo->si_plink_maint_lock);
27936+ }
4a4d8108
AM
27937+ si_write_unlock(sb);
27938+
27939+ return err;
1facf9fc 27940+}
27941+
27942+/* ---------------------------------------------------------------------- */
27943+
1facf9fc 27944+#ifdef CONFIG_AUFS_DEBUG
27945+void au_plink_list(struct super_block *sb)
27946+{
86dc4139 27947+ int i;
1facf9fc 27948+ struct au_sbinfo *sbinfo;
8b6a4947
AM
27949+ struct hlist_bl_head *hbl;
27950+ struct hlist_bl_node *pos;
5afbbe0d 27951+ struct au_icntnr *icntnr;
1facf9fc 27952+
dece6358
AM
27953+ SiMustAnyLock(sb);
27954+
1facf9fc 27955+ sbinfo = au_sbi(sb);
27956+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 27957+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 27958+
86dc4139 27959+ for (i = 0; i < AuPlink_NHASH; i++) {
8b6a4947
AM
27960+ hbl = sbinfo->si_plink + i;
27961+ hlist_bl_lock(hbl);
27962+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink)
5afbbe0d 27963+ AuDbg("%lu\n", icntnr->vfs_inode.i_ino);
8b6a4947 27964+ hlist_bl_unlock(hbl);
86dc4139 27965+ }
1facf9fc 27966+}
27967+#endif
27968+
27969+/* is the inode pseudo-linked? */
27970+int au_plink_test(struct inode *inode)
27971+{
86dc4139 27972+ int found, i;
1facf9fc 27973+ struct au_sbinfo *sbinfo;
8b6a4947
AM
27974+ struct hlist_bl_head *hbl;
27975+ struct hlist_bl_node *pos;
5afbbe0d 27976+ struct au_icntnr *icntnr;
1facf9fc 27977+
27978+ sbinfo = au_sbi(inode->i_sb);
dece6358 27979+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 27980+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 27981+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 27982+
27983+ found = 0;
86dc4139 27984+ i = au_plink_hash(inode->i_ino);
8b6a4947
AM
27985+ hbl = sbinfo->si_plink + i;
27986+ hlist_bl_lock(hbl);
27987+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink)
5afbbe0d 27988+ if (&icntnr->vfs_inode == inode) {
1facf9fc 27989+ found = 1;
27990+ break;
27991+ }
8b6a4947 27992+ hlist_bl_unlock(hbl);
1facf9fc 27993+ return found;
27994+}
27995+
27996+/* ---------------------------------------------------------------------- */
27997+
27998+/*
27999+ * generate a name for plink.
28000+ * the file will be stored under AUFS_WH_PLINKDIR.
28001+ */
28002+/* 20 is max digits length of ulong 64 */
28003+#define PLINK_NAME_LEN ((20 + 1) * 2)
28004+
28005+static int plink_name(char *name, int len, struct inode *inode,
28006+ aufs_bindex_t bindex)
28007+{
28008+ int rlen;
28009+ struct inode *h_inode;
28010+
28011+ h_inode = au_h_iptr(inode, bindex);
28012+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
28013+ return rlen;
28014+}
28015+
7f207e10
AM
28016+struct au_do_plink_lkup_args {
28017+ struct dentry **errp;
28018+ struct qstr *tgtname;
28019+ struct dentry *h_parent;
28020+ struct au_branch *br;
28021+};
28022+
28023+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
28024+ struct dentry *h_parent,
28025+ struct au_branch *br)
28026+{
28027+ struct dentry *h_dentry;
febd17d6 28028+ struct inode *h_inode;
7f207e10 28029+
febd17d6 28030+ h_inode = d_inode(h_parent);
be118d29 28031+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2);
b4510431 28032+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
3c1bdaff 28033+ inode_unlock_shared(h_inode);
7f207e10
AM
28034+ return h_dentry;
28035+}
28036+
28037+static void au_call_do_plink_lkup(void *args)
28038+{
28039+ struct au_do_plink_lkup_args *a = args;
28040+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
28041+}
28042+
1facf9fc 28043+/* lookup the plink-ed @inode under the branch at @bindex */
28044+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
28045+{
28046+ struct dentry *h_dentry, *h_parent;
28047+ struct au_branch *br;
7f207e10 28048+ int wkq_err;
1facf9fc 28049+ char a[PLINK_NAME_LEN];
0c3ec466 28050+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 28051+
e49829fe
JR
28052+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
28053+
1facf9fc 28054+ br = au_sbr(inode->i_sb, bindex);
28055+ h_parent = br->br_wbr->wbr_plink;
1facf9fc 28056+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
28057+
2dfbb274 28058+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
28059+ struct au_do_plink_lkup_args args = {
28060+ .errp = &h_dentry,
28061+ .tgtname = &tgtname,
28062+ .h_parent = h_parent,
28063+ .br = br
28064+ };
28065+
28066+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
28067+ if (unlikely(wkq_err))
28068+ h_dentry = ERR_PTR(wkq_err);
28069+ } else
28070+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
28071+
1facf9fc 28072+ return h_dentry;
28073+}
28074+
28075+/* create a pseudo-link */
28076+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
28077+ struct dentry *h_dentry, struct au_branch *br)
28078+{
28079+ int err;
28080+ struct path h_path = {
86dc4139 28081+ .mnt = au_br_mnt(br)
1facf9fc 28082+ };
523b37e3 28083+ struct inode *h_dir, *delegated;
1facf9fc 28084+
5527c038 28085+ h_dir = d_inode(h_parent);
febd17d6 28086+ inode_lock_nested(h_dir, AuLsc_I_CHILD2);
4f0767ce 28087+again:
b4510431 28088+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 28089+ err = PTR_ERR(h_path.dentry);
28090+ if (IS_ERR(h_path.dentry))
28091+ goto out;
28092+
28093+ err = 0;
28094+ /* wh.plink dir is not monitored */
7f207e10 28095+ /* todo: is it really safe? */
5527c038
JR
28096+ if (d_is_positive(h_path.dentry)
28097+ && d_inode(h_path.dentry) != d_inode(h_dentry)) {
523b37e3
AM
28098+ delegated = NULL;
28099+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
28100+ if (unlikely(err == -EWOULDBLOCK)) {
28101+ pr_warn("cannot retry for NFSv4 delegation"
28102+ " for an internal unlink\n");
28103+ iput(delegated);
28104+ }
1facf9fc 28105+ dput(h_path.dentry);
28106+ h_path.dentry = NULL;
28107+ if (!err)
28108+ goto again;
28109+ }
5527c038 28110+ if (!err && d_is_negative(h_path.dentry)) {
523b37e3
AM
28111+ delegated = NULL;
28112+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
28113+ if (unlikely(err == -EWOULDBLOCK)) {
28114+ pr_warn("cannot retry for NFSv4 delegation"
28115+ " for an internal link\n");
28116+ iput(delegated);
28117+ }
28118+ }
1facf9fc 28119+ dput(h_path.dentry);
28120+
4f0767ce 28121+out:
febd17d6 28122+ inode_unlock(h_dir);
1facf9fc 28123+ return err;
28124+}
28125+
28126+struct do_whplink_args {
28127+ int *errp;
28128+ struct qstr *tgt;
28129+ struct dentry *h_parent;
28130+ struct dentry *h_dentry;
28131+ struct au_branch *br;
28132+};
28133+
28134+static void call_do_whplink(void *args)
28135+{
28136+ struct do_whplink_args *a = args;
28137+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
28138+}
28139+
28140+static int whplink(struct dentry *h_dentry, struct inode *inode,
28141+ aufs_bindex_t bindex, struct au_branch *br)
28142+{
28143+ int err, wkq_err;
28144+ struct au_wbr *wbr;
28145+ struct dentry *h_parent;
1facf9fc 28146+ char a[PLINK_NAME_LEN];
0c3ec466 28147+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 28148+
28149+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
28150+ h_parent = wbr->wbr_plink;
1facf9fc 28151+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
28152+
28153+ /* always superio. */
2dfbb274 28154+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 28155+ struct do_whplink_args args = {
28156+ .errp = &err,
28157+ .tgt = &tgtname,
28158+ .h_parent = h_parent,
28159+ .h_dentry = h_dentry,
28160+ .br = br
28161+ };
28162+ wkq_err = au_wkq_wait(call_do_whplink, &args);
28163+ if (unlikely(wkq_err))
28164+ err = wkq_err;
28165+ } else
28166+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 28167+
28168+ return err;
28169+}
28170+
1facf9fc 28171+/*
28172+ * create a new pseudo-link for @h_dentry on @bindex.
28173+ * the linked inode is held in aufs @inode.
28174+ */
28175+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
28176+ struct dentry *h_dentry)
28177+{
28178+ struct super_block *sb;
28179+ struct au_sbinfo *sbinfo;
8b6a4947
AM
28180+ struct hlist_bl_head *hbl;
28181+ struct hlist_bl_node *pos;
5afbbe0d 28182+ struct au_icntnr *icntnr;
86dc4139 28183+ int found, err, cnt, i;
1facf9fc 28184+
28185+ sb = inode->i_sb;
28186+ sbinfo = au_sbi(sb);
28187+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 28188+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 28189+
86dc4139 28190+ found = au_plink_test(inode);
4a4d8108 28191+ if (found)
1facf9fc 28192+ return;
4a4d8108 28193+
86dc4139 28194+ i = au_plink_hash(inode->i_ino);
8b6a4947 28195+ hbl = sbinfo->si_plink + i;
5afbbe0d 28196+ au_igrab(inode);
1facf9fc 28197+
8b6a4947
AM
28198+ hlist_bl_lock(hbl);
28199+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) {
5afbbe0d 28200+ if (&icntnr->vfs_inode == inode) {
4a4d8108
AM
28201+ found = 1;
28202+ break;
28203+ }
1facf9fc 28204+ }
5afbbe0d
AM
28205+ if (!found) {
28206+ icntnr = container_of(inode, struct au_icntnr, vfs_inode);
8b6a4947 28207+ hlist_bl_add_head(&icntnr->plink, hbl);
5afbbe0d 28208+ }
8b6a4947 28209+ hlist_bl_unlock(hbl);
4a4d8108 28210+ if (!found) {
8b6a4947 28211+ cnt = au_hbl_count(hbl);
acd2b654 28212+#define msg "unexpectedly unbalanced or too many pseudo-links"
86dc4139
AM
28213+ if (cnt > AUFS_PLINK_WARN)
28214+ AuWarn1(msg ", %d\n", cnt);
28215+#undef msg
1facf9fc 28216+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
5afbbe0d
AM
28217+ if (unlikely(err)) {
28218+ pr_warn("err %d, damaged pseudo link.\n", err);
8b6a4947 28219+ au_hbl_del(&icntnr->plink, hbl);
5afbbe0d 28220+ iput(&icntnr->vfs_inode);
4a4d8108 28221+ }
5afbbe0d
AM
28222+ } else
28223+ iput(&icntnr->vfs_inode);
1facf9fc 28224+}
28225+
28226+/* free all plinks */
e49829fe 28227+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 28228+{
86dc4139 28229+ int i, warned;
1facf9fc 28230+ struct au_sbinfo *sbinfo;
8b6a4947
AM
28231+ struct hlist_bl_head *hbl;
28232+ struct hlist_bl_node *pos, *tmp;
5afbbe0d 28233+ struct au_icntnr *icntnr;
1facf9fc 28234+
dece6358
AM
28235+ SiMustWriteLock(sb);
28236+
1facf9fc 28237+ sbinfo = au_sbi(sb);
28238+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 28239+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 28240+
1facf9fc 28241+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
28242+ warned = 0;
28243+ for (i = 0; i < AuPlink_NHASH; i++) {
8b6a4947
AM
28244+ hbl = sbinfo->si_plink + i;
28245+ if (!warned && verbose && !hlist_bl_empty(hbl)) {
86dc4139
AM
28246+ pr_warn("pseudo-link is not flushed");
28247+ warned = 1;
28248+ }
8b6a4947 28249+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink)
5afbbe0d 28250+ iput(&icntnr->vfs_inode);
8b6a4947 28251+ INIT_HLIST_BL_HEAD(hbl);
86dc4139 28252+ }
1facf9fc 28253+}
28254+
e49829fe
JR
28255+void au_plink_clean(struct super_block *sb, int verbose)
28256+{
28257+ struct dentry *root;
28258+
28259+ root = sb->s_root;
28260+ aufs_write_lock(root);
28261+ if (au_opt_test(au_mntflags(sb), PLINK))
28262+ au_plink_put(sb, verbose);
28263+ aufs_write_unlock(root);
28264+}
28265+
86dc4139
AM
28266+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
28267+{
28268+ int do_put;
5afbbe0d 28269+ aufs_bindex_t btop, bbot, bindex;
86dc4139
AM
28270+
28271+ do_put = 0;
5afbbe0d
AM
28272+ btop = au_ibtop(inode);
28273+ bbot = au_ibbot(inode);
28274+ if (btop >= 0) {
28275+ for (bindex = btop; bindex <= bbot; bindex++) {
86dc4139
AM
28276+ if (!au_h_iptr(inode, bindex)
28277+ || au_ii_br_id(inode, bindex) != br_id)
28278+ continue;
28279+ au_set_h_iptr(inode, bindex, NULL, 0);
28280+ do_put = 1;
28281+ break;
28282+ }
28283+ if (do_put)
5afbbe0d 28284+ for (bindex = btop; bindex <= bbot; bindex++)
86dc4139
AM
28285+ if (au_h_iptr(inode, bindex)) {
28286+ do_put = 0;
28287+ break;
28288+ }
28289+ } else
28290+ do_put = 1;
28291+
28292+ return do_put;
28293+}
28294+
1facf9fc 28295+/* free the plinks on a branch specified by @br_id */
28296+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
28297+{
28298+ struct au_sbinfo *sbinfo;
8b6a4947
AM
28299+ struct hlist_bl_head *hbl;
28300+ struct hlist_bl_node *pos, *tmp;
5afbbe0d 28301+ struct au_icntnr *icntnr;
1facf9fc 28302+ struct inode *inode;
86dc4139 28303+ int i, do_put;
1facf9fc 28304+
dece6358
AM
28305+ SiMustWriteLock(sb);
28306+
1facf9fc 28307+ sbinfo = au_sbi(sb);
28308+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 28309+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 28310+
8b6a4947 28311+ /* no bit_lock since sbinfo is write-locked */
86dc4139 28312+ for (i = 0; i < AuPlink_NHASH; i++) {
8b6a4947
AM
28313+ hbl = sbinfo->si_plink + i;
28314+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink) {
5afbbe0d 28315+ inode = au_igrab(&icntnr->vfs_inode);
86dc4139
AM
28316+ ii_write_lock_child(inode);
28317+ do_put = au_plink_do_half_refresh(inode, br_id);
5afbbe0d 28318+ if (do_put) {
8b6a4947 28319+ hlist_bl_del(&icntnr->plink);
5afbbe0d
AM
28320+ iput(inode);
28321+ }
86dc4139
AM
28322+ ii_write_unlock(inode);
28323+ iput(inode);
dece6358 28324+ }
dece6358
AM
28325+ }
28326+}
7f207e10
AM
28327diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
28328--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9
AM
28329+++ linux/fs/aufs/poll.c 2018-08-12 23:43:05.460124736 +0200
28330@@ -0,0 +1,51 @@
28331+// SPDX-License-Identifier: GPL-2.0
dece6358 28332+/*
b00004a5 28333+ * Copyright (C) 2005-2018 Junjiro R. Okajima
dece6358
AM
28334+ *
28335+ * This program, aufs is free software; you can redistribute it and/or modify
28336+ * it under the terms of the GNU General Public License as published by
28337+ * the Free Software Foundation; either version 2 of the License, or
28338+ * (at your option) any later version.
28339+ *
28340+ * This program is distributed in the hope that it will be useful,
28341+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28342+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28343+ * GNU General Public License for more details.
28344+ *
28345+ * You should have received a copy of the GNU General Public License
523b37e3 28346+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
28347+ */
28348+
1308ab2a 28349+/*
28350+ * poll operation
28351+ * There is only one filesystem which implements ->poll operation, currently.
28352+ */
28353+
28354+#include "aufs.h"
28355+
cd7a4cd9 28356+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt)
1308ab2a 28357+{
be118d29 28358+ __poll_t mask;
1308ab2a 28359+ struct file *h_file;
1308ab2a 28360+ struct super_block *sb;
28361+
28362+ /* We should pretend an error happened. */
be118d29 28363+ mask = EPOLLERR /* | EPOLLIN | EPOLLOUT */;
b912730e 28364+ sb = file->f_path.dentry->d_sb;
e49829fe 28365+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 28366+
521ced18 28367+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
062440b3
AM
28368+ if (IS_ERR(h_file)) {
28369+ AuDbg("h_file %ld\n", PTR_ERR(h_file));
1308ab2a 28370+ goto out;
062440b3 28371+ }
1308ab2a 28372+
cd7a4cd9 28373+ mask = vfs_poll(h_file, pt);
b912730e 28374+ fput(h_file); /* instead of au_read_post() */
1308ab2a 28375+
4f0767ce 28376+out:
1308ab2a 28377+ si_read_unlock(sb);
062440b3 28378+ if (mask & EPOLLERR)
b00004a5 28379+ AuDbg("mask 0x%x\n", mask);
1308ab2a 28380+ return mask;
28381+}
c1595e42
JR
28382diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
28383--- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 28384+++ linux/fs/aufs/posix_acl.c 2018-08-12 23:43:05.460124736 +0200
062440b3 28385@@ -0,0 +1,103 @@
cd7a4cd9 28386+// SPDX-License-Identifier: GPL-2.0
c1595e42 28387+/*
b00004a5 28388+ * Copyright (C) 2014-2018 Junjiro R. Okajima
c1595e42
JR
28389+ *
28390+ * This program, aufs is free software; you can redistribute it and/or modify
28391+ * it under the terms of the GNU General Public License as published by
28392+ * the Free Software Foundation; either version 2 of the License, or
28393+ * (at your option) any later version.
28394+ *
28395+ * This program is distributed in the hope that it will be useful,
28396+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28397+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28398+ * GNU General Public License for more details.
28399+ *
28400+ * You should have received a copy of the GNU General Public License
28401+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28402+ */
28403+
28404+/*
28405+ * posix acl operations
28406+ */
28407+
28408+#include <linux/fs.h>
c1595e42
JR
28409+#include "aufs.h"
28410+
28411+struct posix_acl *aufs_get_acl(struct inode *inode, int type)
28412+{
28413+ struct posix_acl *acl;
28414+ int err;
28415+ aufs_bindex_t bindex;
28416+ struct inode *h_inode;
28417+ struct super_block *sb;
28418+
28419+ acl = NULL;
28420+ sb = inode->i_sb;
28421+ si_read_lock(sb, AuLock_FLUSH);
28422+ ii_read_lock_child(inode);
2121bcd9 28423+ if (!(sb->s_flags & SB_POSIXACL))
c1595e42
JR
28424+ goto out;
28425+
5afbbe0d 28426+ bindex = au_ibtop(inode);
c1595e42
JR
28427+ h_inode = au_h_iptr(inode, bindex);
28428+ if (unlikely(!h_inode
28429+ || ((h_inode->i_mode & S_IFMT)
28430+ != (inode->i_mode & S_IFMT)))) {
28431+ err = au_busy_or_stale();
28432+ acl = ERR_PTR(err);
28433+ goto out;
28434+ }
28435+
28436+ /* always topmost only */
28437+ acl = get_acl(h_inode, type);
a2654f78
AM
28438+ if (!IS_ERR_OR_NULL(acl))
28439+ set_cached_acl(inode, type, acl);
c1595e42
JR
28440+
28441+out:
28442+ ii_read_unlock(inode);
28443+ si_read_unlock(sb);
28444+
28445+ AuTraceErrPtr(acl);
28446+ return acl;
28447+}
28448+
28449+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
28450+{
28451+ int err;
28452+ ssize_t ssz;
28453+ struct dentry *dentry;
f2c43d5f 28454+ struct au_sxattr arg = {
c1595e42
JR
28455+ .type = AU_ACL_SET,
28456+ .u.acl_set = {
28457+ .acl = acl,
28458+ .type = type
28459+ },
28460+ };
28461+
5afbbe0d
AM
28462+ IMustLock(inode);
28463+
c1595e42
JR
28464+ if (inode->i_ino == AUFS_ROOT_INO)
28465+ dentry = dget(inode->i_sb->s_root);
28466+ else {
28467+ dentry = d_find_alias(inode);
28468+ if (!dentry)
28469+ dentry = d_find_any_alias(inode);
28470+ if (!dentry) {
28471+ pr_warn("cannot handle this inode, "
28472+ "please report to aufs-users ML\n");
28473+ err = -ENOENT;
28474+ goto out;
28475+ }
28476+ }
28477+
f2c43d5f 28478+ ssz = au_sxattr(dentry, inode, &arg);
c1595e42
JR
28479+ dput(dentry);
28480+ err = ssz;
a2654f78 28481+ if (ssz >= 0) {
c1595e42 28482+ err = 0;
a2654f78
AM
28483+ set_cached_acl(inode, type, acl);
28484+ }
c1595e42
JR
28485+
28486+out:
c1595e42
JR
28487+ return err;
28488+}
7f207e10
AM
28489diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
28490--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 28491+++ linux/fs/aufs/procfs.c 2018-08-12 23:43:05.460124736 +0200
062440b3 28492@@ -0,0 +1,171 @@
cd7a4cd9 28493+// SPDX-License-Identifier: GPL-2.0
e49829fe 28494+/*
b00004a5 28495+ * Copyright (C) 2010-2018 Junjiro R. Okajima
e49829fe
JR
28496+ *
28497+ * This program, aufs is free software; you can redistribute it and/or modify
28498+ * it under the terms of the GNU General Public License as published by
28499+ * the Free Software Foundation; either version 2 of the License, or
28500+ * (at your option) any later version.
28501+ *
28502+ * This program is distributed in the hope that it will be useful,
28503+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28504+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28505+ * GNU General Public License for more details.
28506+ *
28507+ * You should have received a copy of the GNU General Public License
523b37e3 28508+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
28509+ */
28510+
28511+/*
28512+ * procfs interfaces
28513+ */
28514+
28515+#include <linux/proc_fs.h>
28516+#include "aufs.h"
28517+
28518+static int au_procfs_plm_release(struct inode *inode, struct file *file)
28519+{
28520+ struct au_sbinfo *sbinfo;
28521+
28522+ sbinfo = file->private_data;
28523+ if (sbinfo) {
28524+ au_plink_maint_leave(sbinfo);
28525+ kobject_put(&sbinfo->si_kobj);
28526+ }
28527+
28528+ return 0;
28529+}
28530+
28531+static void au_procfs_plm_write_clean(struct file *file)
28532+{
28533+ struct au_sbinfo *sbinfo;
28534+
28535+ sbinfo = file->private_data;
28536+ if (sbinfo)
28537+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
28538+}
28539+
28540+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
28541+{
28542+ int err;
28543+ struct super_block *sb;
28544+ struct au_sbinfo *sbinfo;
8b6a4947 28545+ struct hlist_bl_node *pos;
e49829fe
JR
28546+
28547+ err = -EBUSY;
28548+ if (unlikely(file->private_data))
28549+ goto out;
28550+
28551+ sb = NULL;
53392da6 28552+ /* don't use au_sbilist_lock() here */
8b6a4947
AM
28553+ hlist_bl_lock(&au_sbilist);
28554+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list)
e49829fe
JR
28555+ if (id == sysaufs_si_id(sbinfo)) {
28556+ kobject_get(&sbinfo->si_kobj);
28557+ sb = sbinfo->si_sb;
28558+ break;
28559+ }
8b6a4947 28560+ hlist_bl_unlock(&au_sbilist);
e49829fe
JR
28561+
28562+ err = -EINVAL;
28563+ if (unlikely(!sb))
28564+ goto out;
28565+
28566+ err = au_plink_maint_enter(sb);
28567+ if (!err)
28568+ /* keep kobject_get() */
28569+ file->private_data = sbinfo;
28570+ else
28571+ kobject_put(&sbinfo->si_kobj);
28572+out:
28573+ return err;
28574+}
28575+
28576+/*
28577+ * Accept a valid "si=xxxx" only.
28578+ * Once it is accepted successfully, accept "clean" too.
28579+ */
28580+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
28581+ size_t count, loff_t *ppos)
28582+{
28583+ ssize_t err;
28584+ unsigned long id;
28585+ /* last newline is allowed */
28586+ char buf[3 + sizeof(unsigned long) * 2 + 1];
28587+
28588+ err = -EACCES;
28589+ if (unlikely(!capable(CAP_SYS_ADMIN)))
28590+ goto out;
28591+
28592+ err = -EINVAL;
28593+ if (unlikely(count > sizeof(buf)))
28594+ goto out;
28595+
28596+ err = copy_from_user(buf, ubuf, count);
28597+ if (unlikely(err)) {
28598+ err = -EFAULT;
28599+ goto out;
28600+ }
28601+ buf[count] = 0;
28602+
28603+ err = -EINVAL;
28604+ if (!strcmp("clean", buf)) {
28605+ au_procfs_plm_write_clean(file);
28606+ goto out_success;
28607+ } else if (unlikely(strncmp("si=", buf, 3)))
28608+ goto out;
28609+
9dbd164d 28610+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
28611+ if (unlikely(err))
28612+ goto out;
28613+
28614+ err = au_procfs_plm_write_si(file, id);
28615+ if (unlikely(err))
28616+ goto out;
28617+
28618+out_success:
28619+ err = count; /* success */
28620+out:
28621+ return err;
28622+}
28623+
28624+static const struct file_operations au_procfs_plm_fop = {
28625+ .write = au_procfs_plm_write,
28626+ .release = au_procfs_plm_release,
28627+ .owner = THIS_MODULE
28628+};
28629+
28630+/* ---------------------------------------------------------------------- */
28631+
28632+static struct proc_dir_entry *au_procfs_dir;
28633+
28634+void au_procfs_fin(void)
28635+{
28636+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
28637+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
28638+}
28639+
28640+int __init au_procfs_init(void)
28641+{
28642+ int err;
28643+ struct proc_dir_entry *entry;
28644+
28645+ err = -ENOMEM;
28646+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
28647+ if (unlikely(!au_procfs_dir))
28648+ goto out;
28649+
cd7a4cd9 28650+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | 0200,
e49829fe
JR
28651+ au_procfs_dir, &au_procfs_plm_fop);
28652+ if (unlikely(!entry))
28653+ goto out_dir;
28654+
28655+ err = 0;
28656+ goto out; /* success */
28657+
28658+
28659+out_dir:
28660+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
28661+out:
28662+ return err;
28663+}
7f207e10
AM
28664diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
28665--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 28666+++ linux/fs/aufs/rdu.c 2018-08-12 23:43:05.463458173 +0200
062440b3 28667@@ -0,0 +1,382 @@
cd7a4cd9 28668+// SPDX-License-Identifier: GPL-2.0
1308ab2a 28669+/*
b00004a5 28670+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1308ab2a 28671+ *
28672+ * This program, aufs is free software; you can redistribute it and/or modify
28673+ * it under the terms of the GNU General Public License as published by
28674+ * the Free Software Foundation; either version 2 of the License, or
28675+ * (at your option) any later version.
28676+ *
28677+ * This program is distributed in the hope that it will be useful,
28678+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28679+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28680+ * GNU General Public License for more details.
28681+ *
28682+ * You should have received a copy of the GNU General Public License
523b37e3 28683+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 28684+ */
28685+
28686+/*
28687+ * readdir in userspace.
28688+ */
28689+
b752ccd1 28690+#include <linux/compat.h>
4a4d8108 28691+#include <linux/fs_stack.h>
1308ab2a 28692+#include <linux/security.h>
1308ab2a 28693+#include "aufs.h"
28694+
28695+/* bits for struct aufs_rdu.flags */
28696+#define AuRdu_CALLED 1
28697+#define AuRdu_CONT (1 << 1)
28698+#define AuRdu_FULL (1 << 2)
28699+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
28700+#define au_fset_rdu(flags, name) \
28701+ do { (flags) |= AuRdu_##name; } while (0)
28702+#define au_fclr_rdu(flags, name) \
28703+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 28704+
28705+struct au_rdu_arg {
392086de 28706+ struct dir_context ctx;
1308ab2a 28707+ struct aufs_rdu *rdu;
28708+ union au_rdu_ent_ul ent;
28709+ unsigned long end;
28710+
28711+ struct super_block *sb;
28712+ int err;
28713+};
28714+
392086de 28715+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 28716+ loff_t offset, u64 h_ino, unsigned int d_type)
28717+{
28718+ int err, len;
392086de 28719+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 28720+ struct aufs_rdu *rdu = arg->rdu;
28721+ struct au_rdu_ent ent;
28722+
28723+ err = 0;
28724+ arg->err = 0;
28725+ au_fset_rdu(rdu->cookie.flags, CALLED);
28726+ len = au_rdu_len(nlen);
28727+ if (arg->ent.ul + len < arg->end) {
28728+ ent.ino = h_ino;
28729+ ent.bindex = rdu->cookie.bindex;
28730+ ent.type = d_type;
28731+ ent.nlen = nlen;
4a4d8108
AM
28732+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
28733+ ent.type = DT_UNKNOWN;
1308ab2a 28734+
9dbd164d 28735+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 28736+ err = -EFAULT;
28737+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
28738+ goto out;
28739+ if (copy_to_user(arg->ent.e->name, name, nlen))
28740+ goto out;
28741+ /* the terminating NULL */
28742+ if (__put_user(0, arg->ent.e->name + nlen))
28743+ goto out;
28744+ err = 0;
28745+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
28746+ arg->ent.ul += len;
28747+ rdu->rent++;
28748+ } else {
28749+ err = -EFAULT;
28750+ au_fset_rdu(rdu->cookie.flags, FULL);
28751+ rdu->full = 1;
28752+ rdu->tail = arg->ent;
28753+ }
28754+
4f0767ce 28755+out:
1308ab2a 28756+ /* AuTraceErr(err); */
28757+ return err;
28758+}
28759+
28760+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
28761+{
28762+ int err;
28763+ loff_t offset;
28764+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
28765+
92d182d2 28766+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 28767+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
28768+ err = offset;
28769+ if (unlikely(offset != cookie->h_pos))
28770+ goto out;
28771+
28772+ err = 0;
28773+ do {
28774+ arg->err = 0;
28775+ au_fclr_rdu(cookie->flags, CALLED);
28776+ /* smp_mb(); */
392086de 28777+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 28778+ if (err >= 0)
28779+ err = arg->err;
28780+ } while (!err
28781+ && au_ftest_rdu(cookie->flags, CALLED)
28782+ && !au_ftest_rdu(cookie->flags, FULL));
28783+ cookie->h_pos = h_file->f_pos;
28784+
4f0767ce 28785+out:
1308ab2a 28786+ AuTraceErr(err);
28787+ return err;
28788+}
28789+
28790+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
28791+{
28792+ int err;
5afbbe0d 28793+ aufs_bindex_t bbot;
392086de
AM
28794+ struct au_rdu_arg arg = {
28795+ .ctx = {
2000de60 28796+ .actor = au_rdu_fill
392086de
AM
28797+ }
28798+ };
1308ab2a 28799+ struct dentry *dentry;
28800+ struct inode *inode;
28801+ struct file *h_file;
28802+ struct au_rdu_cookie *cookie = &rdu->cookie;
28803+
28804+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
28805+ if (unlikely(err)) {
28806+ err = -EFAULT;
28807+ AuTraceErr(err);
28808+ goto out;
28809+ }
28810+ rdu->rent = 0;
28811+ rdu->tail = rdu->ent;
28812+ rdu->full = 0;
28813+ arg.rdu = rdu;
28814+ arg.ent = rdu->ent;
28815+ arg.end = arg.ent.ul;
28816+ arg.end += rdu->sz;
28817+
28818+ err = -ENOTDIR;
5afbbe0d 28819+ if (unlikely(!file->f_op->iterate && !file->f_op->iterate_shared))
1308ab2a 28820+ goto out;
28821+
28822+ err = security_file_permission(file, MAY_READ);
28823+ AuTraceErr(err);
28824+ if (unlikely(err))
28825+ goto out;
28826+
2000de60 28827+ dentry = file->f_path.dentry;
5527c038 28828+ inode = d_inode(dentry);
5afbbe0d 28829+ inode_lock_shared(inode);
1308ab2a 28830+
28831+ arg.sb = inode->i_sb;
e49829fe
JR
28832+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
28833+ if (unlikely(err))
28834+ goto out_mtx;
027c5e7a
AM
28835+ err = au_alive_dir(dentry);
28836+ if (unlikely(err))
28837+ goto out_si;
e49829fe 28838+ /* todo: reval? */
1308ab2a 28839+ fi_read_lock(file);
28840+
28841+ err = -EAGAIN;
28842+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
28843+ && cookie->generation != au_figen(file)))
28844+ goto out_unlock;
28845+
28846+ err = 0;
28847+ if (!rdu->blk) {
28848+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
28849+ if (!rdu->blk)
28850+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
28851+ }
5afbbe0d
AM
28852+ bbot = au_fbtop(file);
28853+ if (cookie->bindex < bbot)
28854+ cookie->bindex = bbot;
28855+ bbot = au_fbbot_dir(file);
28856+ /* AuDbg("b%d, b%d\n", cookie->bindex, bbot); */
28857+ for (; !err && cookie->bindex <= bbot;
1308ab2a 28858+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 28859+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 28860+ if (!h_file)
28861+ continue;
28862+
28863+ au_fclr_rdu(cookie->flags, FULL);
28864+ err = au_rdu_do(h_file, &arg);
28865+ AuTraceErr(err);
28866+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
28867+ break;
28868+ }
28869+ AuDbg("rent %llu\n", rdu->rent);
28870+
28871+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
28872+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
28873+ au_fset_rdu(cookie->flags, CONT);
28874+ cookie->generation = au_figen(file);
28875+ }
28876+
28877+ ii_read_lock_child(inode);
5afbbe0d 28878+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibtop(inode)));
1308ab2a 28879+ ii_read_unlock(inode);
28880+
4f0767ce 28881+out_unlock:
1308ab2a 28882+ fi_read_unlock(file);
027c5e7a 28883+out_si:
1308ab2a 28884+ si_read_unlock(arg.sb);
4f0767ce 28885+out_mtx:
5afbbe0d 28886+ inode_unlock_shared(inode);
4f0767ce 28887+out:
1308ab2a 28888+ AuTraceErr(err);
28889+ return err;
28890+}
28891+
28892+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
28893+{
28894+ int err;
28895+ ino_t ino;
28896+ unsigned long long nent;
28897+ union au_rdu_ent_ul *u;
28898+ struct au_rdu_ent ent;
28899+ struct super_block *sb;
28900+
28901+ err = 0;
28902+ nent = rdu->nent;
28903+ u = &rdu->ent;
2000de60 28904+ sb = file->f_path.dentry->d_sb;
1308ab2a 28905+ si_read_lock(sb, AuLock_FLUSH);
28906+ while (nent-- > 0) {
9dbd164d 28907+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 28908+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
28909+ if (!err)
28910+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 28911+ if (unlikely(err)) {
28912+ err = -EFAULT;
28913+ AuTraceErr(err);
28914+ break;
28915+ }
28916+
28917+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
28918+ if (!ent.wh)
28919+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
28920+ else
28921+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
28922+ &ino);
28923+ if (unlikely(err)) {
28924+ AuTraceErr(err);
28925+ break;
28926+ }
28927+
28928+ err = __put_user(ino, &u->e->ino);
28929+ if (unlikely(err)) {
28930+ err = -EFAULT;
28931+ AuTraceErr(err);
28932+ break;
28933+ }
28934+ u->ul += au_rdu_len(ent.nlen);
28935+ }
28936+ si_read_unlock(sb);
28937+
28938+ return err;
28939+}
28940+
28941+/* ---------------------------------------------------------------------- */
28942+
28943+static int au_rdu_verify(struct aufs_rdu *rdu)
28944+{
b752ccd1 28945+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 28946+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 28947+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 28948+ rdu->blk,
28949+ rdu->rent, rdu->shwh, rdu->full,
28950+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
28951+ rdu->cookie.generation);
dece6358 28952+
b752ccd1 28953+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 28954+ return 0;
dece6358 28955+
b752ccd1
AM
28956+ AuDbg("%u:%u\n",
28957+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 28958+ return -EINVAL;
28959+}
28960+
28961+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 28962+{
1308ab2a 28963+ long err, e;
28964+ struct aufs_rdu rdu;
28965+ void __user *p = (void __user *)arg;
dece6358 28966+
1308ab2a 28967+ err = copy_from_user(&rdu, p, sizeof(rdu));
28968+ if (unlikely(err)) {
28969+ err = -EFAULT;
28970+ AuTraceErr(err);
28971+ goto out;
28972+ }
28973+ err = au_rdu_verify(&rdu);
dece6358
AM
28974+ if (unlikely(err))
28975+ goto out;
28976+
1308ab2a 28977+ switch (cmd) {
28978+ case AUFS_CTL_RDU:
28979+ err = au_rdu(file, &rdu);
28980+ if (unlikely(err))
28981+ break;
dece6358 28982+
1308ab2a 28983+ e = copy_to_user(p, &rdu, sizeof(rdu));
28984+ if (unlikely(e)) {
28985+ err = -EFAULT;
28986+ AuTraceErr(err);
28987+ }
28988+ break;
28989+ case AUFS_CTL_RDU_INO:
28990+ err = au_rdu_ino(file, &rdu);
28991+ break;
28992+
28993+ default:
4a4d8108 28994+ /* err = -ENOTTY; */
1308ab2a 28995+ err = -EINVAL;
28996+ }
dece6358 28997+
4f0767ce 28998+out:
1308ab2a 28999+ AuTraceErr(err);
29000+ return err;
1facf9fc 29001+}
b752ccd1
AM
29002+
29003+#ifdef CONFIG_COMPAT
29004+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
29005+{
29006+ long err, e;
29007+ struct aufs_rdu rdu;
29008+ void __user *p = compat_ptr(arg);
29009+
29010+ /* todo: get_user()? */
29011+ err = copy_from_user(&rdu, p, sizeof(rdu));
29012+ if (unlikely(err)) {
29013+ err = -EFAULT;
29014+ AuTraceErr(err);
29015+ goto out;
29016+ }
29017+ rdu.ent.e = compat_ptr(rdu.ent.ul);
29018+ err = au_rdu_verify(&rdu);
29019+ if (unlikely(err))
29020+ goto out;
29021+
29022+ switch (cmd) {
29023+ case AUFS_CTL_RDU:
29024+ err = au_rdu(file, &rdu);
29025+ if (unlikely(err))
29026+ break;
29027+
29028+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
29029+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
29030+ e = copy_to_user(p, &rdu, sizeof(rdu));
29031+ if (unlikely(e)) {
29032+ err = -EFAULT;
29033+ AuTraceErr(err);
29034+ }
29035+ break;
29036+ case AUFS_CTL_RDU_INO:
29037+ err = au_rdu_ino(file, &rdu);
29038+ break;
29039+
29040+ default:
29041+ /* err = -ENOTTY; */
29042+ err = -EINVAL;
29043+ }
29044+
4f0767ce 29045+out:
b752ccd1
AM
29046+ AuTraceErr(err);
29047+ return err;
29048+}
29049+#endif
7f207e10
AM
29050diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
29051--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
acd2b654 29052+++ linux/fs/aufs/rwsem.h 2018-10-23 12:33:35.599375796 +0200
062440b3
AM
29053@@ -0,0 +1,73 @@
29054+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 29055+/*
b00004a5 29056+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 29057+ *
29058+ * This program, aufs is free software; you can redistribute it and/or modify
29059+ * it under the terms of the GNU General Public License as published by
29060+ * the Free Software Foundation; either version 2 of the License, or
29061+ * (at your option) any later version.
dece6358
AM
29062+ *
29063+ * This program is distributed in the hope that it will be useful,
29064+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29065+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29066+ * GNU General Public License for more details.
29067+ *
29068+ * You should have received a copy of the GNU General Public License
523b37e3 29069+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29070+ */
29071+
29072+/*
29073+ * simple read-write semaphore wrappers
29074+ */
29075+
29076+#ifndef __AUFS_RWSEM_H__
29077+#define __AUFS_RWSEM_H__
29078+
29079+#ifdef __KERNEL__
29080+
4a4d8108 29081+#include "debug.h"
dece6358 29082+
acd2b654 29083+/* in the future, the name 'au_rwsem' will be totally gone */
8b6a4947 29084+#define au_rwsem rw_semaphore
dece6358
AM
29085+
29086+/* to debug easier, do not make them inlined functions */
8b6a4947 29087+#define AuRwMustNoWaiters(rw) AuDebugOn(rwsem_is_contended(rw))
dece6358 29088+/* rwsem_is_locked() is unusable */
8b6a4947
AM
29089+#define AuRwMustReadLock(rw) AuDebugOn(!lockdep_recursing(current) \
29090+ && debug_locks \
29091+ && !lockdep_is_held_type(rw, 1))
29092+#define AuRwMustWriteLock(rw) AuDebugOn(!lockdep_recursing(current) \
29093+ && debug_locks \
29094+ && !lockdep_is_held_type(rw, 0))
29095+#define AuRwMustAnyLock(rw) AuDebugOn(!lockdep_recursing(current) \
29096+ && debug_locks \
29097+ && !lockdep_is_held(rw))
29098+#define AuRwDestroy(rw) AuDebugOn(!lockdep_recursing(current) \
29099+ && debug_locks \
29100+ && lockdep_is_held(rw))
29101+
29102+#define au_rw_init(rw) init_rwsem(rw)
dece6358 29103+
5afbbe0d
AM
29104+#define au_rw_init_wlock(rw) do { \
29105+ au_rw_init(rw); \
8b6a4947 29106+ down_write(rw); \
5afbbe0d 29107+ } while (0)
dece6358 29108+
8b6a4947
AM
29109+#define au_rw_init_wlock_nested(rw, lsc) do { \
29110+ au_rw_init(rw); \
29111+ down_write_nested(rw, lsc); \
5afbbe0d 29112+ } while (0)
dece6358 29113+
8b6a4947
AM
29114+#define au_rw_read_lock(rw) down_read(rw)
29115+#define au_rw_read_lock_nested(rw, lsc) down_read_nested(rw, lsc)
29116+#define au_rw_read_unlock(rw) up_read(rw)
29117+#define au_rw_dgrade_lock(rw) downgrade_write(rw)
29118+#define au_rw_write_lock(rw) down_write(rw)
29119+#define au_rw_write_lock_nested(rw, lsc) down_write_nested(rw, lsc)
29120+#define au_rw_write_unlock(rw) up_write(rw)
29121+/* why is not _nested version defined? */
29122+#define au_rw_read_trylock(rw) down_read_trylock(rw)
29123+#define au_rw_write_trylock(rw) down_write_trylock(rw)
1facf9fc 29124+
29125+#endif /* __KERNEL__ */
29126+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
29127diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
29128--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
29129+++ linux/fs/aufs/sbinfo.c 2018-10-23 12:33:35.599375796 +0200
29130@@ -0,0 +1,313 @@
cd7a4cd9 29131+// SPDX-License-Identifier: GPL-2.0
1facf9fc 29132+/*
b00004a5 29133+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 29134+ *
29135+ * This program, aufs is free software; you can redistribute it and/or modify
29136+ * it under the terms of the GNU General Public License as published by
29137+ * the Free Software Foundation; either version 2 of the License, or
29138+ * (at your option) any later version.
dece6358
AM
29139+ *
29140+ * This program is distributed in the hope that it will be useful,
29141+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29142+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29143+ * GNU General Public License for more details.
29144+ *
29145+ * You should have received a copy of the GNU General Public License
523b37e3 29146+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29147+ */
29148+
29149+/*
29150+ * superblock private data
29151+ */
29152+
29153+#include "aufs.h"
29154+
29155+/*
29156+ * they are necessary regardless sysfs is disabled.
29157+ */
29158+void au_si_free(struct kobject *kobj)
29159+{
86dc4139 29160+ int i;
1facf9fc 29161+ struct au_sbinfo *sbinfo;
b752ccd1 29162+ char *locked __maybe_unused; /* debug only */
1facf9fc 29163+
29164+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139 29165+ for (i = 0; i < AuPlink_NHASH; i++)
8b6a4947 29166+ AuDebugOn(!hlist_bl_empty(sbinfo->si_plink + i));
f0c0a007 29167+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
5afbbe0d 29168+
acd2b654
AM
29169+ AuLCntZero(au_lcnt_read(&sbinfo->si_ninodes, /*do_rev*/0));
29170+ au_lcnt_fin(&sbinfo->si_ninodes, /*do_sync*/0);
29171+ AuLCntZero(au_lcnt_read(&sbinfo->si_nfiles, /*do_rev*/0));
29172+ au_lcnt_fin(&sbinfo->si_nfiles, /*do_sync*/0);
1facf9fc 29173+
062440b3 29174+ dbgaufs_si_fin(sbinfo);
e49829fe 29175+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 29176+ au_br_free(sbinfo);
e49829fe 29177+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1 29178+
1c60b727 29179+ kfree(sbinfo->si_branch);
1facf9fc 29180+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 29181+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 29182+
acd2b654
AM
29183+ au_lcnt_wait_for_fin(&sbinfo->si_ninodes);
29184+ /* si_nfiles is waited too */
1c60b727 29185+ kfree(sbinfo);
1facf9fc 29186+}
29187+
29188+int au_si_alloc(struct super_block *sb)
29189+{
86dc4139 29190+ int err, i;
1facf9fc 29191+ struct au_sbinfo *sbinfo;
29192+
29193+ err = -ENOMEM;
4a4d8108 29194+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 29195+ if (unlikely(!sbinfo))
29196+ goto out;
29197+
29198+ /* will be reallocated separately */
29199+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
29200+ if (unlikely(!sbinfo->si_branch))
febd17d6 29201+ goto out_sbinfo;
1facf9fc 29202+
1facf9fc 29203+ err = sysaufs_si_init(sbinfo);
062440b3
AM
29204+ if (!err) {
29205+ dbgaufs_si_null(sbinfo);
29206+ err = dbgaufs_si_init(sbinfo);
29207+ if (unlikely(err))
29208+ kobject_put(&sbinfo->si_kobj);
29209+ }
1facf9fc 29210+ if (unlikely(err))
29211+ goto out_br;
29212+
29213+ au_nwt_init(&sbinfo->si_nowait);
dece6358 29214+ au_rw_init_wlock(&sbinfo->si_rwsem);
b752ccd1 29215+
acd2b654
AM
29216+ au_lcnt_init(&sbinfo->si_ninodes, /*release*/NULL);
29217+ au_lcnt_init(&sbinfo->si_nfiles, /*release*/NULL);
7f207e10 29218+
5afbbe0d 29219+ sbinfo->si_bbot = -1;
392086de 29220+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 29221+
29222+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
29223+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
29224+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
29225+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 29226+
076b876e
AM
29227+ au_fhsm_init(sbinfo);
29228+
e49829fe 29229+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 29230+
392086de
AM
29231+ sbinfo->si_xino_jiffy = jiffies;
29232+ sbinfo->si_xino_expire
29233+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 29234+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 29235+ /* leave si_xib_last_pindex and si_xib_next_bit */
29236+
8b6a4947 29237+ INIT_HLIST_BL_HEAD(&sbinfo->si_aopen);
b912730e 29238+
e49829fe 29239+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 29240+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
29241+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
29242+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
29243+
86dc4139 29244+ for (i = 0; i < AuPlink_NHASH; i++)
8b6a4947 29245+ INIT_HLIST_BL_HEAD(sbinfo->si_plink + i);
1facf9fc 29246+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 29247+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 29248+
8b6a4947 29249+ INIT_HLIST_BL_HEAD(&sbinfo->si_files);
523b37e3 29250+
b95c5147
AM
29251+ /* with getattr by default */
29252+ sbinfo->si_iop_array = aufs_iop;
29253+
1facf9fc 29254+ /* leave other members for sysaufs and si_mnt. */
29255+ sbinfo->si_sb = sb;
29256+ sb->s_fs_info = sbinfo;
b752ccd1 29257+ si_pid_set(sb);
1facf9fc 29258+ return 0; /* success */
29259+
4f0767ce 29260+out_br:
1c60b727 29261+ kfree(sbinfo->si_branch);
4f0767ce 29262+out_sbinfo:
1c60b727 29263+ kfree(sbinfo);
4f0767ce 29264+out:
1facf9fc 29265+ return err;
29266+}
29267+
e2f27e51 29268+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink)
1facf9fc 29269+{
29270+ int err, sz;
29271+ struct au_branch **brp;
29272+
dece6358
AM
29273+ AuRwMustWriteLock(&sbinfo->si_rwsem);
29274+
1facf9fc 29275+ err = -ENOMEM;
5afbbe0d 29276+ sz = sizeof(*brp) * (sbinfo->si_bbot + 1);
1facf9fc 29277+ if (unlikely(!sz))
29278+ sz = sizeof(*brp);
e2f27e51
AM
29279+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS,
29280+ may_shrink);
1facf9fc 29281+ if (brp) {
29282+ sbinfo->si_branch = brp;
29283+ err = 0;
29284+ }
29285+
29286+ return err;
29287+}
29288+
29289+/* ---------------------------------------------------------------------- */
29290+
29291+unsigned int au_sigen_inc(struct super_block *sb)
29292+{
29293+ unsigned int gen;
5527c038 29294+ struct inode *inode;
1facf9fc 29295+
dece6358
AM
29296+ SiMustWriteLock(sb);
29297+
1facf9fc 29298+ gen = ++au_sbi(sb)->si_generation;
29299+ au_update_digen(sb->s_root);
5527c038
JR
29300+ inode = d_inode(sb->s_root);
29301+ au_update_iigen(inode, /*half*/0);
be118d29 29302+ inode_inc_iversion(inode);
1facf9fc 29303+ return gen;
29304+}
29305+
29306+aufs_bindex_t au_new_br_id(struct super_block *sb)
29307+{
29308+ aufs_bindex_t br_id;
29309+ int i;
29310+ struct au_sbinfo *sbinfo;
29311+
dece6358
AM
29312+ SiMustWriteLock(sb);
29313+
1facf9fc 29314+ sbinfo = au_sbi(sb);
29315+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
29316+ br_id = ++sbinfo->si_last_br_id;
7f207e10 29317+ AuDebugOn(br_id < 0);
1facf9fc 29318+ if (br_id && au_br_index(sb, br_id) < 0)
29319+ return br_id;
29320+ }
29321+
29322+ return -1;
29323+}
29324+
29325+/* ---------------------------------------------------------------------- */
29326+
e49829fe
JR
29327+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
29328+int si_read_lock(struct super_block *sb, int flags)
29329+{
29330+ int err;
29331+
29332+ err = 0;
29333+ if (au_ftest_lock(flags, FLUSH))
29334+ au_nwt_flush(&au_sbi(sb)->si_nowait);
29335+
29336+ si_noflush_read_lock(sb);
29337+ err = au_plink_maint(sb, flags);
29338+ if (unlikely(err))
29339+ si_read_unlock(sb);
29340+
29341+ return err;
29342+}
29343+
29344+int si_write_lock(struct super_block *sb, int flags)
29345+{
29346+ int err;
29347+
29348+ if (au_ftest_lock(flags, FLUSH))
29349+ au_nwt_flush(&au_sbi(sb)->si_nowait);
29350+
29351+ si_noflush_write_lock(sb);
29352+ err = au_plink_maint(sb, flags);
29353+ if (unlikely(err))
29354+ si_write_unlock(sb);
29355+
29356+ return err;
29357+}
29358+
1facf9fc 29359+/* dentry and super_block lock. call at entry point */
e49829fe 29360+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 29361+{
e49829fe 29362+ int err;
027c5e7a 29363+ struct super_block *sb;
e49829fe 29364+
027c5e7a
AM
29365+ sb = dentry->d_sb;
29366+ err = si_read_lock(sb, flags);
29367+ if (unlikely(err))
29368+ goto out;
29369+
29370+ if (au_ftest_lock(flags, DW))
29371+ di_write_lock_child(dentry);
29372+ else
29373+ di_read_lock_child(dentry, flags);
29374+
29375+ if (au_ftest_lock(flags, GEN)) {
29376+ err = au_digen_test(dentry, au_sigen(sb));
79b8bda9
AM
29377+ if (!au_opt_test(au_mntflags(sb), UDBA_NONE))
29378+ AuDebugOn(!err && au_dbrange_test(dentry));
29379+ else if (!err)
29380+ err = au_dbrange_test(dentry);
027c5e7a
AM
29381+ if (unlikely(err))
29382+ aufs_read_unlock(dentry, flags);
e49829fe
JR
29383+ }
29384+
027c5e7a 29385+out:
e49829fe 29386+ return err;
1facf9fc 29387+}
29388+
29389+void aufs_read_unlock(struct dentry *dentry, int flags)
29390+{
29391+ if (au_ftest_lock(flags, DW))
29392+ di_write_unlock(dentry);
29393+ else
29394+ di_read_unlock(dentry, flags);
29395+ si_read_unlock(dentry->d_sb);
29396+}
29397+
29398+void aufs_write_lock(struct dentry *dentry)
29399+{
e49829fe 29400+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 29401+ di_write_lock_child(dentry);
29402+}
29403+
29404+void aufs_write_unlock(struct dentry *dentry)
29405+{
29406+ di_write_unlock(dentry);
29407+ si_write_unlock(dentry->d_sb);
29408+}
29409+
e49829fe 29410+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 29411+{
e49829fe 29412+ int err;
027c5e7a
AM
29413+ unsigned int sigen;
29414+ struct super_block *sb;
e49829fe 29415+
027c5e7a
AM
29416+ sb = d1->d_sb;
29417+ err = si_read_lock(sb, flags);
29418+ if (unlikely(err))
29419+ goto out;
29420+
b95c5147 29421+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS));
027c5e7a
AM
29422+
29423+ if (au_ftest_lock(flags, GEN)) {
29424+ sigen = au_sigen(sb);
29425+ err = au_digen_test(d1, sigen);
29426+ AuDebugOn(!err && au_dbrange_test(d1));
29427+ if (!err) {
29428+ err = au_digen_test(d2, sigen);
29429+ AuDebugOn(!err && au_dbrange_test(d2));
29430+ }
29431+ if (unlikely(err))
29432+ aufs_read_and_write_unlock2(d1, d2);
29433+ }
29434+
29435+out:
e49829fe 29436+ return err;
1facf9fc 29437+}
29438+
29439+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
29440+{
29441+ di_write_unlock2(d1, d2);
29442+ si_read_unlock(d1->d_sb);
29443+}
7f207e10
AM
29444diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
29445--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
29446+++ linux/fs/aufs/super.c 2018-10-23 12:33:35.599375796 +0200
29447@@ -0,0 +1,1048 @@
cd7a4cd9 29448+// SPDX-License-Identifier: GPL-2.0
1facf9fc 29449+/*
b00004a5 29450+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 29451+ *
29452+ * This program, aufs is free software; you can redistribute it and/or modify
29453+ * it under the terms of the GNU General Public License as published by
29454+ * the Free Software Foundation; either version 2 of the License, or
29455+ * (at your option) any later version.
dece6358
AM
29456+ *
29457+ * This program is distributed in the hope that it will be useful,
29458+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29459+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29460+ * GNU General Public License for more details.
29461+ *
29462+ * You should have received a copy of the GNU General Public License
523b37e3 29463+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29464+ */
29465+
29466+/*
29467+ * mount and super_block operations
29468+ */
29469+
f6c5ef8b 29470+#include <linux/mm.h>
1facf9fc 29471+#include <linux/seq_file.h>
29472+#include <linux/statfs.h>
7f207e10 29473+#include <linux/vmalloc.h>
1facf9fc 29474+#include "aufs.h"
29475+
29476+/*
29477+ * super_operations
29478+ */
29479+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
29480+{
29481+ struct au_icntnr *c;
29482+
29483+ c = au_cache_alloc_icntnr();
29484+ if (c) {
027c5e7a 29485+ au_icntnr_init(c);
be118d29 29486+ inode_set_iversion(&c->vfs_inode, 1); /* sigen(sb); */
1facf9fc 29487+ c->iinfo.ii_hinode = NULL;
29488+ return &c->vfs_inode;
29489+ }
29490+ return NULL;
29491+}
29492+
027c5e7a
AM
29493+static void aufs_destroy_inode_cb(struct rcu_head *head)
29494+{
29495+ struct inode *inode = container_of(head, struct inode, i_rcu);
29496+
1c60b727 29497+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
027c5e7a
AM
29498+}
29499+
1facf9fc 29500+static void aufs_destroy_inode(struct inode *inode)
29501+{
5afbbe0d
AM
29502+ if (!au_is_bad_inode(inode))
29503+ au_iinfo_fin(inode);
027c5e7a 29504+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 29505+}
29506+
29507+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
29508+{
29509+ struct inode *inode;
29510+ int err;
29511+
29512+ inode = iget_locked(sb, ino);
29513+ if (unlikely(!inode)) {
29514+ inode = ERR_PTR(-ENOMEM);
29515+ goto out;
29516+ }
29517+ if (!(inode->i_state & I_NEW))
29518+ goto out;
29519+
29520+ err = au_xigen_new(inode);
29521+ if (!err)
29522+ err = au_iinfo_init(inode);
29523+ if (!err)
be118d29 29524+ inode_inc_iversion(inode);
1facf9fc 29525+ else {
29526+ iget_failed(inode);
29527+ inode = ERR_PTR(err);
29528+ }
29529+
4f0767ce 29530+out:
1facf9fc 29531+ /* never return NULL */
29532+ AuDebugOn(!inode);
29533+ AuTraceErrPtr(inode);
29534+ return inode;
29535+}
29536+
29537+/* lock free root dinfo */
29538+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
29539+{
29540+ int err;
5afbbe0d 29541+ aufs_bindex_t bindex, bbot;
1facf9fc 29542+ struct path path;
4a4d8108 29543+ struct au_hdentry *hdp;
1facf9fc 29544+ struct au_branch *br;
076b876e 29545+ au_br_perm_str_t perm;
1facf9fc 29546+
29547+ err = 0;
5afbbe0d
AM
29548+ bbot = au_sbbot(sb);
29549+ bindex = 0;
29550+ hdp = au_hdentry(au_di(sb->s_root), bindex);
29551+ for (; !err && bindex <= bbot; bindex++, hdp++) {
1facf9fc 29552+ br = au_sbr(sb, bindex);
86dc4139 29553+ path.mnt = au_br_mnt(br);
5afbbe0d 29554+ path.dentry = hdp->hd_dentry;
1facf9fc 29555+ err = au_seq_path(seq, &path);
79b8bda9 29556+ if (!err) {
076b876e 29557+ au_optstr_br_perm(&perm, br->br_perm);
79b8bda9 29558+ seq_printf(seq, "=%s", perm.a);
5afbbe0d 29559+ if (bindex != bbot)
79b8bda9 29560+ seq_putc(seq, ':');
1e00d052 29561+ }
1facf9fc 29562+ }
79b8bda9
AM
29563+ if (unlikely(err || seq_has_overflowed(seq)))
29564+ err = -E2BIG;
1facf9fc 29565+
29566+ return err;
29567+}
29568+
f2c43d5f
AM
29569+static void au_gen_fmt(char *fmt, int len __maybe_unused, const char *pat,
29570+ const char *append)
29571+{
29572+ char *p;
29573+
29574+ p = fmt;
29575+ while (*pat != ':')
29576+ *p++ = *pat++;
29577+ *p++ = *pat++;
29578+ strcpy(p, append);
29579+ AuDebugOn(strlen(fmt) >= len);
29580+}
29581+
1facf9fc 29582+static void au_show_wbr_create(struct seq_file *m, int v,
29583+ struct au_sbinfo *sbinfo)
29584+{
29585+ const char *pat;
f2c43d5f
AM
29586+ char fmt[32];
29587+ struct au_wbr_mfs *mfs;
1facf9fc 29588+
dece6358
AM
29589+ AuRwMustAnyLock(&sbinfo->si_rwsem);
29590+
c2b27bf2 29591+ seq_puts(m, ",create=");
1facf9fc 29592+ pat = au_optstr_wbr_create(v);
f2c43d5f 29593+ mfs = &sbinfo->si_wbr_mfs;
1facf9fc 29594+ switch (v) {
29595+ case AuWbrCreate_TDP:
29596+ case AuWbrCreate_RR:
29597+ case AuWbrCreate_MFS:
29598+ case AuWbrCreate_PMFS:
c2b27bf2 29599+ seq_puts(m, pat);
1facf9fc 29600+ break;
f2c43d5f
AM
29601+ case AuWbrCreate_MFSRR:
29602+ case AuWbrCreate_TDMFS:
29603+ case AuWbrCreate_PMFSRR:
29604+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu");
29605+ seq_printf(m, fmt, mfs->mfsrr_watermark);
1facf9fc 29606+ break;
f2c43d5f 29607+ case AuWbrCreate_MFSV:
1facf9fc 29608+ case AuWbrCreate_PMFSV:
f2c43d5f
AM
29609+ au_gen_fmt(fmt, sizeof(fmt), pat, "%lu");
29610+ seq_printf(m, fmt,
29611+ jiffies_to_msecs(mfs->mfs_expire)
e49829fe 29612+ / MSEC_PER_SEC);
1facf9fc 29613+ break;
1facf9fc 29614+ case AuWbrCreate_MFSRRV:
f2c43d5f 29615+ case AuWbrCreate_TDMFSV:
392086de 29616+ case AuWbrCreate_PMFSRRV:
f2c43d5f
AM
29617+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu:%lu");
29618+ seq_printf(m, fmt, mfs->mfsrr_watermark,
29619+ jiffies_to_msecs(mfs->mfs_expire) / MSEC_PER_SEC);
392086de 29620+ break;
f2c43d5f
AM
29621+ default:
29622+ BUG();
1facf9fc 29623+ }
29624+}
29625+
7eafdf33 29626+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 29627+{
29628+#ifdef CONFIG_SYSFS
29629+ return 0;
29630+#else
29631+ int err;
29632+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
29633+ aufs_bindex_t bindex, brid;
1facf9fc 29634+ struct qstr *name;
29635+ struct file *f;
29636+ struct dentry *d, *h_root;
acd2b654 29637+ struct au_branch *br;
1facf9fc 29638+
dece6358
AM
29639+ AuRwMustAnyLock(&sbinfo->si_rwsem);
29640+
1facf9fc 29641+ err = 0;
1facf9fc 29642+ f = au_sbi(sb)->si_xib;
29643+ if (!f)
29644+ goto out;
29645+
29646+ /* stop printing the default xino path on the first writable branch */
29647+ h_root = NULL;
acd2b654
AM
29648+ bindex = au_xi_root(sb, f->f_path.dentry);
29649+ if (bindex >= 0) {
29650+ br = au_sbr_sb(sb, bindex);
29651+ h_root = au_br_dentry(br);
1facf9fc 29652+ }
acd2b654 29653+
2000de60 29654+ d = f->f_path.dentry;
1facf9fc 29655+ name = &d->d_name;
29656+ /* safe ->d_parent because the file is unlinked */
29657+ if (d->d_parent == h_root
29658+ && name->len == len
29659+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
29660+ goto out;
29661+
29662+ seq_puts(seq, ",xino=");
29663+ err = au_xino_path(seq, f);
29664+
4f0767ce 29665+out:
1facf9fc 29666+ return err;
29667+#endif
29668+}
29669+
29670+/* seq_file will re-call me in case of too long string */
7eafdf33 29671+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 29672+{
027c5e7a 29673+ int err;
1facf9fc 29674+ unsigned int mnt_flags, v;
29675+ struct super_block *sb;
29676+ struct au_sbinfo *sbinfo;
29677+
29678+#define AuBool(name, str) do { \
29679+ v = au_opt_test(mnt_flags, name); \
29680+ if (v != au_opt_test(AuOpt_Def, name)) \
29681+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
29682+} while (0)
29683+
29684+#define AuStr(name, str) do { \
29685+ v = mnt_flags & AuOptMask_##name; \
29686+ if (v != (AuOpt_Def & AuOptMask_##name)) \
29687+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
29688+} while (0)
29689+
29690+#define AuUInt(name, str, val) do { \
29691+ if (val != AUFS_##name##_DEF) \
29692+ seq_printf(m, "," #str "=%u", val); \
29693+} while (0)
29694+
7eafdf33 29695+ sb = dentry->d_sb;
2121bcd9 29696+ if (sb->s_flags & SB_POSIXACL)
c1595e42 29697+ seq_puts(m, ",acl");
be118d29
JR
29698+#if 0
29699+ if (sb->s_flags & SB_I_VERSION)
29700+ seq_puts(m, ",i_version");
29701+#endif
c1595e42
JR
29702+
29703+ /* lock free root dinfo */
1facf9fc 29704+ si_noflush_read_lock(sb);
29705+ sbinfo = au_sbi(sb);
29706+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
29707+
29708+ mnt_flags = au_mntflags(sb);
29709+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 29710+ err = au_show_xino(m, sb);
1facf9fc 29711+ if (unlikely(err))
29712+ goto out;
29713+ } else
29714+ seq_puts(m, ",noxino");
29715+
29716+ AuBool(TRUNC_XINO, trunc_xino);
29717+ AuStr(UDBA, udba);
dece6358 29718+ AuBool(SHWH, shwh);
1facf9fc 29719+ AuBool(PLINK, plink);
4a4d8108 29720+ AuBool(DIO, dio);
076b876e 29721+ AuBool(DIRPERM1, dirperm1);
1facf9fc 29722+
29723+ v = sbinfo->si_wbr_create;
29724+ if (v != AuWbrCreate_Def)
29725+ au_show_wbr_create(m, v, sbinfo);
29726+
29727+ v = sbinfo->si_wbr_copyup;
29728+ if (v != AuWbrCopyup_Def)
29729+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
29730+
29731+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
29732+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
29733+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
29734+
29735+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
29736+
027c5e7a
AM
29737+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
29738+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 29739+
29740+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
29741+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
29742+
076b876e
AM
29743+ au_fhsm_show(m, sbinfo);
29744+
8b6a4947 29745+ AuBool(DIRREN, dirren);
1facf9fc 29746+ AuBool(SUM, sum);
29747+ /* AuBool(SUM_W, wsum); */
29748+ AuBool(WARN_PERM, warn_perm);
29749+ AuBool(VERBOSE, verbose);
29750+
4f0767ce 29751+out:
1facf9fc 29752+ /* be sure to print "br:" last */
29753+ if (!sysaufs_brs) {
29754+ seq_puts(m, ",br:");
29755+ au_show_brs(m, sb);
29756+ }
29757+ si_read_unlock(sb);
29758+ return 0;
29759+
1facf9fc 29760+#undef AuBool
29761+#undef AuStr
4a4d8108 29762+#undef AuUInt
1facf9fc 29763+}
29764+
29765+/* ---------------------------------------------------------------------- */
29766+
29767+/* sum mode which returns the summation for statfs(2) */
29768+
29769+static u64 au_add_till_max(u64 a, u64 b)
29770+{
29771+ u64 old;
29772+
29773+ old = a;
29774+ a += b;
92d182d2
AM
29775+ if (old <= a)
29776+ return a;
29777+ return ULLONG_MAX;
29778+}
29779+
29780+static u64 au_mul_till_max(u64 a, long mul)
29781+{
29782+ u64 old;
29783+
29784+ old = a;
29785+ a *= mul;
29786+ if (old <= a)
1facf9fc 29787+ return a;
29788+ return ULLONG_MAX;
29789+}
29790+
29791+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
29792+{
29793+ int err;
92d182d2 29794+ long bsize, factor;
1facf9fc 29795+ u64 blocks, bfree, bavail, files, ffree;
5afbbe0d 29796+ aufs_bindex_t bbot, bindex, i;
1facf9fc 29797+ unsigned char shared;
7f207e10 29798+ struct path h_path;
1facf9fc 29799+ struct super_block *h_sb;
29800+
92d182d2
AM
29801+ err = 0;
29802+ bsize = LONG_MAX;
29803+ files = 0;
29804+ ffree = 0;
1facf9fc 29805+ blocks = 0;
29806+ bfree = 0;
29807+ bavail = 0;
5afbbe0d
AM
29808+ bbot = au_sbbot(sb);
29809+ for (bindex = 0; bindex <= bbot; bindex++) {
7f207e10
AM
29810+ h_path.mnt = au_sbr_mnt(sb, bindex);
29811+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 29812+ shared = 0;
92d182d2 29813+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 29814+ shared = (au_sbr_sb(sb, i) == h_sb);
29815+ if (shared)
29816+ continue;
29817+
29818+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
29819+ h_path.dentry = h_path.mnt->mnt_root;
29820+ err = vfs_statfs(&h_path, buf);
1facf9fc 29821+ if (unlikely(err))
29822+ goto out;
29823+
92d182d2
AM
29824+ if (bsize > buf->f_bsize) {
29825+ /*
29826+ * we will reduce bsize, so we have to expand blocks
29827+ * etc. to match them again
29828+ */
29829+ factor = (bsize / buf->f_bsize);
29830+ blocks = au_mul_till_max(blocks, factor);
29831+ bfree = au_mul_till_max(bfree, factor);
29832+ bavail = au_mul_till_max(bavail, factor);
29833+ bsize = buf->f_bsize;
29834+ }
29835+
29836+ factor = (buf->f_bsize / bsize);
29837+ blocks = au_add_till_max(blocks,
29838+ au_mul_till_max(buf->f_blocks, factor));
29839+ bfree = au_add_till_max(bfree,
29840+ au_mul_till_max(buf->f_bfree, factor));
29841+ bavail = au_add_till_max(bavail,
29842+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 29843+ files = au_add_till_max(files, buf->f_files);
29844+ ffree = au_add_till_max(ffree, buf->f_ffree);
29845+ }
29846+
92d182d2 29847+ buf->f_bsize = bsize;
1facf9fc 29848+ buf->f_blocks = blocks;
29849+ buf->f_bfree = bfree;
29850+ buf->f_bavail = bavail;
29851+ buf->f_files = files;
29852+ buf->f_ffree = ffree;
92d182d2 29853+ buf->f_frsize = 0;
1facf9fc 29854+
4f0767ce 29855+out:
1facf9fc 29856+ return err;
29857+}
29858+
29859+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
29860+{
29861+ int err;
7f207e10 29862+ struct path h_path;
1facf9fc 29863+ struct super_block *sb;
29864+
29865+ /* lock free root dinfo */
29866+ sb = dentry->d_sb;
29867+ si_noflush_read_lock(sb);
7f207e10 29868+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 29869+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
29870+ h_path.mnt = au_sbr_mnt(sb, 0);
29871+ h_path.dentry = h_path.mnt->mnt_root;
29872+ err = vfs_statfs(&h_path, buf);
29873+ } else
1facf9fc 29874+ err = au_statfs_sum(sb, buf);
29875+ si_read_unlock(sb);
29876+
29877+ if (!err) {
29878+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 29879+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 29880+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
29881+ }
29882+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
29883+
29884+ return err;
29885+}
29886+
29887+/* ---------------------------------------------------------------------- */
29888+
537831f9
AM
29889+static int aufs_sync_fs(struct super_block *sb, int wait)
29890+{
29891+ int err, e;
5afbbe0d 29892+ aufs_bindex_t bbot, bindex;
537831f9
AM
29893+ struct au_branch *br;
29894+ struct super_block *h_sb;
29895+
29896+ err = 0;
29897+ si_noflush_read_lock(sb);
5afbbe0d
AM
29898+ bbot = au_sbbot(sb);
29899+ for (bindex = 0; bindex <= bbot; bindex++) {
537831f9
AM
29900+ br = au_sbr(sb, bindex);
29901+ if (!au_br_writable(br->br_perm))
29902+ continue;
29903+
29904+ h_sb = au_sbr_sb(sb, bindex);
a2654f78
AM
29905+ e = vfsub_sync_filesystem(h_sb, wait);
29906+ if (unlikely(e && !err))
29907+ err = e;
29908+ /* go on even if an error happens */
537831f9
AM
29909+ }
29910+ si_read_unlock(sb);
29911+
29912+ return err;
29913+}
29914+
29915+/* ---------------------------------------------------------------------- */
29916+
1facf9fc 29917+/* final actions when unmounting a file system */
29918+static void aufs_put_super(struct super_block *sb)
29919+{
29920+ struct au_sbinfo *sbinfo;
29921+
29922+ sbinfo = au_sbi(sb);
062440b3
AM
29923+ if (sbinfo)
29924+ kobject_put(&sbinfo->si_kobj);
1facf9fc 29925+}
29926+
29927+/* ---------------------------------------------------------------------- */
29928+
79b8bda9
AM
29929+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
29930+ struct super_block *sb, void *arg)
7f207e10
AM
29931+{
29932+ void *array;
076b876e 29933+ unsigned long long n, sz;
7f207e10
AM
29934+
29935+ array = NULL;
29936+ n = 0;
29937+ if (!*hint)
29938+ goto out;
29939+
29940+ if (*hint > ULLONG_MAX / sizeof(array)) {
29941+ array = ERR_PTR(-EMFILE);
29942+ pr_err("hint %llu\n", *hint);
29943+ goto out;
29944+ }
29945+
076b876e
AM
29946+ sz = sizeof(array) * *hint;
29947+ array = kzalloc(sz, GFP_NOFS);
7f207e10 29948+ if (unlikely(!array))
076b876e 29949+ array = vzalloc(sz);
7f207e10
AM
29950+ if (unlikely(!array)) {
29951+ array = ERR_PTR(-ENOMEM);
29952+ goto out;
29953+ }
29954+
79b8bda9 29955+ n = cb(sb, array, *hint, arg);
7f207e10
AM
29956+ AuDebugOn(n > *hint);
29957+
29958+out:
29959+ *hint = n;
29960+ return array;
29961+}
29962+
79b8bda9 29963+static unsigned long long au_iarray_cb(struct super_block *sb, void *a,
7f207e10
AM
29964+ unsigned long long max __maybe_unused,
29965+ void *arg)
29966+{
29967+ unsigned long long n;
29968+ struct inode **p, *inode;
29969+ struct list_head *head;
29970+
29971+ n = 0;
29972+ p = a;
29973+ head = arg;
79b8bda9 29974+ spin_lock(&sb->s_inode_list_lock);
7f207e10 29975+ list_for_each_entry(inode, head, i_sb_list) {
5afbbe0d
AM
29976+ if (!au_is_bad_inode(inode)
29977+ && au_ii(inode)->ii_btop >= 0) {
2cbb1c4b
JR
29978+ spin_lock(&inode->i_lock);
29979+ if (atomic_read(&inode->i_count)) {
29980+ au_igrab(inode);
29981+ *p++ = inode;
29982+ n++;
29983+ AuDebugOn(n > max);
29984+ }
29985+ spin_unlock(&inode->i_lock);
7f207e10
AM
29986+ }
29987+ }
79b8bda9 29988+ spin_unlock(&sb->s_inode_list_lock);
7f207e10
AM
29989+
29990+ return n;
29991+}
29992+
29993+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
29994+{
acd2b654
AM
29995+ struct au_sbinfo *sbi;
29996+
29997+ sbi = au_sbi(sb);
29998+ *max = au_lcnt_read(&sbi->si_ninodes, /*do_rev*/1);
79b8bda9 29999+ return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes);
7f207e10
AM
30000+}
30001+
30002+void au_iarray_free(struct inode **a, unsigned long long max)
30003+{
30004+ unsigned long long ull;
30005+
30006+ for (ull = 0; ull < max; ull++)
30007+ iput(a[ull]);
be52b249 30008+ kvfree(a);
7f207e10
AM
30009+}
30010+
30011+/* ---------------------------------------------------------------------- */
30012+
1facf9fc 30013+/*
30014+ * refresh dentry and inode at remount time.
30015+ */
027c5e7a
AM
30016+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
30017+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
30018+ struct dentry *parent)
1facf9fc 30019+{
30020+ int err;
1facf9fc 30021+
30022+ di_write_lock_child(dentry);
1facf9fc 30023+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
30024+ err = au_refresh_dentry(dentry, parent);
30025+ if (!err && dir_flags)
5527c038 30026+ au_hn_reset(d_inode(dentry), dir_flags);
1facf9fc 30027+ di_read_unlock(parent, AuLock_IR);
1facf9fc 30028+ di_write_unlock(dentry);
30029+
30030+ return err;
30031+}
30032+
027c5e7a
AM
30033+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
30034+ struct au_sbinfo *sbinfo,
b95c5147 30035+ const unsigned int dir_flags, unsigned int do_idop)
1facf9fc 30036+{
027c5e7a
AM
30037+ int err;
30038+ struct dentry *parent;
027c5e7a
AM
30039+
30040+ err = 0;
30041+ parent = dget_parent(dentry);
30042+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
5527c038
JR
30043+ if (d_really_is_positive(dentry)) {
30044+ if (!d_is_dir(dentry))
027c5e7a
AM
30045+ err = au_do_refresh(dentry, /*dir_flags*/0,
30046+ parent);
30047+ else {
30048+ err = au_do_refresh(dentry, dir_flags, parent);
30049+ if (unlikely(err))
30050+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
30051+ }
30052+ } else
30053+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
30054+ AuDbgDentry(dentry);
30055+ }
30056+ dput(parent);
30057+
79b8bda9 30058+ if (!err) {
b95c5147 30059+ if (do_idop)
79b8bda9
AM
30060+ au_refresh_dop(dentry, /*force_reval*/0);
30061+ } else
30062+ au_refresh_dop(dentry, /*force_reval*/1);
30063+
027c5e7a
AM
30064+ AuTraceErr(err);
30065+ return err;
1facf9fc 30066+}
30067+
b95c5147 30068+static int au_refresh_d(struct super_block *sb, unsigned int do_idop)
1facf9fc 30069+{
30070+ int err, i, j, ndentry, e;
027c5e7a 30071+ unsigned int sigen;
1facf9fc 30072+ struct au_dcsub_pages dpages;
30073+ struct au_dpage *dpage;
027c5e7a
AM
30074+ struct dentry **dentries, *d;
30075+ struct au_sbinfo *sbinfo;
30076+ struct dentry *root = sb->s_root;
5527c038 30077+ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
1facf9fc 30078+
b95c5147 30079+ if (do_idop)
79b8bda9
AM
30080+ au_refresh_dop(root, /*force_reval*/0);
30081+
027c5e7a
AM
30082+ err = au_dpages_init(&dpages, GFP_NOFS);
30083+ if (unlikely(err))
1facf9fc 30084+ goto out;
027c5e7a
AM
30085+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
30086+ if (unlikely(err))
1facf9fc 30087+ goto out_dpages;
1facf9fc 30088+
027c5e7a
AM
30089+ sigen = au_sigen(sb);
30090+ sbinfo = au_sbi(sb);
30091+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 30092+ dpage = dpages.dpages + i;
30093+ dentries = dpage->dentries;
30094+ ndentry = dpage->ndentry;
027c5e7a 30095+ for (j = 0; j < ndentry; j++) {
1facf9fc 30096+ d = dentries[j];
79b8bda9 30097+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
b95c5147 30098+ do_idop);
027c5e7a
AM
30099+ if (unlikely(e && !err))
30100+ err = e;
30101+ /* go on even err */
1facf9fc 30102+ }
30103+ }
30104+
4f0767ce 30105+out_dpages:
1facf9fc 30106+ au_dpages_free(&dpages);
4f0767ce 30107+out:
1facf9fc 30108+ return err;
30109+}
30110+
b95c5147 30111+static int au_refresh_i(struct super_block *sb, unsigned int do_idop)
1facf9fc 30112+{
027c5e7a
AM
30113+ int err, e;
30114+ unsigned int sigen;
30115+ unsigned long long max, ull;
30116+ struct inode *inode, **array;
1facf9fc 30117+
027c5e7a
AM
30118+ array = au_iarray_alloc(sb, &max);
30119+ err = PTR_ERR(array);
30120+ if (IS_ERR(array))
30121+ goto out;
1facf9fc 30122+
30123+ err = 0;
027c5e7a
AM
30124+ sigen = au_sigen(sb);
30125+ for (ull = 0; ull < max; ull++) {
30126+ inode = array[ull];
076b876e
AM
30127+ if (unlikely(!inode))
30128+ break;
b95c5147
AM
30129+
30130+ e = 0;
30131+ ii_write_lock_child(inode);
537831f9 30132+ if (au_iigen(inode, NULL) != sigen) {
027c5e7a 30133+ e = au_refresh_hinode_self(inode);
1facf9fc 30134+ if (unlikely(e)) {
b95c5147 30135+ au_refresh_iop(inode, /*force_getattr*/1);
027c5e7a 30136+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 30137+ if (!err)
30138+ err = e;
30139+ /* go on even if err */
30140+ }
30141+ }
b95c5147
AM
30142+ if (!e && do_idop)
30143+ au_refresh_iop(inode, /*force_getattr*/0);
30144+ ii_write_unlock(inode);
1facf9fc 30145+ }
30146+
027c5e7a 30147+ au_iarray_free(array, max);
1facf9fc 30148+
4f0767ce 30149+out:
1facf9fc 30150+ return err;
30151+}
30152+
b95c5147 30153+static void au_remount_refresh(struct super_block *sb, unsigned int do_idop)
1facf9fc 30154+{
027c5e7a
AM
30155+ int err, e;
30156+ unsigned int udba;
5afbbe0d 30157+ aufs_bindex_t bindex, bbot;
1facf9fc 30158+ struct dentry *root;
30159+ struct inode *inode;
027c5e7a 30160+ struct au_branch *br;
79b8bda9 30161+ struct au_sbinfo *sbi;
1facf9fc 30162+
30163+ au_sigen_inc(sb);
79b8bda9
AM
30164+ sbi = au_sbi(sb);
30165+ au_fclr_si(sbi, FAILED_REFRESH_DIR);
1facf9fc 30166+
30167+ root = sb->s_root;
30168+ DiMustNoWaiters(root);
5527c038 30169+ inode = d_inode(root);
1facf9fc 30170+ IiMustNoWaiters(inode);
1facf9fc 30171+
027c5e7a 30172+ udba = au_opt_udba(sb);
5afbbe0d
AM
30173+ bbot = au_sbbot(sb);
30174+ for (bindex = 0; bindex <= bbot; bindex++) {
027c5e7a
AM
30175+ br = au_sbr(sb, bindex);
30176+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 30177+ if (unlikely(err))
027c5e7a
AM
30178+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
30179+ bindex, err);
30180+ /* go on even if err */
1facf9fc 30181+ }
027c5e7a 30182+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 30183+
b95c5147 30184+ if (do_idop) {
79b8bda9
AM
30185+ if (au_ftest_si(sbi, NO_DREVAL)) {
30186+ AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
30187+ sb->s_d_op = &aufs_dop_noreval;
b95c5147
AM
30188+ AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr);
30189+ sbi->si_iop_array = aufs_iop_nogetattr;
79b8bda9
AM
30190+ } else {
30191+ AuDebugOn(sb->s_d_op == &aufs_dop);
30192+ sb->s_d_op = &aufs_dop;
b95c5147
AM
30193+ AuDebugOn(sbi->si_iop_array == aufs_iop);
30194+ sbi->si_iop_array = aufs_iop;
79b8bda9 30195+ }
062440b3 30196+ pr_info("reset to %ps and %ps\n",
b95c5147 30197+ sb->s_d_op, sbi->si_iop_array);
79b8bda9
AM
30198+ }
30199+
027c5e7a 30200+ di_write_unlock(root);
b95c5147
AM
30201+ err = au_refresh_d(sb, do_idop);
30202+ e = au_refresh_i(sb, do_idop);
027c5e7a
AM
30203+ if (unlikely(e && !err))
30204+ err = e;
1facf9fc 30205+ /* aufs_write_lock() calls ..._child() */
30206+ di_write_lock_child(root);
027c5e7a
AM
30207+
30208+ au_cpup_attr_all(inode, /*force*/1);
30209+
30210+ if (unlikely(err))
30211+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 30212+}
30213+
30214+/* stop extra interpretation of errno in mount(8), and strange error messages */
30215+static int cvt_err(int err)
30216+{
30217+ AuTraceErr(err);
30218+
30219+ switch (err) {
30220+ case -ENOENT:
30221+ case -ENOTDIR:
30222+ case -EEXIST:
30223+ case -EIO:
30224+ err = -EINVAL;
30225+ }
30226+ return err;
30227+}
30228+
30229+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
30230+{
4a4d8108
AM
30231+ int err, do_dx;
30232+ unsigned int mntflags;
be52b249
AM
30233+ struct au_opts opts = {
30234+ .opt = NULL
30235+ };
1facf9fc 30236+ struct dentry *root;
30237+ struct inode *inode;
30238+ struct au_sbinfo *sbinfo;
30239+
30240+ err = 0;
30241+ root = sb->s_root;
30242+ if (!data || !*data) {
e49829fe
JR
30243+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
30244+ if (!err) {
30245+ di_write_lock_child(root);
30246+ err = au_opts_verify(sb, *flags, /*pending*/0);
30247+ aufs_write_unlock(root);
30248+ }
1facf9fc 30249+ goto out;
30250+ }
30251+
30252+ err = -ENOMEM;
1facf9fc 30253+ opts.opt = (void *)__get_free_page(GFP_NOFS);
30254+ if (unlikely(!opts.opt))
30255+ goto out;
30256+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
30257+ opts.flags = AuOpts_REMOUNT;
30258+ opts.sb_flags = *flags;
30259+
30260+ /* parse it before aufs lock */
30261+ err = au_opts_parse(sb, data, &opts);
30262+ if (unlikely(err))
30263+ goto out_opts;
30264+
30265+ sbinfo = au_sbi(sb);
5527c038 30266+ inode = d_inode(root);
febd17d6 30267+ inode_lock(inode);
e49829fe
JR
30268+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
30269+ if (unlikely(err))
30270+ goto out_mtx;
30271+ di_write_lock_child(root);
1facf9fc 30272+
30273+ /* au_opts_remount() may return an error */
30274+ err = au_opts_remount(sb, &opts);
30275+ au_opts_free(&opts);
30276+
027c5e7a 30277+ if (au_ftest_opts(opts.flags, REFRESH))
b95c5147 30278+ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP));
1facf9fc 30279+
4a4d8108
AM
30280+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
30281+ mntflags = au_mntflags(sb);
30282+ do_dx = !!au_opt_test(mntflags, DIO);
30283+ au_dy_arefresh(do_dx);
30284+ }
30285+
076b876e 30286+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
1facf9fc 30287+ aufs_write_unlock(root);
953406b4 30288+
e49829fe 30289+out_mtx:
febd17d6 30290+ inode_unlock(inode);
4f0767ce 30291+out_opts:
1c60b727 30292+ free_page((unsigned long)opts.opt);
4f0767ce 30293+out:
1facf9fc 30294+ err = cvt_err(err);
30295+ AuTraceErr(err);
30296+ return err;
30297+}
30298+
4a4d8108 30299+static const struct super_operations aufs_sop = {
1facf9fc 30300+ .alloc_inode = aufs_alloc_inode,
30301+ .destroy_inode = aufs_destroy_inode,
b752ccd1 30302+ /* always deleting, no clearing */
1facf9fc 30303+ .drop_inode = generic_delete_inode,
30304+ .show_options = aufs_show_options,
30305+ .statfs = aufs_statfs,
30306+ .put_super = aufs_put_super,
537831f9 30307+ .sync_fs = aufs_sync_fs,
1facf9fc 30308+ .remount_fs = aufs_remount_fs
30309+};
30310+
30311+/* ---------------------------------------------------------------------- */
30312+
30313+static int alloc_root(struct super_block *sb)
30314+{
30315+ int err;
30316+ struct inode *inode;
30317+ struct dentry *root;
30318+
30319+ err = -ENOMEM;
30320+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
30321+ err = PTR_ERR(inode);
30322+ if (IS_ERR(inode))
30323+ goto out;
30324+
b95c5147 30325+ inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */
1facf9fc 30326+ inode->i_fop = &aufs_dir_fop;
30327+ inode->i_mode = S_IFDIR;
9dbd164d 30328+ set_nlink(inode, 2);
1facf9fc 30329+ unlock_new_inode(inode);
30330+
92d182d2 30331+ root = d_make_root(inode);
1facf9fc 30332+ if (unlikely(!root))
92d182d2 30333+ goto out;
1facf9fc 30334+ err = PTR_ERR(root);
30335+ if (IS_ERR(root))
92d182d2 30336+ goto out;
1facf9fc 30337+
4a4d8108 30338+ err = au_di_init(root);
1facf9fc 30339+ if (!err) {
30340+ sb->s_root = root;
30341+ return 0; /* success */
30342+ }
30343+ dput(root);
1facf9fc 30344+
4f0767ce 30345+out:
1facf9fc 30346+ return err;
1facf9fc 30347+}
30348+
30349+static int aufs_fill_super(struct super_block *sb, void *raw_data,
30350+ int silent __maybe_unused)
30351+{
30352+ int err;
be52b249
AM
30353+ struct au_opts opts = {
30354+ .opt = NULL
30355+ };
79b8bda9 30356+ struct au_sbinfo *sbinfo;
1facf9fc 30357+ struct dentry *root;
30358+ struct inode *inode;
30359+ char *arg = raw_data;
30360+
30361+ if (unlikely(!arg || !*arg)) {
30362+ err = -EINVAL;
4a4d8108 30363+ pr_err("no arg\n");
1facf9fc 30364+ goto out;
30365+ }
30366+
30367+ err = -ENOMEM;
1facf9fc 30368+ opts.opt = (void *)__get_free_page(GFP_NOFS);
30369+ if (unlikely(!opts.opt))
30370+ goto out;
30371+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
30372+ opts.sb_flags = sb->s_flags;
30373+
30374+ err = au_si_alloc(sb);
30375+ if (unlikely(err))
30376+ goto out_opts;
79b8bda9 30377+ sbinfo = au_sbi(sb);
1facf9fc 30378+
30379+ /* all timestamps always follow the ones on the branch */
2121bcd9 30380+ sb->s_flags |= SB_NOATIME | SB_NODIRATIME;
be118d29 30381+ sb->s_flags |= SB_I_VERSION; /* do we really need this? */
1facf9fc 30382+ sb->s_op = &aufs_sop;
027c5e7a 30383+ sb->s_d_op = &aufs_dop;
1facf9fc 30384+ sb->s_magic = AUFS_SUPER_MAGIC;
30385+ sb->s_maxbytes = 0;
c1595e42 30386+ sb->s_stack_depth = 1;
1facf9fc 30387+ au_export_init(sb);
f2c43d5f 30388+ au_xattr_init(sb);
1facf9fc 30389+
30390+ err = alloc_root(sb);
30391+ if (unlikely(err)) {
30392+ si_write_unlock(sb);
30393+ goto out_info;
30394+ }
30395+ root = sb->s_root;
5527c038 30396+ inode = d_inode(root);
1facf9fc 30397+
30398+ /*
30399+ * actually we can parse options regardless aufs lock here.
30400+ * but at remount time, parsing must be done before aufs lock.
30401+ * so we follow the same rule.
30402+ */
30403+ ii_write_lock_parent(inode);
30404+ aufs_write_unlock(root);
30405+ err = au_opts_parse(sb, arg, &opts);
30406+ if (unlikely(err))
30407+ goto out_root;
30408+
30409+ /* lock vfs_inode first, then aufs. */
febd17d6 30410+ inode_lock(inode);
1facf9fc 30411+ aufs_write_lock(root);
30412+ err = au_opts_mount(sb, &opts);
30413+ au_opts_free(&opts);
79b8bda9
AM
30414+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) {
30415+ sb->s_d_op = &aufs_dop_noreval;
062440b3 30416+ pr_info("%ps\n", sb->s_d_op);
79b8bda9 30417+ au_refresh_dop(root, /*force_reval*/0);
b95c5147
AM
30418+ sbinfo->si_iop_array = aufs_iop_nogetattr;
30419+ au_refresh_iop(inode, /*force_getattr*/0);
79b8bda9 30420+ }
1facf9fc 30421+ aufs_write_unlock(root);
febd17d6 30422+ inode_unlock(inode);
4a4d8108
AM
30423+ if (!err)
30424+ goto out_opts; /* success */
1facf9fc 30425+
4f0767ce 30426+out_root:
1facf9fc 30427+ dput(root);
30428+ sb->s_root = NULL;
4f0767ce 30429+out_info:
79b8bda9 30430+ kobject_put(&sbinfo->si_kobj);
1facf9fc 30431+ sb->s_fs_info = NULL;
4f0767ce 30432+out_opts:
1c60b727 30433+ free_page((unsigned long)opts.opt);
4f0767ce 30434+out:
1facf9fc 30435+ AuTraceErr(err);
30436+ err = cvt_err(err);
30437+ AuTraceErr(err);
30438+ return err;
30439+}
30440+
30441+/* ---------------------------------------------------------------------- */
30442+
027c5e7a
AM
30443+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
30444+ const char *dev_name __maybe_unused,
30445+ void *raw_data)
1facf9fc 30446+{
027c5e7a 30447+ struct dentry *root;
1facf9fc 30448+
30449+ /* all timestamps always follow the ones on the branch */
30450+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
30451+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
30452+ if (IS_ERR(root))
30453+ goto out;
30454+
062440b3 30455+ au_sbilist_add(root->d_sb);
027c5e7a
AM
30456+
30457+out:
30458+ return root;
1facf9fc 30459+}
30460+
e49829fe
JR
30461+static void aufs_kill_sb(struct super_block *sb)
30462+{
30463+ struct au_sbinfo *sbinfo;
30464+
30465+ sbinfo = au_sbi(sb);
30466+ if (sbinfo) {
30467+ au_sbilist_del(sb);
30468+ aufs_write_lock(sb->s_root);
076b876e 30469+ au_fhsm_fin(sb);
e49829fe
JR
30470+ if (sbinfo->si_wbr_create_ops->fin)
30471+ sbinfo->si_wbr_create_ops->fin(sb);
30472+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
30473+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
b95c5147 30474+ au_remount_refresh(sb, /*do_idop*/0);
e49829fe
JR
30475+ }
30476+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
30477+ au_plink_put(sb, /*verbose*/1);
30478+ au_xino_clr(sb);
8b6a4947 30479+ au_dr_opt_flush(sb);
1e00d052 30480+ sbinfo->si_sb = NULL;
e49829fe 30481+ aufs_write_unlock(sb->s_root);
e49829fe
JR
30482+ au_nwt_flush(&sbinfo->si_nowait);
30483+ }
98d9a5b1 30484+ kill_anon_super(sb);
e49829fe
JR
30485+}
30486+
1facf9fc 30487+struct file_system_type aufs_fs_type = {
30488+ .name = AUFS_FSTYPE,
c06a8ce3
AM
30489+ /* a race between rename and others */
30490+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 30491+ .mount = aufs_mount,
e49829fe 30492+ .kill_sb = aufs_kill_sb,
1facf9fc 30493+ /* no need to __module_get() and module_put(). */
30494+ .owner = THIS_MODULE,
30495+};
7f207e10
AM
30496diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
30497--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
30498+++ linux/fs/aufs/super.h 2018-10-23 12:33:35.599375796 +0200
30499@@ -0,0 +1,589 @@
062440b3 30500+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 30501+/*
b00004a5 30502+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 30503+ *
30504+ * This program, aufs is free software; you can redistribute it and/or modify
30505+ * it under the terms of the GNU General Public License as published by
30506+ * the Free Software Foundation; either version 2 of the License, or
30507+ * (at your option) any later version.
dece6358
AM
30508+ *
30509+ * This program is distributed in the hope that it will be useful,
30510+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30511+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30512+ * GNU General Public License for more details.
30513+ *
30514+ * You should have received a copy of the GNU General Public License
523b37e3 30515+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30516+ */
30517+
30518+/*
30519+ * super_block operations
30520+ */
30521+
30522+#ifndef __AUFS_SUPER_H__
30523+#define __AUFS_SUPER_H__
30524+
30525+#ifdef __KERNEL__
30526+
30527+#include <linux/fs.h>
5527c038 30528+#include <linux/kobject.h>
8b6a4947 30529+#include "hbl.h"
acd2b654 30530+#include "lcnt.h"
1facf9fc 30531+#include "rwsem.h"
1facf9fc 30532+#include "wkq.h"
30533+
1facf9fc 30534+/* policies to select one among multiple writable branches */
30535+struct au_wbr_copyup_operations {
30536+ int (*copyup)(struct dentry *dentry);
30537+};
30538+
392086de
AM
30539+#define AuWbr_DIR 1 /* target is a dir */
30540+#define AuWbr_PARENT (1 << 1) /* always require a parent */
30541+
30542+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
30543+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
30544+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
30545+
1facf9fc 30546+struct au_wbr_create_operations {
392086de 30547+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 30548+ int (*init)(struct super_block *sb);
30549+ int (*fin)(struct super_block *sb);
30550+};
30551+
30552+struct au_wbr_mfs {
30553+ struct mutex mfs_lock; /* protect this structure */
30554+ unsigned long mfs_jiffy;
30555+ unsigned long mfs_expire;
30556+ aufs_bindex_t mfs_bindex;
30557+
30558+ unsigned long long mfsrr_bytes;
30559+ unsigned long long mfsrr_watermark;
30560+};
30561+
86dc4139
AM
30562+#define AuPlink_NHASH 100
30563+static inline int au_plink_hash(ino_t ino)
30564+{
30565+ return ino % AuPlink_NHASH;
30566+}
30567+
076b876e
AM
30568+/* File-based Hierarchical Storage Management */
30569+struct au_fhsm {
30570+#ifdef CONFIG_AUFS_FHSM
30571+ /* allow only one process who can receive the notification */
30572+ spinlock_t fhsm_spin;
30573+ pid_t fhsm_pid;
30574+ wait_queue_head_t fhsm_wqh;
30575+ atomic_t fhsm_readable;
30576+
c1595e42 30577+ /* these are protected by si_rwsem */
076b876e 30578+ unsigned long fhsm_expire;
c1595e42 30579+ aufs_bindex_t fhsm_bottom;
076b876e
AM
30580+#endif
30581+};
30582+
1facf9fc 30583+struct au_branch;
30584+struct au_sbinfo {
30585+ /* nowait tasks in the system-wide workqueue */
30586+ struct au_nowait_tasks si_nowait;
30587+
b752ccd1 30588+ /*
acd2b654 30589+ * tried sb->s_umount, but failed due to the dependency between i_mutex.
b752ccd1
AM
30590+ * rwsem for au_sbinfo is necessary.
30591+ */
dece6358 30592+ struct au_rwsem si_rwsem;
1facf9fc 30593+
7f207e10 30594+ /*
523b37e3
AM
30595+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
30596+ * remount.
7f207e10 30597+ */
acd2b654 30598+ au_lcnt_t si_ninodes, si_nfiles;
7f207e10 30599+
1facf9fc 30600+ /* branch management */
30601+ unsigned int si_generation;
30602+
2000de60 30603+ /* see AuSi_ flags */
1facf9fc 30604+ unsigned char au_si_status;
30605+
5afbbe0d 30606+ aufs_bindex_t si_bbot;
7f207e10
AM
30607+
30608+ /* dirty trick to keep br_id plus */
30609+ unsigned int si_last_br_id :
30610+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 30611+ struct au_branch **si_branch;
30612+
30613+ /* policy to select a writable branch */
30614+ unsigned char si_wbr_copyup;
30615+ unsigned char si_wbr_create;
30616+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
30617+ struct au_wbr_create_operations *si_wbr_create_ops;
30618+
30619+ /* round robin */
30620+ atomic_t si_wbr_rr_next;
30621+
30622+ /* most free space */
30623+ struct au_wbr_mfs si_wbr_mfs;
30624+
076b876e
AM
30625+ /* File-based Hierarchical Storage Management */
30626+ struct au_fhsm si_fhsm;
30627+
1facf9fc 30628+ /* mount flags */
30629+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
30630+ unsigned int si_mntflags;
30631+
30632+ /* external inode number (bitmap and translation table) */
5527c038
JR
30633+ vfs_readf_t si_xread;
30634+ vfs_writef_t si_xwrite;
acd2b654
AM
30635+ loff_t si_ximaxent; /* max entries in a xino */
30636+
1facf9fc 30637+ struct file *si_xib;
30638+ struct mutex si_xib_mtx; /* protect xib members */
30639+ unsigned long *si_xib_buf;
30640+ unsigned long si_xib_last_pindex;
30641+ int si_xib_next_bit;
acd2b654 30642+
392086de
AM
30643+ unsigned long si_xino_jiffy;
30644+ unsigned long si_xino_expire;
1facf9fc 30645+ /* reserved for future use */
30646+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
30647+
30648+#ifdef CONFIG_AUFS_EXPORT
30649+ /* i_generation */
acd2b654 30650+ /* todo: make xigen file an array to support many inode numbers */
1facf9fc 30651+ struct file *si_xigen;
30652+ atomic_t si_xigen_next;
30653+#endif
30654+
acd2b654 30655+ /* dirty trick to support atomic_open */
8b6a4947 30656+ struct hlist_bl_head si_aopen;
b912730e 30657+
1facf9fc 30658+ /* vdir parameters */
e49829fe 30659+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 30660+ unsigned int si_rdblk; /* deblk size */
30661+ unsigned int si_rdhash; /* hash size */
30662+
30663+ /*
30664+ * If the number of whiteouts are larger than si_dirwh, leave all of
30665+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
30666+ * future fsck.aufs or kernel thread will remove them later.
30667+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
30668+ */
30669+ unsigned int si_dirwh;
30670+
1facf9fc 30671+ /* pseudo_link list */
8b6a4947 30672+ struct hlist_bl_head si_plink[AuPlink_NHASH];
1facf9fc 30673+ wait_queue_head_t si_plink_wq;
4a4d8108 30674+ spinlock_t si_plink_maint_lock;
e49829fe 30675+ pid_t si_plink_maint_pid;
1facf9fc 30676+
523b37e3 30677+ /* file list */
8b6a4947 30678+ struct hlist_bl_head si_files;
523b37e3 30679+
b95c5147
AM
30680+ /* with/without getattr, brother of sb->s_d_op */
30681+ struct inode_operations *si_iop_array;
30682+
1facf9fc 30683+ /*
30684+ * sysfs and lifetime management.
30685+ * this is not a small structure and it may be a waste of memory in case
acd2b654 30686+ * of sysfs is disabled, particularly when many aufs-es are mounted.
1facf9fc 30687+ * but using sysfs is majority.
30688+ */
30689+ struct kobject si_kobj;
30690+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
30691+ struct dentry *si_dbgaufs;
30692+ struct dentry *si_dbgaufs_plink;
30693+ struct dentry *si_dbgaufs_xib;
1facf9fc 30694+#ifdef CONFIG_AUFS_EXPORT
30695+ struct dentry *si_dbgaufs_xigen;
30696+#endif
30697+#endif
30698+
e49829fe 30699+#ifdef CONFIG_AUFS_SBILIST
8b6a4947 30700+ struct hlist_bl_node si_list;
e49829fe
JR
30701+#endif
30702+
1facf9fc 30703+ /* dirty, necessary for unmounting, sysfs and sysrq */
30704+ struct super_block *si_sb;
30705+};
30706+
dece6358
AM
30707+/* sbinfo status flags */
30708+/*
30709+ * set true when refresh_dirs() failed at remount time.
30710+ * then try refreshing dirs at access time again.
062440b3 30711+ * if it is false, refreshing dirs at access time is unnecessary
dece6358 30712+ */
027c5e7a 30713+#define AuSi_FAILED_REFRESH_DIR 1
076b876e 30714+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
79b8bda9 30715+#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */
076b876e
AM
30716+
30717+#ifndef CONFIG_AUFS_FHSM
30718+#undef AuSi_FHSM
30719+#define AuSi_FHSM 0
30720+#endif
30721+
dece6358
AM
30722+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
30723+ unsigned int flag)
30724+{
30725+ AuRwMustAnyLock(&sbi->si_rwsem);
30726+ return sbi->au_si_status & flag;
30727+}
30728+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
30729+#define au_fset_si(sbinfo, name) do { \
30730+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
30731+ (sbinfo)->au_si_status |= AuSi_##name; \
30732+} while (0)
30733+#define au_fclr_si(sbinfo, name) do { \
30734+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
30735+ (sbinfo)->au_si_status &= ~AuSi_##name; \
30736+} while (0)
30737+
1facf9fc 30738+/* ---------------------------------------------------------------------- */
30739+
30740+/* policy to select one among writable branches */
4a4d8108
AM
30741+#define AuWbrCopyup(sbinfo, ...) \
30742+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
30743+#define AuWbrCreate(sbinfo, ...) \
30744+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 30745+
30746+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
30747+#define AuLock_DW 1 /* write-lock dentry */
30748+#define AuLock_IR (1 << 1) /* read-lock inode */
30749+#define AuLock_IW (1 << 2) /* write-lock inode */
30750+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
b95c5147 30751+#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */
f2c43d5f 30752+ /* except RENAME_EXCHANGE */
e49829fe
JR
30753+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
30754+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 30755+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 30756+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
30757+#define au_fset_lock(flags, name) \
30758+ do { (flags) |= AuLock_##name; } while (0)
30759+#define au_fclr_lock(flags, name) \
30760+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 30761+
30762+/* ---------------------------------------------------------------------- */
30763+
30764+/* super.c */
30765+extern struct file_system_type aufs_fs_type;
30766+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
79b8bda9
AM
30767+typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array,
30768+ unsigned long long max, void *arg);
79b8bda9
AM
30769+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
30770+ struct super_block *sb, void *arg);
7f207e10
AM
30771+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
30772+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 30773+
30774+/* sbinfo.c */
30775+void au_si_free(struct kobject *kobj);
30776+int au_si_alloc(struct super_block *sb);
e2f27e51 30777+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink);
1facf9fc 30778+
30779+unsigned int au_sigen_inc(struct super_block *sb);
30780+aufs_bindex_t au_new_br_id(struct super_block *sb);
30781+
e49829fe
JR
30782+int si_read_lock(struct super_block *sb, int flags);
30783+int si_write_lock(struct super_block *sb, int flags);
30784+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 30785+void aufs_read_unlock(struct dentry *dentry, int flags);
30786+void aufs_write_lock(struct dentry *dentry);
30787+void aufs_write_unlock(struct dentry *dentry);
e49829fe 30788+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 30789+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
30790+
30791+/* wbr_policy.c */
30792+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
30793+extern struct au_wbr_create_operations au_wbr_create_ops[];
30794+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2 30795+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
5afbbe0d 30796+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop);
c2b27bf2
AM
30797+
30798+/* mvdown.c */
30799+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 30800+
076b876e
AM
30801+#ifdef CONFIG_AUFS_FHSM
30802+/* fhsm.c */
30803+
30804+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
30805+{
30806+ pid_t pid;
30807+
30808+ spin_lock(&fhsm->fhsm_spin);
30809+ pid = fhsm->fhsm_pid;
30810+ spin_unlock(&fhsm->fhsm_spin);
30811+
30812+ return pid;
30813+}
30814+
30815+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
30816+void au_fhsm_wrote_all(struct super_block *sb, int force);
30817+int au_fhsm_fd(struct super_block *sb, int oflags);
30818+int au_fhsm_br_alloc(struct au_branch *br);
c1595e42 30819+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
076b876e
AM
30820+void au_fhsm_fin(struct super_block *sb);
30821+void au_fhsm_init(struct au_sbinfo *sbinfo);
30822+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
30823+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
30824+#else
30825+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
30826+ int force)
30827+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
30828+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
c1595e42
JR
30829+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
30830+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
30831+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
076b876e
AM
30832+AuStubVoid(au_fhsm_fin, struct super_block *sb)
30833+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
30834+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
30835+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
30836+#endif
30837+
1facf9fc 30838+/* ---------------------------------------------------------------------- */
30839+
30840+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
30841+{
30842+ return sb->s_fs_info;
30843+}
30844+
30845+/* ---------------------------------------------------------------------- */
30846+
30847+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 30848+int au_test_nfsd(void);
1facf9fc 30849+void au_export_init(struct super_block *sb);
b752ccd1 30850+void au_xigen_inc(struct inode *inode);
1facf9fc 30851+int au_xigen_new(struct inode *inode);
062440b3 30852+int au_xigen_set(struct super_block *sb, struct path *path);
1facf9fc 30853+void au_xigen_clr(struct super_block *sb);
30854+
30855+static inline int au_busy_or_stale(void)
30856+{
b752ccd1 30857+ if (!au_test_nfsd())
1facf9fc 30858+ return -EBUSY;
30859+ return -ESTALE;
30860+}
30861+#else
b752ccd1 30862+AuStubInt0(au_test_nfsd, void)
a2a7ad62 30863+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 30864+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108 30865+AuStubInt0(au_xigen_new, struct inode *inode)
062440b3 30866+AuStubInt0(au_xigen_set, struct super_block *sb, struct path *path)
4a4d8108 30867+AuStubVoid(au_xigen_clr, struct super_block *sb)
c1595e42 30868+AuStub(int, au_busy_or_stale, return -EBUSY, void)
1facf9fc 30869+#endif /* CONFIG_AUFS_EXPORT */
30870+
30871+/* ---------------------------------------------------------------------- */
30872+
e49829fe
JR
30873+#ifdef CONFIG_AUFS_SBILIST
30874+/* module.c */
8b6a4947 30875+extern struct hlist_bl_head au_sbilist;
e49829fe
JR
30876+
30877+static inline void au_sbilist_init(void)
30878+{
8b6a4947 30879+ INIT_HLIST_BL_HEAD(&au_sbilist);
e49829fe
JR
30880+}
30881+
30882+static inline void au_sbilist_add(struct super_block *sb)
30883+{
8b6a4947 30884+ au_hbl_add(&au_sbi(sb)->si_list, &au_sbilist);
e49829fe
JR
30885+}
30886+
30887+static inline void au_sbilist_del(struct super_block *sb)
30888+{
8b6a4947 30889+ au_hbl_del(&au_sbi(sb)->si_list, &au_sbilist);
e49829fe 30890+}
53392da6
AM
30891+
30892+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
30893+static inline void au_sbilist_lock(void)
30894+{
8b6a4947 30895+ hlist_bl_lock(&au_sbilist);
53392da6
AM
30896+}
30897+
30898+static inline void au_sbilist_unlock(void)
30899+{
8b6a4947 30900+ hlist_bl_unlock(&au_sbilist);
53392da6
AM
30901+}
30902+#define AuGFP_SBILIST GFP_ATOMIC
30903+#else
30904+AuStubVoid(au_sbilist_lock, void)
30905+AuStubVoid(au_sbilist_unlock, void)
30906+#define AuGFP_SBILIST GFP_NOFS
30907+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
30908+#else
30909+AuStubVoid(au_sbilist_init, void)
c1595e42
JR
30910+AuStubVoid(au_sbilist_add, struct super_block *sb)
30911+AuStubVoid(au_sbilist_del, struct super_block *sb)
53392da6
AM
30912+AuStubVoid(au_sbilist_lock, void)
30913+AuStubVoid(au_sbilist_unlock, void)
30914+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
30915+#endif
30916+
30917+/* ---------------------------------------------------------------------- */
30918+
1facf9fc 30919+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
30920+{
dece6358 30921+ /*
c1595e42 30922+ * This function is a dynamic '__init' function actually,
dece6358
AM
30923+ * so the tiny check for si_rwsem is unnecessary.
30924+ */
30925+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 30926+#ifdef CONFIG_DEBUG_FS
30927+ sbinfo->si_dbgaufs = NULL;
86dc4139 30928+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 30929+ sbinfo->si_dbgaufs_xib = NULL;
30930+#ifdef CONFIG_AUFS_EXPORT
30931+ sbinfo->si_dbgaufs_xigen = NULL;
30932+#endif
30933+#endif
30934+}
30935+
30936+/* ---------------------------------------------------------------------- */
30937+
a2654f78
AM
30938+/* current->atomic_flags */
30939+/* this value should never corrupt the ones defined in linux/sched.h */
30940+#define PFA_AUFS 7
30941+
30942+TASK_PFA_TEST(AUFS, test_aufs) /* task_test_aufs */
30943+TASK_PFA_SET(AUFS, aufs) /* task_set_aufs */
30944+TASK_PFA_CLEAR(AUFS, aufs) /* task_clear_aufs */
b752ccd1
AM
30945+
30946+static inline int si_pid_test(struct super_block *sb)
30947+{
a2654f78 30948+ return !!task_test_aufs(current);
b752ccd1
AM
30949+}
30950+
30951+static inline void si_pid_clr(struct super_block *sb)
30952+{
a2654f78
AM
30953+ AuDebugOn(!task_test_aufs(current));
30954+ task_clear_aufs(current);
b752ccd1
AM
30955+}
30956+
a2654f78
AM
30957+static inline void si_pid_set(struct super_block *sb)
30958+{
30959+ AuDebugOn(task_test_aufs(current));
30960+ task_set_aufs(current);
30961+}
febd17d6 30962+
b752ccd1
AM
30963+/* ---------------------------------------------------------------------- */
30964+
1facf9fc 30965+/* lock superblock. mainly for entry point functions */
8b6a4947
AM
30966+#define __si_read_lock(sb) au_rw_read_lock(&au_sbi(sb)->si_rwsem)
30967+#define __si_write_lock(sb) au_rw_write_lock(&au_sbi(sb)->si_rwsem)
30968+#define __si_read_trylock(sb) au_rw_read_trylock(&au_sbi(sb)->si_rwsem)
30969+#define __si_write_trylock(sb) au_rw_write_trylock(&au_sbi(sb)->si_rwsem)
30970+/*
30971+#define __si_read_trylock_nested(sb) \
30972+ au_rw_read_trylock_nested(&au_sbi(sb)->si_rwsem)
30973+#define __si_write_trylock_nested(sb) \
30974+ au_rw_write_trylock_nested(&au_sbi(sb)->si_rwsem)
30975+*/
30976+
30977+#define __si_read_unlock(sb) au_rw_read_unlock(&au_sbi(sb)->si_rwsem)
30978+#define __si_write_unlock(sb) au_rw_write_unlock(&au_sbi(sb)->si_rwsem)
30979+#define __si_downgrade_lock(sb) au_rw_dgrade_lock(&au_sbi(sb)->si_rwsem)
1facf9fc 30980+
dece6358
AM
30981+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
30982+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
30983+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
30984+
b752ccd1
AM
30985+static inline void si_noflush_read_lock(struct super_block *sb)
30986+{
30987+ __si_read_lock(sb);
30988+ si_pid_set(sb);
30989+}
30990+
30991+static inline int si_noflush_read_trylock(struct super_block *sb)
30992+{
076b876e
AM
30993+ int locked;
30994+
30995+ locked = __si_read_trylock(sb);
b752ccd1
AM
30996+ if (locked)
30997+ si_pid_set(sb);
30998+ return locked;
30999+}
31000+
31001+static inline void si_noflush_write_lock(struct super_block *sb)
31002+{
31003+ __si_write_lock(sb);
31004+ si_pid_set(sb);
31005+}
31006+
31007+static inline int si_noflush_write_trylock(struct super_block *sb)
31008+{
076b876e
AM
31009+ int locked;
31010+
31011+ locked = __si_write_trylock(sb);
b752ccd1
AM
31012+ if (locked)
31013+ si_pid_set(sb);
31014+ return locked;
31015+}
31016+
7e9cd9fe 31017+#if 0 /* reserved */
1facf9fc 31018+static inline int si_read_trylock(struct super_block *sb, int flags)
31019+{
31020+ if (au_ftest_lock(flags, FLUSH))
31021+ au_nwt_flush(&au_sbi(sb)->si_nowait);
31022+ return si_noflush_read_trylock(sb);
31023+}
e49829fe 31024+#endif
1facf9fc 31025+
b752ccd1
AM
31026+static inline void si_read_unlock(struct super_block *sb)
31027+{
31028+ si_pid_clr(sb);
31029+ __si_read_unlock(sb);
31030+}
31031+
7e9cd9fe 31032+#if 0 /* reserved */
1facf9fc 31033+static inline int si_write_trylock(struct super_block *sb, int flags)
31034+{
31035+ if (au_ftest_lock(flags, FLUSH))
31036+ au_nwt_flush(&au_sbi(sb)->si_nowait);
31037+ return si_noflush_write_trylock(sb);
31038+}
b752ccd1
AM
31039+#endif
31040+
31041+static inline void si_write_unlock(struct super_block *sb)
31042+{
31043+ si_pid_clr(sb);
31044+ __si_write_unlock(sb);
31045+}
31046+
7e9cd9fe 31047+#if 0 /* reserved */
b752ccd1
AM
31048+static inline void si_downgrade_lock(struct super_block *sb)
31049+{
31050+ __si_downgrade_lock(sb);
31051+}
31052+#endif
1facf9fc 31053+
31054+/* ---------------------------------------------------------------------- */
31055+
5afbbe0d 31056+static inline aufs_bindex_t au_sbbot(struct super_block *sb)
1facf9fc 31057+{
dece6358 31058+ SiMustAnyLock(sb);
5afbbe0d 31059+ return au_sbi(sb)->si_bbot;
1facf9fc 31060+}
31061+
31062+static inline unsigned int au_mntflags(struct super_block *sb)
31063+{
dece6358 31064+ SiMustAnyLock(sb);
1facf9fc 31065+ return au_sbi(sb)->si_mntflags;
31066+}
31067+
31068+static inline unsigned int au_sigen(struct super_block *sb)
31069+{
dece6358 31070+ SiMustAnyLock(sb);
1facf9fc 31071+ return au_sbi(sb)->si_generation;
31072+}
31073+
31074+static inline struct au_branch *au_sbr(struct super_block *sb,
31075+ aufs_bindex_t bindex)
31076+{
dece6358 31077+ SiMustAnyLock(sb);
1facf9fc 31078+ return au_sbi(sb)->si_branch[0 + bindex];
31079+}
31080+
acd2b654 31081+static inline loff_t au_xi_maxent(struct super_block *sb)
1facf9fc 31082+{
dece6358 31083+ SiMustAnyLock(sb);
acd2b654 31084+ return au_sbi(sb)->si_ximaxent;
1facf9fc 31085+}
31086+
31087+#endif /* __KERNEL__ */
31088+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
31089diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
31090--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 31091+++ linux/fs/aufs/sysaufs.c 2018-08-12 23:43:05.463458173 +0200
062440b3 31092@@ -0,0 +1,93 @@
cd7a4cd9 31093+// SPDX-License-Identifier: GPL-2.0
1facf9fc 31094+/*
b00004a5 31095+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 31096+ *
31097+ * This program, aufs is free software; you can redistribute it and/or modify
31098+ * it under the terms of the GNU General Public License as published by
31099+ * the Free Software Foundation; either version 2 of the License, or
31100+ * (at your option) any later version.
dece6358
AM
31101+ *
31102+ * This program is distributed in the hope that it will be useful,
31103+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31104+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31105+ * GNU General Public License for more details.
31106+ *
31107+ * You should have received a copy of the GNU General Public License
523b37e3 31108+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31109+ */
31110+
31111+/*
31112+ * sysfs interface and lifetime management
31113+ * they are necessary regardless sysfs is disabled.
31114+ */
31115+
1facf9fc 31116+#include <linux/random.h>
1facf9fc 31117+#include "aufs.h"
31118+
31119+unsigned long sysaufs_si_mask;
e49829fe 31120+struct kset *sysaufs_kset;
1facf9fc 31121+
31122+#define AuSiAttr(_name) { \
31123+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
31124+ .show = sysaufs_si_##_name, \
31125+}
31126+
31127+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
31128+struct attribute *sysaufs_si_attrs[] = {
31129+ &sysaufs_si_attr_xi_path.attr,
31130+ NULL,
31131+};
31132+
4a4d8108 31133+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 31134+ .show = sysaufs_si_show
31135+};
31136+
31137+static struct kobj_type au_sbi_ktype = {
31138+ .release = au_si_free,
31139+ .sysfs_ops = &au_sbi_ops,
31140+ .default_attrs = sysaufs_si_attrs
31141+};
31142+
31143+/* ---------------------------------------------------------------------- */
31144+
31145+int sysaufs_si_init(struct au_sbinfo *sbinfo)
31146+{
31147+ int err;
31148+
e49829fe 31149+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 31150+ /* cf. sysaufs_name() */
31151+ err = kobject_init_and_add
e49829fe 31152+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 31153+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
31154+
1facf9fc 31155+ return err;
31156+}
31157+
31158+void sysaufs_fin(void)
31159+{
e49829fe
JR
31160+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
31161+ kset_unregister(sysaufs_kset);
1facf9fc 31162+}
31163+
31164+int __init sysaufs_init(void)
31165+{
31166+ int err;
31167+
31168+ do {
31169+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
31170+ } while (!sysaufs_si_mask);
31171+
4a4d8108 31172+ err = -EINVAL;
e49829fe
JR
31173+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
31174+ if (unlikely(!sysaufs_kset))
4a4d8108 31175+ goto out;
e49829fe
JR
31176+ err = PTR_ERR(sysaufs_kset);
31177+ if (IS_ERR(sysaufs_kset))
1facf9fc 31178+ goto out;
e49829fe 31179+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
062440b3 31180+ if (unlikely(err))
e49829fe 31181+ kset_unregister(sysaufs_kset);
1facf9fc 31182+
4f0767ce 31183+out:
1facf9fc 31184+ return err;
31185+}
7f207e10
AM
31186diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
31187--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 31188+++ linux/fs/aufs/sysaufs.h 2018-08-12 23:43:05.463458173 +0200
062440b3
AM
31189@@ -0,0 +1,102 @@
31190+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 31191+/*
b00004a5 31192+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 31193+ *
31194+ * This program, aufs is free software; you can redistribute it and/or modify
31195+ * it under the terms of the GNU General Public License as published by
31196+ * the Free Software Foundation; either version 2 of the License, or
31197+ * (at your option) any later version.
dece6358
AM
31198+ *
31199+ * This program is distributed in the hope that it will be useful,
31200+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31201+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31202+ * GNU General Public License for more details.
31203+ *
31204+ * You should have received a copy of the GNU General Public License
523b37e3 31205+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31206+ */
31207+
31208+/*
31209+ * sysfs interface and mount lifetime management
31210+ */
31211+
31212+#ifndef __SYSAUFS_H__
31213+#define __SYSAUFS_H__
31214+
31215+#ifdef __KERNEL__
31216+
1facf9fc 31217+#include <linux/sysfs.h>
1facf9fc 31218+#include "module.h"
31219+
dece6358
AM
31220+struct super_block;
31221+struct au_sbinfo;
31222+
1facf9fc 31223+struct sysaufs_si_attr {
31224+ struct attribute attr;
31225+ int (*show)(struct seq_file *seq, struct super_block *sb);
31226+};
31227+
31228+/* ---------------------------------------------------------------------- */
31229+
31230+/* sysaufs.c */
31231+extern unsigned long sysaufs_si_mask;
e49829fe 31232+extern struct kset *sysaufs_kset;
1facf9fc 31233+extern struct attribute *sysaufs_si_attrs[];
31234+int sysaufs_si_init(struct au_sbinfo *sbinfo);
31235+int __init sysaufs_init(void);
31236+void sysaufs_fin(void);
31237+
31238+/* ---------------------------------------------------------------------- */
31239+
31240+/* some people doesn't like to show a pointer in kernel */
31241+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
31242+{
31243+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
31244+}
31245+
31246+#define SysaufsSiNamePrefix "si_"
31247+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
31248+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
31249+{
31250+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
31251+ sysaufs_si_id(sbinfo));
31252+}
31253+
31254+struct au_branch;
31255+#ifdef CONFIG_SYSFS
31256+/* sysfs.c */
31257+extern struct attribute_group *sysaufs_attr_group;
31258+
31259+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
31260+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
31261+ char *buf);
076b876e
AM
31262+long au_brinfo_ioctl(struct file *file, unsigned long arg);
31263+#ifdef CONFIG_COMPAT
31264+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
31265+#endif
1facf9fc 31266+
31267+void sysaufs_br_init(struct au_branch *br);
31268+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
31269+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
31270+
31271+#define sysaufs_brs_init() do {} while (0)
31272+
31273+#else
31274+#define sysaufs_attr_group NULL
31275+
4a4d8108 31276+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
c1595e42
JR
31277+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
31278+ struct attribute *attr, char *buf)
4a4d8108
AM
31279+AuStubVoid(sysaufs_br_init, struct au_branch *br)
31280+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
31281+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 31282+
31283+static inline void sysaufs_brs_init(void)
31284+{
31285+ sysaufs_brs = 0;
31286+}
31287+
31288+#endif /* CONFIG_SYSFS */
31289+
31290+#endif /* __KERNEL__ */
31291+#endif /* __SYSAUFS_H__ */
7f207e10
AM
31292diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
31293--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 31294+++ linux/fs/aufs/sysfs.c 2018-08-12 23:43:05.463458173 +0200
062440b3 31295@@ -0,0 +1,373 @@
cd7a4cd9 31296+// SPDX-License-Identifier: GPL-2.0
1facf9fc 31297+/*
b00004a5 31298+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 31299+ *
31300+ * This program, aufs is free software; you can redistribute it and/or modify
31301+ * it under the terms of the GNU General Public License as published by
31302+ * the Free Software Foundation; either version 2 of the License, or
31303+ * (at your option) any later version.
dece6358
AM
31304+ *
31305+ * This program is distributed in the hope that it will be useful,
31306+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31307+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31308+ * GNU General Public License for more details.
31309+ *
31310+ * You should have received a copy of the GNU General Public License
523b37e3 31311+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31312+ */
31313+
31314+/*
31315+ * sysfs interface
31316+ */
31317+
076b876e 31318+#include <linux/compat.h>
1facf9fc 31319+#include <linux/seq_file.h>
1facf9fc 31320+#include "aufs.h"
31321+
4a4d8108
AM
31322+#ifdef CONFIG_AUFS_FS_MODULE
31323+/* this entry violates the "one line per file" policy of sysfs */
31324+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
31325+ char *buf)
31326+{
31327+ ssize_t err;
31328+ static char *conf =
31329+/* this file is generated at compiling */
31330+#include "conf.str"
31331+ ;
31332+
31333+ err = snprintf(buf, PAGE_SIZE, conf);
31334+ if (unlikely(err >= PAGE_SIZE))
31335+ err = -EFBIG;
31336+ return err;
31337+}
31338+
31339+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
31340+#endif
31341+
1facf9fc 31342+static struct attribute *au_attr[] = {
4a4d8108
AM
31343+#ifdef CONFIG_AUFS_FS_MODULE
31344+ &au_config_attr.attr,
31345+#endif
1facf9fc 31346+ NULL, /* need to NULL terminate the list of attributes */
31347+};
31348+
31349+static struct attribute_group sysaufs_attr_group_body = {
31350+ .attrs = au_attr
31351+};
31352+
31353+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
31354+
31355+/* ---------------------------------------------------------------------- */
31356+
31357+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
31358+{
31359+ int err;
31360+
dece6358
AM
31361+ SiMustAnyLock(sb);
31362+
1facf9fc 31363+ err = 0;
31364+ if (au_opt_test(au_mntflags(sb), XINO)) {
31365+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
31366+ seq_putc(seq, '\n');
31367+ }
31368+ return err;
31369+}
31370+
31371+/*
31372+ * the lifetime of branch is independent from the entry under sysfs.
31373+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
31374+ * unlinked.
31375+ */
31376+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 31377+ aufs_bindex_t bindex, int idx)
1facf9fc 31378+{
1e00d052 31379+ int err;
1facf9fc 31380+ struct path path;
31381+ struct dentry *root;
31382+ struct au_branch *br;
076b876e 31383+ au_br_perm_str_t perm;
1facf9fc 31384+
31385+ AuDbg("b%d\n", bindex);
31386+
1e00d052 31387+ err = 0;
1facf9fc 31388+ root = sb->s_root;
31389+ di_read_lock_parent(root, !AuLock_IR);
31390+ br = au_sbr(sb, bindex);
392086de
AM
31391+
31392+ switch (idx) {
31393+ case AuBrSysfs_BR:
31394+ path.mnt = au_br_mnt(br);
31395+ path.dentry = au_h_dptr(root, bindex);
79b8bda9
AM
31396+ err = au_seq_path(seq, &path);
31397+ if (!err) {
31398+ au_optstr_br_perm(&perm, br->br_perm);
31399+ seq_printf(seq, "=%s\n", perm.a);
31400+ }
392086de
AM
31401+ break;
31402+ case AuBrSysfs_BRID:
79b8bda9 31403+ seq_printf(seq, "%d\n", br->br_id);
392086de
AM
31404+ break;
31405+ }
076b876e 31406+ di_read_unlock(root, !AuLock_IR);
79b8bda9 31407+ if (unlikely(err || seq_has_overflowed(seq)))
076b876e 31408+ err = -E2BIG;
392086de 31409+
1e00d052 31410+ return err;
1facf9fc 31411+}
31412+
31413+/* ---------------------------------------------------------------------- */
31414+
31415+static struct seq_file *au_seq(char *p, ssize_t len)
31416+{
31417+ struct seq_file *seq;
31418+
31419+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
31420+ if (seq) {
31421+ /* mutex_init(&seq.lock); */
31422+ seq->buf = p;
31423+ seq->size = len;
31424+ return seq; /* success */
31425+ }
31426+
31427+ seq = ERR_PTR(-ENOMEM);
31428+ return seq;
31429+}
31430+
392086de
AM
31431+#define SysaufsBr_PREFIX "br"
31432+#define SysaufsBrid_PREFIX "brid"
1facf9fc 31433+
31434+/* todo: file size may exceed PAGE_SIZE */
31435+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 31436+ char *buf)
1facf9fc 31437+{
31438+ ssize_t err;
392086de 31439+ int idx;
1facf9fc 31440+ long l;
5afbbe0d 31441+ aufs_bindex_t bbot;
1facf9fc 31442+ struct au_sbinfo *sbinfo;
31443+ struct super_block *sb;
31444+ struct seq_file *seq;
31445+ char *name;
31446+ struct attribute **cattr;
31447+
31448+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
31449+ sb = sbinfo->si_sb;
1308ab2a 31450+
31451+ /*
31452+ * prevent a race condition between sysfs and aufs.
31453+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
31454+ * prohibits maintaining the sysfs entries.
31455+ * hew we acquire read lock after sysfs_get_active_two().
31456+ * on the other hand, the remount process may maintain the sysfs/aufs
31457+ * entries after acquiring write lock.
31458+ * it can cause a deadlock.
31459+ * simply we gave up processing read here.
31460+ */
31461+ err = -EBUSY;
31462+ if (unlikely(!si_noflush_read_trylock(sb)))
31463+ goto out;
1facf9fc 31464+
31465+ seq = au_seq(buf, PAGE_SIZE);
31466+ err = PTR_ERR(seq);
31467+ if (IS_ERR(seq))
1308ab2a 31468+ goto out_unlock;
1facf9fc 31469+
31470+ name = (void *)attr->name;
31471+ cattr = sysaufs_si_attrs;
31472+ while (*cattr) {
31473+ if (!strcmp(name, (*cattr)->name)) {
31474+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
31475+ ->show(seq, sb);
31476+ goto out_seq;
31477+ }
31478+ cattr++;
31479+ }
31480+
392086de
AM
31481+ if (!strncmp(name, SysaufsBrid_PREFIX,
31482+ sizeof(SysaufsBrid_PREFIX) - 1)) {
31483+ idx = AuBrSysfs_BRID;
31484+ name += sizeof(SysaufsBrid_PREFIX) - 1;
31485+ } else if (!strncmp(name, SysaufsBr_PREFIX,
31486+ sizeof(SysaufsBr_PREFIX) - 1)) {
31487+ idx = AuBrSysfs_BR;
1facf9fc 31488+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
31489+ } else
31490+ BUG();
31491+
31492+ err = kstrtol(name, 10, &l);
31493+ if (!err) {
5afbbe0d
AM
31494+ bbot = au_sbbot(sb);
31495+ if (l <= bbot)
392086de
AM
31496+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
31497+ else
31498+ err = -ENOENT;
1facf9fc 31499+ }
1facf9fc 31500+
4f0767ce 31501+out_seq:
1facf9fc 31502+ if (!err) {
31503+ err = seq->count;
31504+ /* sysfs limit */
31505+ if (unlikely(err == PAGE_SIZE))
31506+ err = -EFBIG;
31507+ }
1c60b727 31508+ kfree(seq);
4f0767ce 31509+out_unlock:
1facf9fc 31510+ si_read_unlock(sb);
4f0767ce 31511+out:
1facf9fc 31512+ return err;
31513+}
31514+
31515+/* ---------------------------------------------------------------------- */
31516+
076b876e
AM
31517+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
31518+{
31519+ int err;
31520+ int16_t brid;
5afbbe0d 31521+ aufs_bindex_t bindex, bbot;
076b876e
AM
31522+ size_t sz;
31523+ char *buf;
31524+ struct seq_file *seq;
31525+ struct au_branch *br;
31526+
31527+ si_read_lock(sb, AuLock_FLUSH);
5afbbe0d
AM
31528+ bbot = au_sbbot(sb);
31529+ err = bbot + 1;
076b876e
AM
31530+ if (!arg)
31531+ goto out;
31532+
31533+ err = -ENOMEM;
31534+ buf = (void *)__get_free_page(GFP_NOFS);
31535+ if (unlikely(!buf))
31536+ goto out;
31537+
31538+ seq = au_seq(buf, PAGE_SIZE);
31539+ err = PTR_ERR(seq);
31540+ if (IS_ERR(seq))
31541+ goto out_buf;
31542+
31543+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
5afbbe0d 31544+ for (bindex = 0; bindex <= bbot; bindex++, arg++) {
076b876e
AM
31545+ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg));
31546+ if (unlikely(err))
31547+ break;
31548+
31549+ br = au_sbr(sb, bindex);
31550+ brid = br->br_id;
31551+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
31552+ err = __put_user(brid, &arg->id);
31553+ if (unlikely(err))
31554+ break;
31555+
31556+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
31557+ err = __put_user(br->br_perm, &arg->perm);
31558+ if (unlikely(err))
31559+ break;
31560+
79b8bda9
AM
31561+ err = au_seq_path(seq, &br->br_path);
31562+ if (unlikely(err))
31563+ break;
31564+ seq_putc(seq, '\0');
31565+ if (!seq_has_overflowed(seq)) {
076b876e
AM
31566+ err = copy_to_user(arg->path, seq->buf, seq->count);
31567+ seq->count = 0;
31568+ if (unlikely(err))
31569+ break;
31570+ } else {
31571+ err = -E2BIG;
31572+ goto out_seq;
31573+ }
31574+ }
31575+ if (unlikely(err))
31576+ err = -EFAULT;
31577+
31578+out_seq:
1c60b727 31579+ kfree(seq);
076b876e 31580+out_buf:
1c60b727 31581+ free_page((unsigned long)buf);
076b876e
AM
31582+out:
31583+ si_read_unlock(sb);
31584+ return err;
31585+}
31586+
31587+long au_brinfo_ioctl(struct file *file, unsigned long arg)
31588+{
2000de60 31589+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg);
076b876e
AM
31590+}
31591+
31592+#ifdef CONFIG_COMPAT
31593+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
31594+{
2000de60 31595+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg));
076b876e
AM
31596+}
31597+#endif
31598+
31599+/* ---------------------------------------------------------------------- */
31600+
1facf9fc 31601+void sysaufs_br_init(struct au_branch *br)
31602+{
392086de
AM
31603+ int i;
31604+ struct au_brsysfs *br_sysfs;
31605+ struct attribute *attr;
4a4d8108 31606+
392086de
AM
31607+ br_sysfs = br->br_sysfs;
31608+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31609+ attr = &br_sysfs->attr;
31610+ sysfs_attr_init(attr);
31611+ attr->name = br_sysfs->name;
cd7a4cd9 31612+ attr->mode = 0444;
392086de
AM
31613+ br_sysfs++;
31614+ }
1facf9fc 31615+}
31616+
31617+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
31618+{
31619+ struct au_branch *br;
31620+ struct kobject *kobj;
392086de
AM
31621+ struct au_brsysfs *br_sysfs;
31622+ int i;
5afbbe0d 31623+ aufs_bindex_t bbot;
1facf9fc 31624+
1facf9fc 31625+ if (!sysaufs_brs)
31626+ return;
31627+
31628+ kobj = &au_sbi(sb)->si_kobj;
5afbbe0d
AM
31629+ bbot = au_sbbot(sb);
31630+ for (; bindex <= bbot; bindex++) {
1facf9fc 31631+ br = au_sbr(sb, bindex);
392086de
AM
31632+ br_sysfs = br->br_sysfs;
31633+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31634+ sysfs_remove_file(kobj, &br_sysfs->attr);
31635+ br_sysfs++;
31636+ }
1facf9fc 31637+ }
31638+}
31639+
31640+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
31641+{
392086de 31642+ int err, i;
5afbbe0d 31643+ aufs_bindex_t bbot;
1facf9fc 31644+ struct kobject *kobj;
31645+ struct au_branch *br;
392086de 31646+ struct au_brsysfs *br_sysfs;
1facf9fc 31647+
1facf9fc 31648+ if (!sysaufs_brs)
31649+ return;
31650+
31651+ kobj = &au_sbi(sb)->si_kobj;
5afbbe0d
AM
31652+ bbot = au_sbbot(sb);
31653+ for (; bindex <= bbot; bindex++) {
1facf9fc 31654+ br = au_sbr(sb, bindex);
392086de
AM
31655+ br_sysfs = br->br_sysfs;
31656+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
31657+ SysaufsBr_PREFIX "%d", bindex);
31658+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
31659+ SysaufsBrid_PREFIX "%d", bindex);
31660+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
31661+ err = sysfs_create_file(kobj, &br_sysfs->attr);
31662+ if (unlikely(err))
31663+ pr_warn("failed %s under sysfs(%d)\n",
31664+ br_sysfs->name, err);
31665+ br_sysfs++;
31666+ }
1facf9fc 31667+ }
31668+}
7f207e10
AM
31669diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
31670--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 31671+++ linux/fs/aufs/sysrq.c 2018-10-23 12:33:35.599375796 +0200
062440b3 31672@@ -0,0 +1,160 @@
cd7a4cd9 31673+// SPDX-License-Identifier: GPL-2.0
1facf9fc 31674+/*
b00004a5 31675+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 31676+ *
31677+ * This program, aufs is free software; you can redistribute it and/or modify
31678+ * it under the terms of the GNU General Public License as published by
31679+ * the Free Software Foundation; either version 2 of the License, or
31680+ * (at your option) any later version.
dece6358
AM
31681+ *
31682+ * This program is distributed in the hope that it will be useful,
31683+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31684+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31685+ * GNU General Public License for more details.
31686+ *
31687+ * You should have received a copy of the GNU General Public License
523b37e3 31688+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31689+ */
31690+
31691+/*
acd2b654 31692+ * magic sysrq handler
1facf9fc 31693+ */
31694+
1facf9fc 31695+/* #include <linux/sysrq.h> */
027c5e7a 31696+#include <linux/writeback.h>
1facf9fc 31697+#include "aufs.h"
31698+
31699+/* ---------------------------------------------------------------------- */
31700+
31701+static void sysrq_sb(struct super_block *sb)
31702+{
31703+ char *plevel;
31704+ struct au_sbinfo *sbinfo;
31705+ struct file *file;
8b6a4947
AM
31706+ struct hlist_bl_head *files;
31707+ struct hlist_bl_node *pos;
523b37e3 31708+ struct au_finfo *finfo;
1facf9fc 31709+
31710+ plevel = au_plevel;
31711+ au_plevel = KERN_WARNING;
1facf9fc 31712+
4a4d8108 31713+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
31714+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
31715+
31716+ sbinfo = au_sbi(sb);
4a4d8108 31717+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 31718+ pr("superblock\n");
1facf9fc 31719+ au_dpri_sb(sb);
027c5e7a
AM
31720+
31721+#if 0
c06a8ce3 31722+ pr("root dentry\n");
1facf9fc 31723+ au_dpri_dentry(sb->s_root);
c06a8ce3 31724+ pr("root inode\n");
5527c038 31725+ au_dpri_inode(d_inode(sb->s_root));
027c5e7a
AM
31726+#endif
31727+
1facf9fc 31728+#if 0
027c5e7a
AM
31729+ do {
31730+ int err, i, j, ndentry;
31731+ struct au_dcsub_pages dpages;
31732+ struct au_dpage *dpage;
31733+
31734+ err = au_dpages_init(&dpages, GFP_ATOMIC);
31735+ if (unlikely(err))
31736+ break;
31737+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
31738+ if (!err)
31739+ for (i = 0; i < dpages.ndpage; i++) {
31740+ dpage = dpages.dpages + i;
31741+ ndentry = dpage->ndentry;
31742+ for (j = 0; j < ndentry; j++)
31743+ au_dpri_dentry(dpage->dentries[j]);
31744+ }
31745+ au_dpages_free(&dpages);
31746+ } while (0);
31747+#endif
31748+
31749+#if 1
31750+ {
31751+ struct inode *i;
076b876e 31752+
c06a8ce3 31753+ pr("isolated inode\n");
79b8bda9 31754+ spin_lock(&sb->s_inode_list_lock);
2cbb1c4b
JR
31755+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
31756+ spin_lock(&i->i_lock);
b4510431 31757+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 31758+ au_dpri_inode(i);
2cbb1c4b
JR
31759+ spin_unlock(&i->i_lock);
31760+ }
79b8bda9 31761+ spin_unlock(&sb->s_inode_list_lock);
027c5e7a 31762+ }
1facf9fc 31763+#endif
c06a8ce3 31764+ pr("files\n");
523b37e3 31765+ files = &au_sbi(sb)->si_files;
8b6a4947
AM
31766+ hlist_bl_lock(files);
31767+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) {
4a4d8108 31768+ umode_t mode;
076b876e 31769+
523b37e3 31770+ file = finfo->fi_file;
c06a8ce3 31771+ mode = file_inode(file)->i_mode;
38d290e6 31772+ if (!special_file(mode))
1facf9fc 31773+ au_dpri_file(file);
523b37e3 31774+ }
8b6a4947 31775+ hlist_bl_unlock(files);
c06a8ce3 31776+ pr("done\n");
1facf9fc 31777+
c06a8ce3 31778+#undef pr
1facf9fc 31779+ au_plevel = plevel;
1facf9fc 31780+}
31781+
31782+/* ---------------------------------------------------------------------- */
31783+
31784+/* module parameter */
31785+static char *aufs_sysrq_key = "a";
cd7a4cd9 31786+module_param_named(sysrq, aufs_sysrq_key, charp, 0444);
1facf9fc 31787+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
31788+
0c5527e5 31789+static void au_sysrq(int key __maybe_unused)
1facf9fc 31790+{
1facf9fc 31791+ struct au_sbinfo *sbinfo;
8b6a4947 31792+ struct hlist_bl_node *pos;
1facf9fc 31793+
027c5e7a 31794+ lockdep_off();
53392da6 31795+ au_sbilist_lock();
8b6a4947 31796+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list)
1facf9fc 31797+ sysrq_sb(sbinfo->si_sb);
53392da6 31798+ au_sbilist_unlock();
027c5e7a 31799+ lockdep_on();
1facf9fc 31800+}
31801+
31802+static struct sysrq_key_op au_sysrq_op = {
31803+ .handler = au_sysrq,
31804+ .help_msg = "Aufs",
31805+ .action_msg = "Aufs",
31806+ .enable_mask = SYSRQ_ENABLE_DUMP
31807+};
31808+
31809+/* ---------------------------------------------------------------------- */
31810+
31811+int __init au_sysrq_init(void)
31812+{
31813+ int err;
31814+ char key;
31815+
31816+ err = -1;
31817+ key = *aufs_sysrq_key;
31818+ if ('a' <= key && key <= 'z')
31819+ err = register_sysrq_key(key, &au_sysrq_op);
31820+ if (unlikely(err))
4a4d8108 31821+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 31822+ return err;
31823+}
31824+
31825+void au_sysrq_fin(void)
31826+{
31827+ int err;
076b876e 31828+
1facf9fc 31829+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
31830+ if (unlikely(err))
4a4d8108 31831+ pr_err("err %d (ignored)\n", err);
1facf9fc 31832+}
7f207e10
AM
31833diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
31834--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
31835+++ linux/fs/aufs/vdir.c 2018-10-23 12:33:35.599375796 +0200
31836@@ -0,0 +1,895 @@
cd7a4cd9 31837+// SPDX-License-Identifier: GPL-2.0
1facf9fc 31838+/*
b00004a5 31839+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 31840+ *
31841+ * This program, aufs is free software; you can redistribute it and/or modify
31842+ * it under the terms of the GNU General Public License as published by
31843+ * the Free Software Foundation; either version 2 of the License, or
31844+ * (at your option) any later version.
dece6358
AM
31845+ *
31846+ * This program is distributed in the hope that it will be useful,
31847+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31848+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31849+ * GNU General Public License for more details.
31850+ *
31851+ * You should have received a copy of the GNU General Public License
523b37e3 31852+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31853+ */
31854+
31855+/*
31856+ * virtual or vertical directory
31857+ */
31858+
31859+#include "aufs.h"
31860+
dece6358 31861+static unsigned int calc_size(int nlen)
1facf9fc 31862+{
dece6358 31863+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 31864+}
31865+
31866+static int set_deblk_end(union au_vdir_deblk_p *p,
31867+ union au_vdir_deblk_p *deblk_end)
31868+{
31869+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
31870+ p->de->de_str.len = 0;
31871+ /* smp_mb(); */
31872+ return 0;
31873+ }
31874+ return -1; /* error */
31875+}
31876+
31877+/* returns true or false */
31878+static int is_deblk_end(union au_vdir_deblk_p *p,
31879+ union au_vdir_deblk_p *deblk_end)
31880+{
31881+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
31882+ return !p->de->de_str.len;
31883+ return 1;
31884+}
31885+
31886+static unsigned char *last_deblk(struct au_vdir *vdir)
31887+{
31888+ return vdir->vd_deblk[vdir->vd_nblk - 1];
31889+}
31890+
31891+/* ---------------------------------------------------------------------- */
31892+
79b8bda9 31893+/* estimate the appropriate size for name hash table */
1308ab2a 31894+unsigned int au_rdhash_est(loff_t sz)
31895+{
31896+ unsigned int n;
31897+
31898+ n = UINT_MAX;
31899+ sz >>= 10;
31900+ if (sz < n)
31901+ n = sz;
31902+ if (sz < AUFS_RDHASH_DEF)
31903+ n = AUFS_RDHASH_DEF;
4a4d8108 31904+ /* pr_info("n %u\n", n); */
1308ab2a 31905+ return n;
31906+}
31907+
1facf9fc 31908+/*
31909+ * the allocated memory has to be freed by
dece6358 31910+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 31911+ */
dece6358 31912+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 31913+{
1facf9fc 31914+ struct hlist_head *head;
dece6358 31915+ unsigned int u;
076b876e 31916+ size_t sz;
1facf9fc 31917+
076b876e
AM
31918+ sz = sizeof(*nhash->nh_head) * num_hash;
31919+ head = kmalloc(sz, gfp);
dece6358
AM
31920+ if (head) {
31921+ nhash->nh_num = num_hash;
31922+ nhash->nh_head = head;
31923+ for (u = 0; u < num_hash; u++)
1facf9fc 31924+ INIT_HLIST_HEAD(head++);
dece6358 31925+ return 0; /* success */
1facf9fc 31926+ }
1facf9fc 31927+
dece6358 31928+ return -ENOMEM;
1facf9fc 31929+}
31930+
dece6358
AM
31931+static void nhash_count(struct hlist_head *head)
31932+{
31933+#if 0
31934+ unsigned long n;
31935+ struct hlist_node *pos;
31936+
31937+ n = 0;
31938+ hlist_for_each(pos, head)
31939+ n++;
4a4d8108 31940+ pr_info("%lu\n", n);
dece6358
AM
31941+#endif
31942+}
31943+
31944+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 31945+{
c06a8ce3
AM
31946+ struct au_vdir_wh *pos;
31947+ struct hlist_node *node;
1facf9fc 31948+
c06a8ce3 31949+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
1c60b727 31950+ kfree(pos);
1facf9fc 31951+}
31952+
dece6358 31953+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 31954+{
c06a8ce3
AM
31955+ struct au_vdir_dehstr *pos;
31956+ struct hlist_node *node;
1facf9fc 31957+
c06a8ce3 31958+ hlist_for_each_entry_safe(pos, node, head, hash)
1c60b727 31959+ au_cache_free_vdir_dehstr(pos);
1facf9fc 31960+}
31961+
dece6358
AM
31962+static void au_nhash_do_free(struct au_nhash *nhash,
31963+ void (*free)(struct hlist_head *head))
1facf9fc 31964+{
1308ab2a 31965+ unsigned int n;
1facf9fc 31966+ struct hlist_head *head;
1facf9fc 31967+
dece6358 31968+ n = nhash->nh_num;
1308ab2a 31969+ if (!n)
31970+ return;
31971+
dece6358 31972+ head = nhash->nh_head;
1308ab2a 31973+ while (n-- > 0) {
dece6358
AM
31974+ nhash_count(head);
31975+ free(head++);
1facf9fc 31976+ }
1c60b727 31977+ kfree(nhash->nh_head);
1facf9fc 31978+}
31979+
dece6358 31980+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 31981+{
dece6358
AM
31982+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
31983+}
1facf9fc 31984+
dece6358
AM
31985+static void au_nhash_de_free(struct au_nhash *delist)
31986+{
31987+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 31988+}
31989+
31990+/* ---------------------------------------------------------------------- */
31991+
31992+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
31993+ int limit)
31994+{
31995+ int num;
31996+ unsigned int u, n;
31997+ struct hlist_head *head;
c06a8ce3 31998+ struct au_vdir_wh *pos;
1facf9fc 31999+
32000+ num = 0;
32001+ n = whlist->nh_num;
32002+ head = whlist->nh_head;
1308ab2a 32003+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
32004+ hlist_for_each_entry(pos, head, wh_hash)
32005+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 32006+ return 1;
1facf9fc 32007+ return 0;
32008+}
32009+
32010+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 32011+ unsigned char *name,
1facf9fc 32012+ unsigned int len)
32013+{
dece6358
AM
32014+ unsigned int v;
32015+ /* const unsigned int magic_bit = 12; */
32016+
1308ab2a 32017+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
32018+
dece6358 32019+ v = 0;
f0c0a007
AM
32020+ if (len > 8)
32021+ len = 8;
dece6358
AM
32022+ while (len--)
32023+ v += *name++;
32024+ /* v = hash_long(v, magic_bit); */
32025+ v %= nhash->nh_num;
32026+ return nhash->nh_head + v;
32027+}
32028+
32029+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
32030+ int nlen)
32031+{
32032+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 32033+}
32034+
32035+/* returns found or not */
dece6358 32036+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 32037+{
32038+ struct hlist_head *head;
c06a8ce3 32039+ struct au_vdir_wh *pos;
1facf9fc 32040+ struct au_vdir_destr *str;
32041+
dece6358 32042+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
32043+ hlist_for_each_entry(pos, head, wh_hash) {
32044+ str = &pos->wh_str;
1facf9fc 32045+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
32046+ if (au_nhash_test_name(str, name, nlen))
32047+ return 1;
32048+ }
32049+ return 0;
32050+}
32051+
32052+/* returns found(true) or not */
32053+static int test_known(struct au_nhash *delist, char *name, int nlen)
32054+{
32055+ struct hlist_head *head;
c06a8ce3 32056+ struct au_vdir_dehstr *pos;
dece6358
AM
32057+ struct au_vdir_destr *str;
32058+
32059+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
32060+ hlist_for_each_entry(pos, head, hash) {
32061+ str = pos->str;
dece6358
AM
32062+ AuDbg("%.*s\n", str->len, str->name);
32063+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 32064+ return 1;
32065+ }
32066+ return 0;
32067+}
32068+
dece6358
AM
32069+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
32070+ unsigned char d_type)
32071+{
32072+#ifdef CONFIG_AUFS_SHWH
32073+ wh->wh_ino = ino;
32074+ wh->wh_type = d_type;
32075+#endif
32076+}
32077+
32078+/* ---------------------------------------------------------------------- */
32079+
32080+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
32081+ unsigned int d_type, aufs_bindex_t bindex,
32082+ unsigned char shwh)
1facf9fc 32083+{
32084+ int err;
32085+ struct au_vdir_destr *str;
32086+ struct au_vdir_wh *wh;
32087+
dece6358 32088+ AuDbg("%.*s\n", nlen, name);
1308ab2a 32089+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
32090+
1facf9fc 32091+ err = -ENOMEM;
dece6358 32092+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 32093+ if (unlikely(!wh))
32094+ goto out;
32095+
32096+ err = 0;
32097+ wh->wh_bindex = bindex;
dece6358
AM
32098+ if (shwh)
32099+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 32100+ str = &wh->wh_str;
dece6358
AM
32101+ str->len = nlen;
32102+ memcpy(str->name, name, nlen);
32103+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 32104+ /* smp_mb(); */
32105+
4f0767ce 32106+out:
1facf9fc 32107+ return err;
32108+}
32109+
1facf9fc 32110+static int append_deblk(struct au_vdir *vdir)
32111+{
32112+ int err;
dece6358 32113+ unsigned long ul;
1facf9fc 32114+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
32115+ union au_vdir_deblk_p p, deblk_end;
32116+ unsigned char **o;
32117+
32118+ err = -ENOMEM;
e2f27e51
AM
32119+ o = au_krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
32120+ GFP_NOFS, /*may_shrink*/0);
1facf9fc 32121+ if (unlikely(!o))
32122+ goto out;
32123+
32124+ vdir->vd_deblk = o;
32125+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
32126+ if (p.deblk) {
32127+ ul = vdir->vd_nblk++;
32128+ vdir->vd_deblk[ul] = p.deblk;
32129+ vdir->vd_last.ul = ul;
32130+ vdir->vd_last.p.deblk = p.deblk;
32131+ deblk_end.deblk = p.deblk + deblk_sz;
32132+ err = set_deblk_end(&p, &deblk_end);
32133+ }
32134+
4f0767ce 32135+out:
1facf9fc 32136+ return err;
32137+}
32138+
dece6358
AM
32139+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
32140+ unsigned int d_type, struct au_nhash *delist)
32141+{
32142+ int err;
32143+ unsigned int sz;
32144+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
32145+ union au_vdir_deblk_p p, *room, deblk_end;
32146+ struct au_vdir_dehstr *dehstr;
32147+
32148+ p.deblk = last_deblk(vdir);
32149+ deblk_end.deblk = p.deblk + deblk_sz;
32150+ room = &vdir->vd_last.p;
32151+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
32152+ || !is_deblk_end(room, &deblk_end));
32153+
32154+ sz = calc_size(nlen);
32155+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
32156+ err = append_deblk(vdir);
32157+ if (unlikely(err))
32158+ goto out;
32159+
32160+ p.deblk = last_deblk(vdir);
32161+ deblk_end.deblk = p.deblk + deblk_sz;
32162+ /* smp_mb(); */
32163+ AuDebugOn(room->deblk != p.deblk);
32164+ }
32165+
32166+ err = -ENOMEM;
4a4d8108 32167+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
32168+ if (unlikely(!dehstr))
32169+ goto out;
32170+
32171+ dehstr->str = &room->de->de_str;
32172+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
32173+ room->de->de_ino = ino;
32174+ room->de->de_type = d_type;
32175+ room->de->de_str.len = nlen;
32176+ memcpy(room->de->de_str.name, name, nlen);
32177+
32178+ err = 0;
32179+ room->deblk += sz;
32180+ if (unlikely(set_deblk_end(room, &deblk_end)))
32181+ err = append_deblk(vdir);
32182+ /* smp_mb(); */
32183+
4f0767ce 32184+out:
dece6358
AM
32185+ return err;
32186+}
32187+
32188+/* ---------------------------------------------------------------------- */
32189+
1c60b727 32190+void au_vdir_free(struct au_vdir *vdir)
dece6358
AM
32191+{
32192+ unsigned char **deblk;
32193+
32194+ deblk = vdir->vd_deblk;
1c60b727
AM
32195+ while (vdir->vd_nblk--)
32196+ kfree(*deblk++);
32197+ kfree(vdir->vd_deblk);
32198+ au_cache_free_vdir(vdir);
dece6358
AM
32199+}
32200+
1308ab2a 32201+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 32202+{
32203+ struct au_vdir *vdir;
1308ab2a 32204+ struct super_block *sb;
1facf9fc 32205+ int err;
32206+
2000de60 32207+ sb = file->f_path.dentry->d_sb;
dece6358
AM
32208+ SiMustAnyLock(sb);
32209+
1facf9fc 32210+ err = -ENOMEM;
32211+ vdir = au_cache_alloc_vdir();
32212+ if (unlikely(!vdir))
32213+ goto out;
32214+
32215+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
32216+ if (unlikely(!vdir->vd_deblk))
32217+ goto out_free;
32218+
32219+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 32220+ if (!vdir->vd_deblk_sz) {
79b8bda9 32221+ /* estimate the appropriate size for deblk */
1308ab2a 32222+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 32223+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 32224+ }
1facf9fc 32225+ vdir->vd_nblk = 0;
32226+ vdir->vd_version = 0;
32227+ vdir->vd_jiffy = 0;
32228+ err = append_deblk(vdir);
32229+ if (!err)
32230+ return vdir; /* success */
32231+
1c60b727 32232+ kfree(vdir->vd_deblk);
1facf9fc 32233+
4f0767ce 32234+out_free:
1c60b727 32235+ au_cache_free_vdir(vdir);
4f0767ce 32236+out:
1facf9fc 32237+ vdir = ERR_PTR(err);
32238+ return vdir;
32239+}
32240+
32241+static int reinit_vdir(struct au_vdir *vdir)
32242+{
32243+ int err;
32244+ union au_vdir_deblk_p p, deblk_end;
32245+
32246+ while (vdir->vd_nblk > 1) {
1c60b727 32247+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
1facf9fc 32248+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
32249+ vdir->vd_nblk--;
32250+ }
32251+ p.deblk = vdir->vd_deblk[0];
32252+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
32253+ err = set_deblk_end(&p, &deblk_end);
32254+ /* keep vd_dblk_sz */
32255+ vdir->vd_last.ul = 0;
32256+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
32257+ vdir->vd_version = 0;
32258+ vdir->vd_jiffy = 0;
32259+ /* smp_mb(); */
32260+ return err;
32261+}
32262+
32263+/* ---------------------------------------------------------------------- */
32264+
1facf9fc 32265+#define AuFillVdir_CALLED 1
32266+#define AuFillVdir_WHABLE (1 << 1)
dece6358 32267+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 32268+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
32269+#define au_fset_fillvdir(flags, name) \
32270+ do { (flags) |= AuFillVdir_##name; } while (0)
32271+#define au_fclr_fillvdir(flags, name) \
32272+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 32273+
dece6358
AM
32274+#ifndef CONFIG_AUFS_SHWH
32275+#undef AuFillVdir_SHWH
32276+#define AuFillVdir_SHWH 0
32277+#endif
32278+
1facf9fc 32279+struct fillvdir_arg {
392086de 32280+ struct dir_context ctx;
1facf9fc 32281+ struct file *file;
32282+ struct au_vdir *vdir;
dece6358
AM
32283+ struct au_nhash delist;
32284+ struct au_nhash whlist;
1facf9fc 32285+ aufs_bindex_t bindex;
32286+ unsigned int flags;
32287+ int err;
32288+};
32289+
392086de 32290+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 32291+ loff_t offset __maybe_unused, u64 h_ino,
32292+ unsigned int d_type)
32293+{
392086de 32294+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 32295+ char *name = (void *)__name;
32296+ struct super_block *sb;
1facf9fc 32297+ ino_t ino;
dece6358 32298+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 32299+
1facf9fc 32300+ arg->err = 0;
2000de60 32301+ sb = arg->file->f_path.dentry->d_sb;
1facf9fc 32302+ au_fset_fillvdir(arg->flags, CALLED);
32303+ /* smp_mb(); */
dece6358 32304+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 32305+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
32306+ if (test_known(&arg->delist, name, nlen)
32307+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
32308+ goto out; /* already exists or whiteouted */
1facf9fc 32309+
dece6358 32310+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
32311+ if (!arg->err) {
32312+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
32313+ d_type = DT_UNKNOWN;
dece6358
AM
32314+ arg->err = append_de(arg->vdir, name, nlen, ino,
32315+ d_type, &arg->delist);
4a4d8108 32316+ }
1facf9fc 32317+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
32318+ name += AUFS_WH_PFX_LEN;
dece6358
AM
32319+ nlen -= AUFS_WH_PFX_LEN;
32320+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
32321+ goto out; /* already whiteouted */
1facf9fc 32322+
acd2b654 32323+ ino = 0; /* just to suppress a warning */
dece6358
AM
32324+ if (shwh)
32325+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
32326+ &ino);
4a4d8108
AM
32327+ if (!arg->err) {
32328+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
32329+ d_type = DT_UNKNOWN;
1facf9fc 32330+ arg->err = au_nhash_append_wh
dece6358
AM
32331+ (&arg->whlist, name, nlen, ino, d_type,
32332+ arg->bindex, shwh);
4a4d8108 32333+ }
1facf9fc 32334+ }
32335+
4f0767ce 32336+out:
1facf9fc 32337+ if (!arg->err)
32338+ arg->vdir->vd_jiffy = jiffies;
32339+ /* smp_mb(); */
32340+ AuTraceErr(arg->err);
32341+ return arg->err;
32342+}
32343+
dece6358
AM
32344+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
32345+ struct au_nhash *whlist, struct au_nhash *delist)
32346+{
32347+#ifdef CONFIG_AUFS_SHWH
32348+ int err;
32349+ unsigned int nh, u;
32350+ struct hlist_head *head;
c06a8ce3
AM
32351+ struct au_vdir_wh *pos;
32352+ struct hlist_node *n;
dece6358
AM
32353+ char *p, *o;
32354+ struct au_vdir_destr *destr;
32355+
32356+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
32357+
32358+ err = -ENOMEM;
537831f9 32359+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
32360+ if (unlikely(!p))
32361+ goto out;
32362+
32363+ err = 0;
32364+ nh = whlist->nh_num;
32365+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
32366+ p += AUFS_WH_PFX_LEN;
32367+ for (u = 0; u < nh; u++) {
32368+ head = whlist->nh_head + u;
c06a8ce3
AM
32369+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
32370+ destr = &pos->wh_str;
dece6358
AM
32371+ memcpy(p, destr->name, destr->len);
32372+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 32373+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
32374+ if (unlikely(err))
32375+ break;
32376+ }
32377+ }
32378+
1c60b727 32379+ free_page((unsigned long)o);
dece6358 32380+
4f0767ce 32381+out:
dece6358
AM
32382+ AuTraceErr(err);
32383+ return err;
32384+#else
32385+ return 0;
32386+#endif
32387+}
32388+
1facf9fc 32389+static int au_do_read_vdir(struct fillvdir_arg *arg)
32390+{
32391+ int err;
dece6358 32392+ unsigned int rdhash;
1facf9fc 32393+ loff_t offset;
5afbbe0d 32394+ aufs_bindex_t bbot, bindex, btop;
dece6358 32395+ unsigned char shwh;
1facf9fc 32396+ struct file *hf, *file;
32397+ struct super_block *sb;
32398+
1facf9fc 32399+ file = arg->file;
2000de60 32400+ sb = file->f_path.dentry->d_sb;
dece6358
AM
32401+ SiMustAnyLock(sb);
32402+
32403+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 32404+ if (!rdhash)
32405+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
32406+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
32407+ if (unlikely(err))
1facf9fc 32408+ goto out;
dece6358
AM
32409+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
32410+ if (unlikely(err))
1facf9fc 32411+ goto out_delist;
32412+
32413+ err = 0;
32414+ arg->flags = 0;
dece6358
AM
32415+ shwh = 0;
32416+ if (au_opt_test(au_mntflags(sb), SHWH)) {
32417+ shwh = 1;
32418+ au_fset_fillvdir(arg->flags, SHWH);
32419+ }
5afbbe0d
AM
32420+ btop = au_fbtop(file);
32421+ bbot = au_fbbot_dir(file);
32422+ for (bindex = btop; !err && bindex <= bbot; bindex++) {
4a4d8108 32423+ hf = au_hf_dir(file, bindex);
1facf9fc 32424+ if (!hf)
32425+ continue;
32426+
32427+ offset = vfsub_llseek(hf, 0, SEEK_SET);
32428+ err = offset;
32429+ if (unlikely(offset))
32430+ break;
32431+
32432+ arg->bindex = bindex;
32433+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358 32434+ if (shwh
5afbbe0d 32435+ || (bindex != bbot
dece6358 32436+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 32437+ au_fset_fillvdir(arg->flags, WHABLE);
32438+ do {
32439+ arg->err = 0;
32440+ au_fclr_fillvdir(arg->flags, CALLED);
32441+ /* smp_mb(); */
392086de 32442+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 32443+ if (err >= 0)
32444+ err = arg->err;
32445+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
32446+
32447+ /*
32448+ * dir_relax() may be good for concurrency, but aufs should not
32449+ * use it since it will cause a lockdep problem.
32450+ */
1facf9fc 32451+ }
dece6358
AM
32452+
32453+ if (!err && shwh)
32454+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
32455+
32456+ au_nhash_wh_free(&arg->whlist);
1facf9fc 32457+
4f0767ce 32458+out_delist:
dece6358 32459+ au_nhash_de_free(&arg->delist);
4f0767ce 32460+out:
1facf9fc 32461+ return err;
32462+}
32463+
32464+static int read_vdir(struct file *file, int may_read)
32465+{
32466+ int err;
32467+ unsigned long expire;
32468+ unsigned char do_read;
392086de
AM
32469+ struct fillvdir_arg arg = {
32470+ .ctx = {
2000de60 32471+ .actor = fillvdir
392086de
AM
32472+ }
32473+ };
1facf9fc 32474+ struct inode *inode;
32475+ struct au_vdir *vdir, *allocated;
32476+
32477+ err = 0;
c06a8ce3 32478+ inode = file_inode(file);
1facf9fc 32479+ IMustLock(inode);
5afbbe0d 32480+ IiMustWriteLock(inode);
dece6358
AM
32481+ SiMustAnyLock(inode->i_sb);
32482+
1facf9fc 32483+ allocated = NULL;
32484+ do_read = 0;
32485+ expire = au_sbi(inode->i_sb)->si_rdcache;
32486+ vdir = au_ivdir(inode);
32487+ if (!vdir) {
32488+ do_read = 1;
1308ab2a 32489+ vdir = alloc_vdir(file);
1facf9fc 32490+ err = PTR_ERR(vdir);
32491+ if (IS_ERR(vdir))
32492+ goto out;
32493+ err = 0;
32494+ allocated = vdir;
32495+ } else if (may_read
be118d29 32496+ && (!inode_eq_iversion(inode, vdir->vd_version)
1facf9fc 32497+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
32498+ do_read = 1;
32499+ err = reinit_vdir(vdir);
32500+ if (unlikely(err))
32501+ goto out;
32502+ }
32503+
32504+ if (!do_read)
32505+ return 0; /* success */
32506+
32507+ arg.file = file;
32508+ arg.vdir = vdir;
32509+ err = au_do_read_vdir(&arg);
32510+ if (!err) {
392086de 32511+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
be118d29 32512+ vdir->vd_version = inode_query_iversion(inode);
1facf9fc 32513+ vdir->vd_last.ul = 0;
32514+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
32515+ if (allocated)
32516+ au_set_ivdir(inode, allocated);
32517+ } else if (allocated)
1c60b727 32518+ au_vdir_free(allocated);
1facf9fc 32519+
4f0767ce 32520+out:
1facf9fc 32521+ return err;
32522+}
32523+
32524+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
32525+{
32526+ int err, rerr;
32527+ unsigned long ul, n;
32528+ const unsigned int deblk_sz = src->vd_deblk_sz;
32529+
32530+ AuDebugOn(tgt->vd_nblk != 1);
32531+
32532+ err = -ENOMEM;
32533+ if (tgt->vd_nblk < src->vd_nblk) {
32534+ unsigned char **p;
32535+
e2f27e51
AM
32536+ p = au_krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
32537+ GFP_NOFS, /*may_shrink*/0);
1facf9fc 32538+ if (unlikely(!p))
32539+ goto out;
32540+ tgt->vd_deblk = p;
32541+ }
32542+
1308ab2a 32543+ if (tgt->vd_deblk_sz != deblk_sz) {
32544+ unsigned char *p;
32545+
32546+ tgt->vd_deblk_sz = deblk_sz;
e2f27e51
AM
32547+ p = au_krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS,
32548+ /*may_shrink*/1);
1308ab2a 32549+ if (unlikely(!p))
32550+ goto out;
32551+ tgt->vd_deblk[0] = p;
32552+ }
1facf9fc 32553+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 32554+ tgt->vd_version = src->vd_version;
32555+ tgt->vd_jiffy = src->vd_jiffy;
32556+
32557+ n = src->vd_nblk;
32558+ for (ul = 1; ul < n; ul++) {
dece6358
AM
32559+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
32560+ GFP_NOFS);
32561+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 32562+ goto out;
1308ab2a 32563+ tgt->vd_nblk++;
1facf9fc 32564+ }
1308ab2a 32565+ tgt->vd_nblk = n;
32566+ tgt->vd_last.ul = tgt->vd_last.ul;
32567+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
32568+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
32569+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 32570+ /* smp_mb(); */
32571+ return 0; /* success */
32572+
4f0767ce 32573+out:
1facf9fc 32574+ rerr = reinit_vdir(tgt);
32575+ BUG_ON(rerr);
32576+ return err;
32577+}
32578+
32579+int au_vdir_init(struct file *file)
32580+{
32581+ int err;
32582+ struct inode *inode;
32583+ struct au_vdir *vdir_cache, *allocated;
32584+
392086de 32585+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 32586+ err = read_vdir(file, !file->f_pos);
32587+ if (unlikely(err))
32588+ goto out;
32589+
32590+ allocated = NULL;
32591+ vdir_cache = au_fvdir_cache(file);
32592+ if (!vdir_cache) {
1308ab2a 32593+ vdir_cache = alloc_vdir(file);
1facf9fc 32594+ err = PTR_ERR(vdir_cache);
32595+ if (IS_ERR(vdir_cache))
32596+ goto out;
32597+ allocated = vdir_cache;
32598+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 32599+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 32600+ err = reinit_vdir(vdir_cache);
32601+ if (unlikely(err))
32602+ goto out;
32603+ } else
32604+ return 0; /* success */
32605+
c06a8ce3 32606+ inode = file_inode(file);
1facf9fc 32607+ err = copy_vdir(vdir_cache, au_ivdir(inode));
32608+ if (!err) {
be118d29 32609+ file->f_version = inode_query_iversion(inode);
1facf9fc 32610+ if (allocated)
32611+ au_set_fvdir_cache(file, allocated);
32612+ } else if (allocated)
1c60b727 32613+ au_vdir_free(allocated);
1facf9fc 32614+
4f0767ce 32615+out:
1facf9fc 32616+ return err;
32617+}
32618+
32619+static loff_t calc_offset(struct au_vdir *vdir)
32620+{
32621+ loff_t offset;
32622+ union au_vdir_deblk_p p;
32623+
32624+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
32625+ offset = vdir->vd_last.p.deblk - p.deblk;
32626+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
32627+ return offset;
32628+}
32629+
32630+/* returns true or false */
392086de 32631+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 32632+{
32633+ int valid;
32634+ unsigned int deblk_sz;
32635+ unsigned long ul, n;
32636+ loff_t offset;
32637+ union au_vdir_deblk_p p, deblk_end;
32638+ struct au_vdir *vdir_cache;
32639+
32640+ valid = 1;
32641+ vdir_cache = au_fvdir_cache(file);
32642+ offset = calc_offset(vdir_cache);
32643+ AuDbg("offset %lld\n", offset);
392086de 32644+ if (ctx->pos == offset)
1facf9fc 32645+ goto out;
32646+
32647+ vdir_cache->vd_last.ul = 0;
32648+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 32649+ if (!ctx->pos)
1facf9fc 32650+ goto out;
32651+
32652+ valid = 0;
32653+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 32654+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 32655+ AuDbg("ul %lu\n", ul);
32656+ if (ul >= vdir_cache->vd_nblk)
32657+ goto out;
32658+
32659+ n = vdir_cache->vd_nblk;
32660+ for (; ul < n; ul++) {
32661+ p.deblk = vdir_cache->vd_deblk[ul];
32662+ deblk_end.deblk = p.deblk + deblk_sz;
32663+ offset = ul;
32664+ offset *= deblk_sz;
392086de 32665+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 32666+ unsigned int l;
32667+
32668+ l = calc_size(p.de->de_str.len);
32669+ offset += l;
32670+ p.deblk += l;
32671+ }
32672+ if (!is_deblk_end(&p, &deblk_end)) {
32673+ valid = 1;
32674+ vdir_cache->vd_last.ul = ul;
32675+ vdir_cache->vd_last.p = p;
32676+ break;
32677+ }
32678+ }
32679+
4f0767ce 32680+out:
1facf9fc 32681+ /* smp_mb(); */
b00004a5
AM
32682+ if (!valid)
32683+ AuDbg("valid %d\n", !valid);
1facf9fc 32684+ return valid;
32685+}
32686+
392086de 32687+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 32688+{
1facf9fc 32689+ unsigned int l, deblk_sz;
32690+ union au_vdir_deblk_p deblk_end;
32691+ struct au_vdir *vdir_cache;
32692+ struct au_vdir_de *de;
32693+
392086de 32694+ if (!seek_vdir(file, ctx))
1facf9fc 32695+ return 0;
32696+
acd2b654 32697+ vdir_cache = au_fvdir_cache(file);
1facf9fc 32698+ deblk_sz = vdir_cache->vd_deblk_sz;
32699+ while (1) {
32700+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
32701+ deblk_end.deblk += deblk_sz;
32702+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
32703+ de = vdir_cache->vd_last.p.de;
32704+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 32705+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 32706+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
32707+ if (unlikely(!dir_emit(ctx, de->de_str.name,
32708+ de->de_str.len, de->de_ino,
32709+ de->de_type))) {
1facf9fc 32710+ /* todo: ignore the error caused by udba? */
32711+ /* return err; */
32712+ return 0;
32713+ }
32714+
32715+ l = calc_size(de->de_str.len);
32716+ vdir_cache->vd_last.p.deblk += l;
392086de 32717+ ctx->pos += l;
1facf9fc 32718+ }
32719+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
32720+ vdir_cache->vd_last.ul++;
32721+ vdir_cache->vd_last.p.deblk
32722+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 32723+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 32724+ continue;
32725+ }
32726+ break;
32727+ }
32728+
32729+ /* smp_mb(); */
32730+ return 0;
32731+}
7f207e10
AM
32732diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
32733--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
32734+++ linux/fs/aufs/vfsub.c 2018-10-23 12:33:35.599375796 +0200
32735@@ -0,0 +1,902 @@
cd7a4cd9 32736+// SPDX-License-Identifier: GPL-2.0
1facf9fc 32737+/*
b00004a5 32738+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 32739+ *
32740+ * This program, aufs is free software; you can redistribute it and/or modify
32741+ * it under the terms of the GNU General Public License as published by
32742+ * the Free Software Foundation; either version 2 of the License, or
32743+ * (at your option) any later version.
dece6358
AM
32744+ *
32745+ * This program is distributed in the hope that it will be useful,
32746+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32747+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32748+ * GNU General Public License for more details.
32749+ *
32750+ * You should have received a copy of the GNU General Public License
523b37e3 32751+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32752+ */
32753+
32754+/*
32755+ * sub-routines for VFS
32756+ */
32757+
8b6a4947 32758+#include <linux/mnt_namespace.h>
dece6358 32759+#include <linux/namei.h>
8cdd5066 32760+#include <linux/nsproxy.h>
dece6358
AM
32761+#include <linux/security.h>
32762+#include <linux/splice.h>
1facf9fc 32763+#include "aufs.h"
32764+
8cdd5066
JR
32765+#ifdef CONFIG_AUFS_BR_FUSE
32766+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb)
32767+{
8cdd5066
JR
32768+ if (!au_test_fuse(h_sb) || !au_userns)
32769+ return 0;
32770+
8b6a4947 32771+ return is_current_mnt_ns(mnt) ? 0 : -EACCES;
8cdd5066
JR
32772+}
32773+#endif
32774+
a2654f78
AM
32775+int vfsub_sync_filesystem(struct super_block *h_sb, int wait)
32776+{
32777+ int err;
32778+
32779+ lockdep_off();
32780+ down_read(&h_sb->s_umount);
32781+ err = __sync_filesystem(h_sb, wait);
32782+ up_read(&h_sb->s_umount);
32783+ lockdep_on();
32784+
32785+ return err;
32786+}
32787+
8cdd5066
JR
32788+/* ---------------------------------------------------------------------- */
32789+
1facf9fc 32790+int vfsub_update_h_iattr(struct path *h_path, int *did)
32791+{
32792+ int err;
32793+ struct kstat st;
32794+ struct super_block *h_sb;
32795+
32796+ /* for remote fs, leave work for its getattr or d_revalidate */
32797+ /* for bad i_attr fs, handle them in aufs_getattr() */
32798+ /* still some fs may acquire i_mutex. we need to skip them */
32799+ err = 0;
32800+ if (!did)
32801+ did = &err;
32802+ h_sb = h_path->dentry->d_sb;
32803+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
32804+ if (*did)
521ced18 32805+ err = vfsub_getattr(h_path, &st);
1facf9fc 32806+
32807+ return err;
32808+}
32809+
32810+/* ---------------------------------------------------------------------- */
32811+
4a4d8108 32812+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 32813+{
32814+ struct file *file;
32815+
b4510431 32816+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 32817+ current_cred());
2cbb1c4b
JR
32818+ if (!IS_ERR_OR_NULL(file)
32819+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
5527c038 32820+ i_readcount_inc(d_inode(path->dentry));
4a4d8108 32821+
1308ab2a 32822+ return file;
32823+}
32824+
1facf9fc 32825+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
32826+{
32827+ struct file *file;
32828+
2cbb1c4b 32829+ lockdep_off();
7f207e10 32830+ file = filp_open(path,
2cbb1c4b 32831+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 32832+ mode);
2cbb1c4b 32833+ lockdep_on();
1facf9fc 32834+ if (IS_ERR(file))
32835+ goto out;
32836+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
32837+
4f0767ce 32838+out:
1facf9fc 32839+ return file;
32840+}
32841+
b912730e
AM
32842+/*
32843+ * Ideally this function should call VFS:do_last() in order to keep all its
32844+ * checkings. But it is very hard for aufs to regenerate several VFS internal
32845+ * structure such as nameidata. This is a second (or third) best approach.
32846+ * cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open().
32847+ */
32848+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
acd2b654 32849+ struct vfsub_aopen_args *args)
b912730e
AM
32850+{
32851+ int err;
acd2b654 32852+ struct au_branch *br = args->br;
b912730e
AM
32853+ struct file *file = args->file;
32854+ /* copied from linux/fs/namei.c:atomic_open() */
32855+ struct dentry *const DENTRY_NOT_SET = (void *)-1UL;
32856+
32857+ IMustLock(dir);
32858+ AuDebugOn(!dir->i_op->atomic_open);
32859+
32860+ err = au_br_test_oflag(args->open_flag, br);
32861+ if (unlikely(err))
32862+ goto out;
32863+
acd2b654
AM
32864+ au_lcnt_inc(&br->br_nfiles);
32865+ file->f_path.dentry = DENTRY_NOT_SET;
32866+ file->f_path.mnt = au_br_mnt(br);
32867+ AuDbg("%ps\n", dir->i_op->atomic_open);
b912730e 32868+ err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag,
acd2b654
AM
32869+ args->create_mode);
32870+ if (unlikely(err < 0)) {
32871+ au_lcnt_dec(&br->br_nfiles);
b912730e 32872+ goto out;
acd2b654 32873+ }
b912730e 32874+
acd2b654
AM
32875+ /* temporary workaround for nfsv4 branch */
32876+ if (au_test_nfs(dir->i_sb))
32877+ nfs_mark_for_revalidate(dir);
b912730e 32878+
acd2b654
AM
32879+ if (file->f_mode & FMODE_CREATED)
32880+ fsnotify_create(dir, dentry);
32881+ if (!(file->f_mode & FMODE_OPENED)) {
32882+ au_lcnt_dec(&br->br_nfiles);
32883+ goto out;
b912730e
AM
32884+ }
32885+
acd2b654
AM
32886+ /* todo: call VFS:may_open() here */
32887+ /* todo: ima_file_check() too? */
32888+ if (!err && (args->open_flag & __FMODE_EXEC))
32889+ err = deny_write_access(file);
32890+ if (!err)
32891+ fsnotify_open(file);
32892+ else
32893+ au_lcnt_dec(&br->br_nfiles);
32894+ /* note that the file is created and still opened */
b912730e
AM
32895+
32896+out:
32897+ return err;
32898+}
32899+
1facf9fc 32900+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
32901+{
32902+ int err;
32903+
1facf9fc 32904+ err = kern_path(name, flags, path);
5527c038 32905+ if (!err && d_is_positive(path->dentry))
1facf9fc 32906+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
32907+ return err;
32908+}
32909+
febd17d6
JR
32910+struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
32911+ struct dentry *parent, int len)
32912+{
32913+ struct path path = {
32914+ .mnt = NULL
32915+ };
32916+
32917+ path.dentry = lookup_one_len_unlocked(name, parent, len);
32918+ if (IS_ERR(path.dentry))
32919+ goto out;
32920+ if (d_is_positive(path.dentry))
32921+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
32922+
32923+out:
32924+ AuTraceErrPtr(path.dentry);
32925+ return path.dentry;
32926+}
32927+
1facf9fc 32928+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
32929+ int len)
32930+{
32931+ struct path path = {
32932+ .mnt = NULL
32933+ };
32934+
1308ab2a 32935+ /* VFS checks it too, but by WARN_ON_ONCE() */
5527c038 32936+ IMustLock(d_inode(parent));
1facf9fc 32937+
32938+ path.dentry = lookup_one_len(name, parent, len);
32939+ if (IS_ERR(path.dentry))
32940+ goto out;
5527c038 32941+ if (d_is_positive(path.dentry))
1facf9fc 32942+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
32943+
4f0767ce 32944+out:
4a4d8108 32945+ AuTraceErrPtr(path.dentry);
1facf9fc 32946+ return path.dentry;
32947+}
32948+
b4510431 32949+void vfsub_call_lkup_one(void *args)
2cbb1c4b 32950+{
b4510431
AM
32951+ struct vfsub_lkup_one_args *a = args;
32952+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
32953+}
32954+
1facf9fc 32955+/* ---------------------------------------------------------------------- */
32956+
32957+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
32958+ struct dentry *d2, struct au_hinode *hdir2)
32959+{
32960+ struct dentry *d;
32961+
2cbb1c4b 32962+ lockdep_off();
1facf9fc 32963+ d = lock_rename(d1, d2);
2cbb1c4b 32964+ lockdep_on();
4a4d8108 32965+ au_hn_suspend(hdir1);
1facf9fc 32966+ if (hdir1 != hdir2)
4a4d8108 32967+ au_hn_suspend(hdir2);
1facf9fc 32968+
32969+ return d;
32970+}
32971+
32972+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
32973+ struct dentry *d2, struct au_hinode *hdir2)
32974+{
4a4d8108 32975+ au_hn_resume(hdir1);
1facf9fc 32976+ if (hdir1 != hdir2)
4a4d8108 32977+ au_hn_resume(hdir2);
2cbb1c4b 32978+ lockdep_off();
1facf9fc 32979+ unlock_rename(d1, d2);
2cbb1c4b 32980+ lockdep_on();
1facf9fc 32981+}
32982+
32983+/* ---------------------------------------------------------------------- */
32984+
b4510431 32985+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 32986+{
32987+ int err;
32988+ struct dentry *d;
32989+
32990+ IMustLock(dir);
32991+
32992+ d = path->dentry;
32993+ path->dentry = d->d_parent;
b752ccd1 32994+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 32995+ path->dentry = d;
32996+ if (unlikely(err))
32997+ goto out;
32998+
c1595e42 32999+ lockdep_off();
b4510431 33000+ err = vfs_create(dir, path->dentry, mode, want_excl);
c1595e42 33001+ lockdep_on();
1facf9fc 33002+ if (!err) {
33003+ struct path tmp = *path;
33004+ int did;
33005+
33006+ vfsub_update_h_iattr(&tmp, &did);
33007+ if (did) {
33008+ tmp.dentry = path->dentry->d_parent;
33009+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33010+ }
33011+ /*ignore*/
33012+ }
33013+
4f0767ce 33014+out:
1facf9fc 33015+ return err;
33016+}
33017+
33018+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
33019+{
33020+ int err;
33021+ struct dentry *d;
33022+
33023+ IMustLock(dir);
33024+
33025+ d = path->dentry;
33026+ path->dentry = d->d_parent;
b752ccd1 33027+ err = security_path_symlink(path, d, symname);
1facf9fc 33028+ path->dentry = d;
33029+ if (unlikely(err))
33030+ goto out;
33031+
c1595e42 33032+ lockdep_off();
1facf9fc 33033+ err = vfs_symlink(dir, path->dentry, symname);
c1595e42 33034+ lockdep_on();
1facf9fc 33035+ if (!err) {
33036+ struct path tmp = *path;
33037+ int did;
33038+
33039+ vfsub_update_h_iattr(&tmp, &did);
33040+ if (did) {
33041+ tmp.dentry = path->dentry->d_parent;
33042+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33043+ }
33044+ /*ignore*/
33045+ }
33046+
4f0767ce 33047+out:
1facf9fc 33048+ return err;
33049+}
33050+
33051+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
33052+{
33053+ int err;
33054+ struct dentry *d;
33055+
33056+ IMustLock(dir);
33057+
33058+ d = path->dentry;
33059+ path->dentry = d->d_parent;
027c5e7a 33060+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 33061+ path->dentry = d;
33062+ if (unlikely(err))
33063+ goto out;
33064+
c1595e42 33065+ lockdep_off();
1facf9fc 33066+ err = vfs_mknod(dir, path->dentry, mode, dev);
c1595e42 33067+ lockdep_on();
1facf9fc 33068+ if (!err) {
33069+ struct path tmp = *path;
33070+ int did;
33071+
33072+ vfsub_update_h_iattr(&tmp, &did);
33073+ if (did) {
33074+ tmp.dentry = path->dentry->d_parent;
33075+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33076+ }
33077+ /*ignore*/
33078+ }
33079+
4f0767ce 33080+out:
1facf9fc 33081+ return err;
33082+}
33083+
33084+static int au_test_nlink(struct inode *inode)
33085+{
33086+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
33087+
33088+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
33089+ || inode->i_nlink < link_max)
33090+ return 0;
33091+ return -EMLINK;
33092+}
33093+
523b37e3
AM
33094+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
33095+ struct inode **delegated_inode)
1facf9fc 33096+{
33097+ int err;
33098+ struct dentry *d;
33099+
33100+ IMustLock(dir);
33101+
5527c038 33102+ err = au_test_nlink(d_inode(src_dentry));
1facf9fc 33103+ if (unlikely(err))
33104+ return err;
33105+
b4510431 33106+ /* we don't call may_linkat() */
1facf9fc 33107+ d = path->dentry;
33108+ path->dentry = d->d_parent;
b752ccd1 33109+ err = security_path_link(src_dentry, path, d);
1facf9fc 33110+ path->dentry = d;
33111+ if (unlikely(err))
33112+ goto out;
33113+
2cbb1c4b 33114+ lockdep_off();
523b37e3 33115+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 33116+ lockdep_on();
1facf9fc 33117+ if (!err) {
33118+ struct path tmp = *path;
33119+ int did;
33120+
33121+ /* fuse has different memory inode for the same inumber */
33122+ vfsub_update_h_iattr(&tmp, &did);
33123+ if (did) {
33124+ tmp.dentry = path->dentry->d_parent;
33125+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33126+ tmp.dentry = src_dentry;
33127+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33128+ }
33129+ /*ignore*/
33130+ }
33131+
4f0767ce 33132+out:
1facf9fc 33133+ return err;
33134+}
33135+
33136+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3 33137+ struct inode *dir, struct path *path,
f2c43d5f 33138+ struct inode **delegated_inode, unsigned int flags)
1facf9fc 33139+{
33140+ int err;
33141+ struct path tmp = {
33142+ .mnt = path->mnt
33143+ };
33144+ struct dentry *d;
33145+
33146+ IMustLock(dir);
33147+ IMustLock(src_dir);
33148+
33149+ d = path->dentry;
33150+ path->dentry = d->d_parent;
33151+ tmp.dentry = src_dentry->d_parent;
38d290e6 33152+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
1facf9fc 33153+ path->dentry = d;
33154+ if (unlikely(err))
33155+ goto out;
33156+
2cbb1c4b 33157+ lockdep_off();
523b37e3 33158+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
f2c43d5f 33159+ delegated_inode, flags);
2cbb1c4b 33160+ lockdep_on();
1facf9fc 33161+ if (!err) {
33162+ int did;
33163+
33164+ tmp.dentry = d->d_parent;
33165+ vfsub_update_h_iattr(&tmp, &did);
33166+ if (did) {
33167+ tmp.dentry = src_dentry;
33168+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33169+ tmp.dentry = src_dentry->d_parent;
33170+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33171+ }
33172+ /*ignore*/
33173+ }
33174+
4f0767ce 33175+out:
1facf9fc 33176+ return err;
33177+}
33178+
33179+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
33180+{
33181+ int err;
33182+ struct dentry *d;
33183+
33184+ IMustLock(dir);
33185+
33186+ d = path->dentry;
33187+ path->dentry = d->d_parent;
b752ccd1 33188+ err = security_path_mkdir(path, d, mode);
1facf9fc 33189+ path->dentry = d;
33190+ if (unlikely(err))
33191+ goto out;
33192+
c1595e42 33193+ lockdep_off();
1facf9fc 33194+ err = vfs_mkdir(dir, path->dentry, mode);
c1595e42 33195+ lockdep_on();
1facf9fc 33196+ if (!err) {
33197+ struct path tmp = *path;
33198+ int did;
33199+
33200+ vfsub_update_h_iattr(&tmp, &did);
33201+ if (did) {
33202+ tmp.dentry = path->dentry->d_parent;
33203+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
33204+ }
33205+ /*ignore*/
33206+ }
33207+
4f0767ce 33208+out:
1facf9fc 33209+ return err;
33210+}
33211+
33212+int vfsub_rmdir(struct inode *dir, struct path *path)
33213+{
33214+ int err;
33215+ struct dentry *d;
33216+
33217+ IMustLock(dir);
33218+
33219+ d = path->dentry;
33220+ path->dentry = d->d_parent;
b752ccd1 33221+ err = security_path_rmdir(path, d);
1facf9fc 33222+ path->dentry = d;
33223+ if (unlikely(err))
33224+ goto out;
33225+
2cbb1c4b 33226+ lockdep_off();
1facf9fc 33227+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 33228+ lockdep_on();
1facf9fc 33229+ if (!err) {
33230+ struct path tmp = {
33231+ .dentry = path->dentry->d_parent,
33232+ .mnt = path->mnt
33233+ };
33234+
33235+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
33236+ }
33237+
4f0767ce 33238+out:
1facf9fc 33239+ return err;
33240+}
33241+
33242+/* ---------------------------------------------------------------------- */
33243+
9dbd164d 33244+/* todo: support mmap_sem? */
1facf9fc 33245+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
33246+ loff_t *ppos)
33247+{
33248+ ssize_t err;
33249+
2cbb1c4b 33250+ lockdep_off();
1facf9fc 33251+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 33252+ lockdep_on();
1facf9fc 33253+ if (err >= 0)
33254+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
33255+ return err;
33256+}
33257+
33258+/* todo: kernel_read()? */
33259+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
33260+ loff_t *ppos)
33261+{
33262+ ssize_t err;
33263+ mm_segment_t oldfs;
b752ccd1
AM
33264+ union {
33265+ void *k;
33266+ char __user *u;
33267+ } buf;
1facf9fc 33268+
b752ccd1 33269+ buf.k = kbuf;
1facf9fc 33270+ oldfs = get_fs();
33271+ set_fs(KERNEL_DS);
b752ccd1 33272+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 33273+ set_fs(oldfs);
33274+ return err;
33275+}
33276+
33277+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
33278+ loff_t *ppos)
33279+{
33280+ ssize_t err;
33281+
2cbb1c4b 33282+ lockdep_off();
1facf9fc 33283+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 33284+ lockdep_on();
1facf9fc 33285+ if (err >= 0)
33286+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
33287+ return err;
33288+}
33289+
33290+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
33291+{
33292+ ssize_t err;
33293+ mm_segment_t oldfs;
b752ccd1
AM
33294+ union {
33295+ void *k;
33296+ const char __user *u;
33297+ } buf;
1facf9fc 33298+
b752ccd1 33299+ buf.k = kbuf;
1facf9fc 33300+ oldfs = get_fs();
33301+ set_fs(KERNEL_DS);
b752ccd1 33302+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 33303+ set_fs(oldfs);
33304+ return err;
33305+}
33306+
4a4d8108
AM
33307+int vfsub_flush(struct file *file, fl_owner_t id)
33308+{
33309+ int err;
33310+
33311+ err = 0;
523b37e3 33312+ if (file->f_op->flush) {
2000de60 33313+ if (!au_test_nfs(file->f_path.dentry->d_sb))
2cbb1c4b
JR
33314+ err = file->f_op->flush(file, id);
33315+ else {
33316+ lockdep_off();
33317+ err = file->f_op->flush(file, id);
33318+ lockdep_on();
33319+ }
4a4d8108
AM
33320+ if (!err)
33321+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
33322+ /*ignore*/
33323+ }
33324+ return err;
33325+}
33326+
392086de 33327+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 33328+{
33329+ int err;
33330+
062440b3 33331+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos);
392086de 33332+
2cbb1c4b 33333+ lockdep_off();
392086de 33334+ err = iterate_dir(file, ctx);
2cbb1c4b 33335+ lockdep_on();
1facf9fc 33336+ if (err >= 0)
33337+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
1c60b727 33338+
1facf9fc 33339+ return err;
33340+}
33341+
33342+long vfsub_splice_to(struct file *in, loff_t *ppos,
33343+ struct pipe_inode_info *pipe, size_t len,
33344+ unsigned int flags)
33345+{
33346+ long err;
33347+
2cbb1c4b 33348+ lockdep_off();
0fc653ad 33349+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 33350+ lockdep_on();
4a4d8108 33351+ file_accessed(in);
1facf9fc 33352+ if (err >= 0)
33353+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
33354+ return err;
33355+}
33356+
33357+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
33358+ loff_t *ppos, size_t len, unsigned int flags)
33359+{
33360+ long err;
33361+
2cbb1c4b 33362+ lockdep_off();
0fc653ad 33363+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 33364+ lockdep_on();
1facf9fc 33365+ if (err >= 0)
33366+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
33367+ return err;
33368+}
33369+
53392da6
AM
33370+int vfsub_fsync(struct file *file, struct path *path, int datasync)
33371+{
33372+ int err;
33373+
33374+ /* file can be NULL */
33375+ lockdep_off();
33376+ err = vfs_fsync(file, datasync);
33377+ lockdep_on();
33378+ if (!err) {
33379+ if (!path) {
33380+ AuDebugOn(!file);
33381+ path = &file->f_path;
33382+ }
33383+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
33384+ }
33385+ return err;
33386+}
33387+
1facf9fc 33388+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
33389+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
33390+ struct file *h_file)
33391+{
33392+ int err;
33393+ struct inode *h_inode;
c06a8ce3 33394+ struct super_block *h_sb;
1facf9fc 33395+
1facf9fc 33396+ if (!h_file) {
c06a8ce3
AM
33397+ err = vfsub_truncate(h_path, length);
33398+ goto out;
1facf9fc 33399+ }
33400+
5527c038 33401+ h_inode = d_inode(h_path->dentry);
c06a8ce3
AM
33402+ h_sb = h_inode->i_sb;
33403+ lockdep_off();
33404+ sb_start_write(h_sb);
33405+ lockdep_on();
1facf9fc 33406+ err = locks_verify_truncate(h_inode, h_file, length);
33407+ if (!err)
953406b4 33408+ err = security_path_truncate(h_path);
2cbb1c4b
JR
33409+ if (!err) {
33410+ lockdep_off();
1facf9fc 33411+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
33412+ lockdep_on();
33413+ }
c06a8ce3
AM
33414+ lockdep_off();
33415+ sb_end_write(h_sb);
33416+ lockdep_on();
1facf9fc 33417+
4f0767ce 33418+out:
1facf9fc 33419+ return err;
33420+}
33421+
33422+/* ---------------------------------------------------------------------- */
33423+
33424+struct au_vfsub_mkdir_args {
33425+ int *errp;
33426+ struct inode *dir;
33427+ struct path *path;
33428+ int mode;
33429+};
33430+
33431+static void au_call_vfsub_mkdir(void *args)
33432+{
33433+ struct au_vfsub_mkdir_args *a = args;
33434+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
33435+}
33436+
33437+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
33438+{
33439+ int err, do_sio, wkq_err;
33440+
33441+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
33442+ if (!do_sio) {
33443+ lockdep_off();
1facf9fc 33444+ err = vfsub_mkdir(dir, path, mode);
c1595e42
JR
33445+ lockdep_on();
33446+ } else {
1facf9fc 33447+ struct au_vfsub_mkdir_args args = {
33448+ .errp = &err,
33449+ .dir = dir,
33450+ .path = path,
33451+ .mode = mode
33452+ };
33453+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
33454+ if (unlikely(wkq_err))
33455+ err = wkq_err;
33456+ }
33457+
33458+ return err;
33459+}
33460+
33461+struct au_vfsub_rmdir_args {
33462+ int *errp;
33463+ struct inode *dir;
33464+ struct path *path;
33465+};
33466+
33467+static void au_call_vfsub_rmdir(void *args)
33468+{
33469+ struct au_vfsub_rmdir_args *a = args;
33470+ *a->errp = vfsub_rmdir(a->dir, a->path);
33471+}
33472+
33473+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
33474+{
33475+ int err, do_sio, wkq_err;
33476+
33477+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
33478+ if (!do_sio) {
33479+ lockdep_off();
1facf9fc 33480+ err = vfsub_rmdir(dir, path);
c1595e42
JR
33481+ lockdep_on();
33482+ } else {
1facf9fc 33483+ struct au_vfsub_rmdir_args args = {
33484+ .errp = &err,
33485+ .dir = dir,
33486+ .path = path
33487+ };
33488+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
33489+ if (unlikely(wkq_err))
33490+ err = wkq_err;
33491+ }
33492+
33493+ return err;
33494+}
33495+
33496+/* ---------------------------------------------------------------------- */
33497+
33498+struct notify_change_args {
33499+ int *errp;
33500+ struct path *path;
33501+ struct iattr *ia;
523b37e3 33502+ struct inode **delegated_inode;
1facf9fc 33503+};
33504+
33505+static void call_notify_change(void *args)
33506+{
33507+ struct notify_change_args *a = args;
33508+ struct inode *h_inode;
33509+
5527c038 33510+ h_inode = d_inode(a->path->dentry);
1facf9fc 33511+ IMustLock(h_inode);
33512+
33513+ *a->errp = -EPERM;
33514+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
c1595e42 33515+ lockdep_off();
523b37e3
AM
33516+ *a->errp = notify_change(a->path->dentry, a->ia,
33517+ a->delegated_inode);
c1595e42 33518+ lockdep_on();
1facf9fc 33519+ if (!*a->errp)
33520+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
33521+ }
33522+ AuTraceErr(*a->errp);
33523+}
33524+
523b37e3
AM
33525+int vfsub_notify_change(struct path *path, struct iattr *ia,
33526+ struct inode **delegated_inode)
1facf9fc 33527+{
33528+ int err;
33529+ struct notify_change_args args = {
523b37e3
AM
33530+ .errp = &err,
33531+ .path = path,
33532+ .ia = ia,
33533+ .delegated_inode = delegated_inode
1facf9fc 33534+ };
33535+
33536+ call_notify_change(&args);
33537+
33538+ return err;
33539+}
33540+
523b37e3
AM
33541+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
33542+ struct inode **delegated_inode)
1facf9fc 33543+{
33544+ int err, wkq_err;
33545+ struct notify_change_args args = {
523b37e3
AM
33546+ .errp = &err,
33547+ .path = path,
33548+ .ia = ia,
33549+ .delegated_inode = delegated_inode
1facf9fc 33550+ };
33551+
33552+ wkq_err = au_wkq_wait(call_notify_change, &args);
33553+ if (unlikely(wkq_err))
33554+ err = wkq_err;
33555+
33556+ return err;
33557+}
33558+
33559+/* ---------------------------------------------------------------------- */
33560+
33561+struct unlink_args {
33562+ int *errp;
33563+ struct inode *dir;
33564+ struct path *path;
523b37e3 33565+ struct inode **delegated_inode;
1facf9fc 33566+};
33567+
33568+static void call_unlink(void *args)
33569+{
33570+ struct unlink_args *a = args;
33571+ struct dentry *d = a->path->dentry;
33572+ struct inode *h_inode;
33573+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
c1595e42 33574+ && au_dcount(d) == 1);
1facf9fc 33575+
33576+ IMustLock(a->dir);
33577+
33578+ a->path->dentry = d->d_parent;
33579+ *a->errp = security_path_unlink(a->path, d);
33580+ a->path->dentry = d;
33581+ if (unlikely(*a->errp))
33582+ return;
33583+
33584+ if (!stop_sillyrename)
33585+ dget(d);
5527c038
JR
33586+ h_inode = NULL;
33587+ if (d_is_positive(d)) {
33588+ h_inode = d_inode(d);
027c5e7a 33589+ ihold(h_inode);
5527c038 33590+ }
1facf9fc 33591+
2cbb1c4b 33592+ lockdep_off();
523b37e3 33593+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 33594+ lockdep_on();
1facf9fc 33595+ if (!*a->errp) {
33596+ struct path tmp = {
33597+ .dentry = d->d_parent,
33598+ .mnt = a->path->mnt
33599+ };
33600+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
33601+ }
33602+
33603+ if (!stop_sillyrename)
33604+ dput(d);
33605+ if (h_inode)
33606+ iput(h_inode);
33607+
33608+ AuTraceErr(*a->errp);
33609+}
33610+
33611+/*
33612+ * @dir: must be locked.
33613+ * @dentry: target dentry.
33614+ */
523b37e3
AM
33615+int vfsub_unlink(struct inode *dir, struct path *path,
33616+ struct inode **delegated_inode, int force)
1facf9fc 33617+{
33618+ int err;
33619+ struct unlink_args args = {
523b37e3
AM
33620+ .errp = &err,
33621+ .dir = dir,
33622+ .path = path,
33623+ .delegated_inode = delegated_inode
1facf9fc 33624+ };
33625+
33626+ if (!force)
33627+ call_unlink(&args);
33628+ else {
33629+ int wkq_err;
33630+
33631+ wkq_err = au_wkq_wait(call_unlink, &args);
33632+ if (unlikely(wkq_err))
33633+ err = wkq_err;
33634+ }
33635+
33636+ return err;
33637+}
7f207e10
AM
33638diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
33639--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
acd2b654 33640+++ linux/fs/aufs/vfsub.h 2018-10-23 12:33:35.599375796 +0200
062440b3
AM
33641@@ -0,0 +1,355 @@
33642+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 33643+/*
b00004a5 33644+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 33645+ *
33646+ * This program, aufs is free software; you can redistribute it and/or modify
33647+ * it under the terms of the GNU General Public License as published by
33648+ * the Free Software Foundation; either version 2 of the License, or
33649+ * (at your option) any later version.
dece6358
AM
33650+ *
33651+ * This program is distributed in the hope that it will be useful,
33652+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33653+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33654+ * GNU General Public License for more details.
33655+ *
33656+ * You should have received a copy of the GNU General Public License
523b37e3 33657+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33658+ */
33659+
33660+/*
33661+ * sub-routines for VFS
33662+ */
33663+
33664+#ifndef __AUFS_VFSUB_H__
33665+#define __AUFS_VFSUB_H__
33666+
33667+#ifdef __KERNEL__
33668+
33669+#include <linux/fs.h>
be118d29 33670+#include <linux/iversion.h>
b4510431 33671+#include <linux/mount.h>
8cdd5066 33672+#include <linux/posix_acl.h>
c1595e42 33673+#include <linux/xattr.h>
7f207e10 33674+#include "debug.h"
1facf9fc 33675+
7f207e10 33676+/* copied from linux/fs/internal.h */
2cbb1c4b 33677+/* todo: BAD approach!! */
c06a8ce3 33678+extern void __mnt_drop_write(struct vfsmount *);
acd2b654 33679+extern struct file *alloc_empty_file(int, const struct cred *);
7f207e10
AM
33680+
33681+/* ---------------------------------------------------------------------- */
1facf9fc 33682+
33683+/* lock subclass for lower inode */
33684+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
33685+/* reduce? gave up. */
33686+enum {
c1595e42 33687+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
1facf9fc 33688+ AuLsc_I_PARENT, /* lower inode, parent first */
33689+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 33690+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 33691+ AuLsc_I_CHILD,
33692+ AuLsc_I_CHILD2,
33693+ AuLsc_I_End
33694+};
33695+
33696+/* to debug easier, do not make them inlined functions */
33697+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
febd17d6 33698+#define IMustLock(i) AuDebugOn(!inode_is_locked(i))
1facf9fc 33699+
33700+/* ---------------------------------------------------------------------- */
33701+
7f207e10
AM
33702+static inline void vfsub_drop_nlink(struct inode *inode)
33703+{
33704+ AuDebugOn(!inode->i_nlink);
33705+ drop_nlink(inode);
33706+}
33707+
027c5e7a
AM
33708+static inline void vfsub_dead_dir(struct inode *inode)
33709+{
33710+ AuDebugOn(!S_ISDIR(inode->i_mode));
33711+ inode->i_flags |= S_DEAD;
33712+ clear_nlink(inode);
33713+}
33714+
392086de
AM
33715+static inline int vfsub_native_ro(struct inode *inode)
33716+{
8b6a4947 33717+ return sb_rdonly(inode->i_sb)
392086de
AM
33718+ || IS_RDONLY(inode)
33719+ /* || IS_APPEND(inode) */
33720+ || IS_IMMUTABLE(inode);
33721+}
33722+
8cdd5066
JR
33723+#ifdef CONFIG_AUFS_BR_FUSE
33724+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb);
33725+#else
33726+AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb);
33727+#endif
33728+
a2654f78
AM
33729+int vfsub_sync_filesystem(struct super_block *h_sb, int wait);
33730+
7f207e10
AM
33731+/* ---------------------------------------------------------------------- */
33732+
33733+int vfsub_update_h_iattr(struct path *h_path, int *did);
33734+struct file *vfsub_dentry_open(struct path *path, int flags);
33735+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
acd2b654 33736+struct au_branch;
b912730e 33737+struct vfsub_aopen_args {
acd2b654
AM
33738+ struct file *file;
33739+ unsigned int open_flag;
33740+ umode_t create_mode;
33741+ struct au_branch *br;
b912730e 33742+};
b912730e 33743+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
acd2b654 33744+ struct vfsub_aopen_args *args);
1facf9fc 33745+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 33746+
febd17d6
JR
33747+struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
33748+ struct dentry *parent, int len);
1facf9fc 33749+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
33750+ int len);
b4510431
AM
33751+
33752+struct vfsub_lkup_one_args {
33753+ struct dentry **errp;
33754+ struct qstr *name;
33755+ struct dentry *parent;
33756+};
33757+
33758+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
33759+ struct dentry *parent)
33760+{
33761+ return vfsub_lookup_one_len(name->name, parent, name->len);
33762+}
33763+
33764+void vfsub_call_lkup_one(void *args);
33765+
33766+/* ---------------------------------------------------------------------- */
33767+
33768+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
33769+{
33770+ int err;
076b876e 33771+
b4510431
AM
33772+ lockdep_off();
33773+ err = mnt_want_write(mnt);
33774+ lockdep_on();
33775+ return err;
33776+}
33777+
33778+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
33779+{
33780+ lockdep_off();
33781+ mnt_drop_write(mnt);
33782+ lockdep_on();
33783+}
1facf9fc 33784+
7e9cd9fe 33785+#if 0 /* reserved */
c06a8ce3
AM
33786+static inline void vfsub_mnt_drop_write_file(struct file *file)
33787+{
33788+ lockdep_off();
33789+ mnt_drop_write_file(file);
33790+ lockdep_on();
33791+}
7e9cd9fe 33792+#endif
c06a8ce3 33793+
1facf9fc 33794+/* ---------------------------------------------------------------------- */
33795+
33796+struct au_hinode;
33797+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
33798+ struct dentry *d2, struct au_hinode *hdir2);
33799+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
33800+ struct dentry *d2, struct au_hinode *hdir2);
33801+
537831f9
AM
33802+int vfsub_create(struct inode *dir, struct path *path, int mode,
33803+ bool want_excl);
1facf9fc 33804+int vfsub_symlink(struct inode *dir, struct path *path,
33805+ const char *symname);
33806+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
33807+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 33808+ struct path *path, struct inode **delegated_inode);
1facf9fc 33809+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3 33810+ struct inode *hdir, struct path *path,
f2c43d5f 33811+ struct inode **delegated_inode, unsigned int flags);
1facf9fc 33812+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
33813+int vfsub_rmdir(struct inode *dir, struct path *path);
33814+
33815+/* ---------------------------------------------------------------------- */
33816+
33817+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
33818+ loff_t *ppos);
33819+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
33820+ loff_t *ppos);
33821+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
33822+ loff_t *ppos);
33823+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
33824+ loff_t *ppos);
4a4d8108 33825+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
33826+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
33827+
c06a8ce3
AM
33828+static inline loff_t vfsub_f_size_read(struct file *file)
33829+{
33830+ return i_size_read(file_inode(file));
33831+}
33832+
4a4d8108
AM
33833+static inline unsigned int vfsub_file_flags(struct file *file)
33834+{
33835+ unsigned int flags;
33836+
33837+ spin_lock(&file->f_lock);
33838+ flags = file->f_flags;
33839+ spin_unlock(&file->f_lock);
33840+
33841+ return flags;
33842+}
1308ab2a 33843+
f0c0a007
AM
33844+static inline int vfsub_file_execed(struct file *file)
33845+{
33846+ /* todo: direct access f_flags */
33847+ return !!(vfsub_file_flags(file) & __FMODE_EXEC);
33848+}
33849+
7e9cd9fe 33850+#if 0 /* reserved */
1facf9fc 33851+static inline void vfsub_file_accessed(struct file *h_file)
33852+{
33853+ file_accessed(h_file);
33854+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
33855+}
7e9cd9fe 33856+#endif
1facf9fc 33857+
79b8bda9 33858+#if 0 /* reserved */
1facf9fc 33859+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
33860+ struct dentry *h_dentry)
33861+{
33862+ struct path h_path = {
33863+ .dentry = h_dentry,
33864+ .mnt = h_mnt
33865+ };
92d182d2 33866+ touch_atime(&h_path);
1facf9fc 33867+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
33868+}
79b8bda9 33869+#endif
1facf9fc 33870+
cd7a4cd9
AM
33871+static inline int vfsub_update_time(struct inode *h_inode,
33872+ struct timespec64 *ts, int flags)
0c3ec466 33873+{
5afbbe0d 33874+ return update_time(h_inode, ts, flags);
0c3ec466
AM
33875+ /* no vfsub_update_h_iattr() since we don't have struct path */
33876+}
33877+
8cdd5066
JR
33878+#ifdef CONFIG_FS_POSIX_ACL
33879+static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode)
33880+{
33881+ int err;
33882+
33883+ err = posix_acl_chmod(h_inode, h_mode);
33884+ if (err == -EOPNOTSUPP)
33885+ err = 0;
33886+ return err;
33887+}
33888+#else
33889+AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode);
33890+#endif
33891+
4a4d8108
AM
33892+long vfsub_splice_to(struct file *in, loff_t *ppos,
33893+ struct pipe_inode_info *pipe, size_t len,
33894+ unsigned int flags);
33895+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
33896+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
33897+
33898+static inline long vfsub_truncate(struct path *path, loff_t length)
33899+{
33900+ long err;
076b876e 33901+
c06a8ce3
AM
33902+ lockdep_off();
33903+ err = vfs_truncate(path, length);
33904+ lockdep_on();
33905+ return err;
33906+}
33907+
4a4d8108
AM
33908+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
33909+ struct file *h_file);
53392da6 33910+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 33911+
521ced18
JR
33912+/*
33913+ * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such
33914+ * ioctl.
33915+ */
33916+static inline int vfsub_clone_file_range(struct file *src, struct file *dst,
33917+ u64 len)
33918+{
33919+ int err;
33920+
33921+ lockdep_off();
33922+ err = vfs_clone_file_range(src, 0, dst, 0, len);
33923+ lockdep_on();
33924+
33925+ return err;
33926+}
33927+
33928+/* copy_file_range(2) is a systemcall */
33929+static inline ssize_t vfsub_copy_file_range(struct file *src, loff_t src_pos,
33930+ struct file *dst, loff_t dst_pos,
33931+ size_t len, unsigned int flags)
33932+{
33933+ ssize_t ssz;
33934+
33935+ lockdep_off();
33936+ ssz = vfs_copy_file_range(src, src_pos, dst, dst_pos, len, flags);
33937+ lockdep_on();
33938+
33939+ return ssz;
33940+}
33941+
1facf9fc 33942+/* ---------------------------------------------------------------------- */
33943+
33944+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
33945+{
33946+ loff_t err;
33947+
2cbb1c4b 33948+ lockdep_off();
1facf9fc 33949+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 33950+ lockdep_on();
1facf9fc 33951+ return err;
33952+}
33953+
33954+/* ---------------------------------------------------------------------- */
33955+
4a4d8108
AM
33956+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
33957+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
33958+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
33959+ struct inode **delegated_inode);
33960+int vfsub_notify_change(struct path *path, struct iattr *ia,
33961+ struct inode **delegated_inode);
33962+int vfsub_unlink(struct inode *dir, struct path *path,
33963+ struct inode **delegated_inode, int force);
4a4d8108 33964+
521ced18
JR
33965+static inline int vfsub_getattr(const struct path *path, struct kstat *st)
33966+{
33967+ return vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
33968+}
33969+
c1595e42
JR
33970+/* ---------------------------------------------------------------------- */
33971+
33972+static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
33973+ const void *value, size_t size, int flags)
33974+{
33975+ int err;
33976+
33977+ lockdep_off();
33978+ err = vfs_setxattr(dentry, name, value, size, flags);
33979+ lockdep_on();
33980+
33981+ return err;
33982+}
33983+
33984+static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
33985+{
33986+ int err;
33987+
33988+ lockdep_off();
33989+ err = vfs_removexattr(dentry, name);
33990+ lockdep_on();
33991+
33992+ return err;
33993+}
33994+
1facf9fc 33995+#endif /* __KERNEL__ */
33996+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
33997diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
33998--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9
AM
33999+++ linux/fs/aufs/wbr_policy.c 2018-08-12 23:43:05.463458173 +0200
34000@@ -0,0 +1,830 @@
34001+// SPDX-License-Identifier: GPL-2.0
1facf9fc 34002+/*
b00004a5 34003+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 34004+ *
34005+ * This program, aufs is free software; you can redistribute it and/or modify
34006+ * it under the terms of the GNU General Public License as published by
34007+ * the Free Software Foundation; either version 2 of the License, or
34008+ * (at your option) any later version.
dece6358
AM
34009+ *
34010+ * This program is distributed in the hope that it will be useful,
34011+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34012+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34013+ * GNU General Public License for more details.
34014+ *
34015+ * You should have received a copy of the GNU General Public License
523b37e3 34016+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 34017+ */
34018+
34019+/*
34020+ * policies for selecting one among multiple writable branches
34021+ */
34022+
34023+#include <linux/statfs.h>
34024+#include "aufs.h"
34025+
34026+/* subset of cpup_attr() */
34027+static noinline_for_stack
34028+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
34029+{
34030+ int err, sbits;
34031+ struct iattr ia;
34032+ struct inode *h_isrc;
34033+
5527c038 34034+ h_isrc = d_inode(h_src);
1facf9fc 34035+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
34036+ ia.ia_mode = h_isrc->i_mode;
34037+ ia.ia_uid = h_isrc->i_uid;
34038+ ia.ia_gid = h_isrc->i_gid;
34039+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
5527c038 34040+ au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags);
523b37e3
AM
34041+ /* no delegation since it is just created */
34042+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 34043+
34044+ /* is this nfs only? */
34045+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
34046+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
34047+ ia.ia_mode = h_isrc->i_mode;
523b37e3 34048+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 34049+ }
34050+
34051+ return err;
34052+}
34053+
34054+#define AuCpdown_PARENT_OPQ 1
34055+#define AuCpdown_WHED (1 << 1)
34056+#define AuCpdown_MADE_DIR (1 << 2)
34057+#define AuCpdown_DIROPQ (1 << 3)
34058+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
34059+#define au_fset_cpdown(flags, name) \
34060+ do { (flags) |= AuCpdown_##name; } while (0)
34061+#define au_fclr_cpdown(flags, name) \
34062+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 34063+
1facf9fc 34064+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 34065+ unsigned int *flags)
1facf9fc 34066+{
34067+ int err;
34068+ struct dentry *opq_dentry;
34069+
34070+ opq_dentry = au_diropq_create(dentry, bdst);
34071+ err = PTR_ERR(opq_dentry);
34072+ if (IS_ERR(opq_dentry))
34073+ goto out;
34074+ dput(opq_dentry);
c2b27bf2 34075+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 34076+
4f0767ce 34077+out:
1facf9fc 34078+ return err;
34079+}
34080+
34081+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
34082+ struct inode *dir, aufs_bindex_t bdst)
34083+{
34084+ int err;
34085+ struct path h_path;
34086+ struct au_branch *br;
34087+
34088+ br = au_sbr(dentry->d_sb, bdst);
34089+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
34090+ err = PTR_ERR(h_path.dentry);
34091+ if (IS_ERR(h_path.dentry))
34092+ goto out;
34093+
34094+ err = 0;
5527c038 34095+ if (d_is_positive(h_path.dentry)) {
86dc4139 34096+ h_path.mnt = au_br_mnt(br);
1facf9fc 34097+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
34098+ dentry);
34099+ }
34100+ dput(h_path.dentry);
34101+
4f0767ce 34102+out:
1facf9fc 34103+ return err;
34104+}
34105+
34106+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 34107+ struct au_pin *pin,
1facf9fc 34108+ struct dentry *h_parent, void *arg)
34109+{
34110+ int err, rerr;
5afbbe0d 34111+ aufs_bindex_t bopq, btop;
1facf9fc 34112+ struct path h_path;
34113+ struct dentry *parent;
34114+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 34115+ unsigned int *flags = arg;
1facf9fc 34116+
5afbbe0d 34117+ btop = au_dbtop(dentry);
1facf9fc 34118+ /* dentry is di-locked */
34119+ parent = dget_parent(dentry);
5527c038
JR
34120+ dir = d_inode(parent);
34121+ h_dir = d_inode(h_parent);
1facf9fc 34122+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
34123+ IMustLock(h_dir);
34124+
86dc4139 34125+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 34126+ if (unlikely(err < 0))
34127+ goto out;
34128+ h_path.dentry = au_h_dptr(dentry, bdst);
34129+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
cd7a4cd9 34130+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path, 0755);
1facf9fc 34131+ if (unlikely(err))
34132+ goto out_put;
c2b27bf2 34133+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 34134+
1facf9fc 34135+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
34136+ au_fclr_cpdown(*flags, WHED);
34137+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 34138+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
34139+ au_fset_cpdown(*flags, WHED);
34140+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
34141+ au_fset_cpdown(*flags, PARENT_OPQ);
5527c038 34142+ h_inode = d_inode(h_path.dentry);
febd17d6 34143+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
c2b27bf2
AM
34144+ if (au_ftest_cpdown(*flags, WHED)) {
34145+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 34146+ if (unlikely(err)) {
febd17d6 34147+ inode_unlock(h_inode);
1facf9fc 34148+ goto out_dir;
34149+ }
34150+ }
34151+
5afbbe0d 34152+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, btop));
febd17d6 34153+ inode_unlock(h_inode);
1facf9fc 34154+ if (unlikely(err))
34155+ goto out_opq;
34156+
c2b27bf2 34157+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 34158+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
34159+ if (unlikely(err))
34160+ goto out_opq;
34161+ }
34162+
5527c038 34163+ inode = d_inode(dentry);
5afbbe0d
AM
34164+ if (au_ibbot(inode) < bdst)
34165+ au_set_ibbot(inode, bdst);
1facf9fc 34166+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
34167+ au_hi_flags(inode, /*isdir*/1));
076b876e 34168+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
1facf9fc 34169+ goto out; /* success */
34170+
34171+ /* revert */
4f0767ce 34172+out_opq:
c2b27bf2 34173+ if (au_ftest_cpdown(*flags, DIROPQ)) {
febd17d6 34174+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
1facf9fc 34175+ rerr = au_diropq_remove(dentry, bdst);
febd17d6 34176+ inode_unlock(h_inode);
1facf9fc 34177+ if (unlikely(rerr)) {
523b37e3
AM
34178+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
34179+ dentry, bdst, rerr);
1facf9fc 34180+ err = -EIO;
34181+ goto out;
34182+ }
34183+ }
4f0767ce 34184+out_dir:
c2b27bf2 34185+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 34186+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
34187+ if (unlikely(rerr)) {
523b37e3
AM
34188+ AuIOErr("failed removing %pd b%d (%d)\n",
34189+ dentry, bdst, rerr);
1facf9fc 34190+ err = -EIO;
34191+ }
34192+ }
4f0767ce 34193+out_put:
1facf9fc 34194+ au_set_h_dptr(dentry, bdst, NULL);
5afbbe0d
AM
34195+ if (au_dbbot(dentry) == bdst)
34196+ au_update_dbbot(dentry);
4f0767ce 34197+out:
1facf9fc 34198+ dput(parent);
34199+ return err;
34200+}
34201+
34202+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
34203+{
34204+ int err;
c2b27bf2 34205+ unsigned int flags;
1facf9fc 34206+
c2b27bf2
AM
34207+ flags = 0;
34208+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 34209+
34210+ return err;
34211+}
34212+
34213+/* ---------------------------------------------------------------------- */
34214+
34215+/* policies for create */
34216+
c2b27bf2 34217+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
34218+{
34219+ int err, i, j, ndentry;
34220+ aufs_bindex_t bopq;
34221+ struct au_dcsub_pages dpages;
34222+ struct au_dpage *dpage;
34223+ struct dentry **dentries, *parent, *d;
34224+
34225+ err = au_dpages_init(&dpages, GFP_NOFS);
34226+ if (unlikely(err))
34227+ goto out;
34228+ parent = dget_parent(dentry);
027c5e7a 34229+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
34230+ if (unlikely(err))
34231+ goto out_free;
34232+
34233+ err = bindex;
34234+ for (i = 0; i < dpages.ndpage; i++) {
34235+ dpage = dpages.dpages + i;
34236+ dentries = dpage->dentries;
34237+ ndentry = dpage->ndentry;
34238+ for (j = 0; j < ndentry; j++) {
34239+ d = dentries[j];
34240+ di_read_lock_parent2(d, !AuLock_IR);
34241+ bopq = au_dbdiropq(d);
34242+ di_read_unlock(d, !AuLock_IR);
34243+ if (bopq >= 0 && bopq < err)
34244+ err = bopq;
34245+ }
34246+ }
34247+
34248+out_free:
34249+ dput(parent);
34250+ au_dpages_free(&dpages);
34251+out:
34252+ return err;
34253+}
34254+
1facf9fc 34255+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
34256+{
34257+ for (; bindex >= 0; bindex--)
34258+ if (!au_br_rdonly(au_sbr(sb, bindex)))
34259+ return bindex;
34260+ return -EROFS;
34261+}
34262+
34263+/* top down parent */
392086de
AM
34264+static int au_wbr_create_tdp(struct dentry *dentry,
34265+ unsigned int flags __maybe_unused)
1facf9fc 34266+{
34267+ int err;
5afbbe0d 34268+ aufs_bindex_t btop, bindex;
1facf9fc 34269+ struct super_block *sb;
34270+ struct dentry *parent, *h_parent;
34271+
34272+ sb = dentry->d_sb;
5afbbe0d
AM
34273+ btop = au_dbtop(dentry);
34274+ err = btop;
34275+ if (!au_br_rdonly(au_sbr(sb, btop)))
1facf9fc 34276+ goto out;
34277+
34278+ err = -EROFS;
34279+ parent = dget_parent(dentry);
5afbbe0d 34280+ for (bindex = au_dbtop(parent); bindex < btop; bindex++) {
1facf9fc 34281+ h_parent = au_h_dptr(parent, bindex);
5527c038 34282+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 34283+ continue;
34284+
34285+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
34286+ err = bindex;
34287+ break;
34288+ }
34289+ }
34290+ dput(parent);
34291+
34292+ /* bottom up here */
4a4d8108 34293+ if (unlikely(err < 0)) {
5afbbe0d 34294+ err = au_wbr_bu(sb, btop - 1);
4a4d8108
AM
34295+ if (err >= 0)
34296+ err = au_wbr_nonopq(dentry, err);
34297+ }
1facf9fc 34298+
4f0767ce 34299+out:
1facf9fc 34300+ AuDbg("b%d\n", err);
34301+ return err;
34302+}
34303+
34304+/* ---------------------------------------------------------------------- */
34305+
34306+/* an exception for the policy other than tdp */
34307+static int au_wbr_create_exp(struct dentry *dentry)
34308+{
34309+ int err;
34310+ aufs_bindex_t bwh, bdiropq;
34311+ struct dentry *parent;
34312+
34313+ err = -1;
34314+ bwh = au_dbwh(dentry);
34315+ parent = dget_parent(dentry);
34316+ bdiropq = au_dbdiropq(parent);
34317+ if (bwh >= 0) {
34318+ if (bdiropq >= 0)
34319+ err = min(bdiropq, bwh);
34320+ else
34321+ err = bwh;
34322+ AuDbg("%d\n", err);
34323+ } else if (bdiropq >= 0) {
34324+ err = bdiropq;
34325+ AuDbg("%d\n", err);
34326+ }
34327+ dput(parent);
34328+
4a4d8108
AM
34329+ if (err >= 0)
34330+ err = au_wbr_nonopq(dentry, err);
34331+
1facf9fc 34332+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
34333+ err = -1;
34334+
34335+ AuDbg("%d\n", err);
34336+ return err;
34337+}
34338+
34339+/* ---------------------------------------------------------------------- */
34340+
34341+/* round robin */
34342+static int au_wbr_create_init_rr(struct super_block *sb)
34343+{
34344+ int err;
34345+
5afbbe0d 34346+ err = au_wbr_bu(sb, au_sbbot(sb));
1facf9fc 34347+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 34348+ /* smp_mb(); */
1facf9fc 34349+
34350+ AuDbg("b%d\n", err);
34351+ return err;
34352+}
34353+
392086de 34354+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 34355+{
34356+ int err, nbr;
34357+ unsigned int u;
5afbbe0d 34358+ aufs_bindex_t bindex, bbot;
1facf9fc 34359+ struct super_block *sb;
34360+ atomic_t *next;
34361+
34362+ err = au_wbr_create_exp(dentry);
34363+ if (err >= 0)
34364+ goto out;
34365+
34366+ sb = dentry->d_sb;
34367+ next = &au_sbi(sb)->si_wbr_rr_next;
5afbbe0d
AM
34368+ bbot = au_sbbot(sb);
34369+ nbr = bbot + 1;
34370+ for (bindex = 0; bindex <= bbot; bindex++) {
392086de 34371+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 34372+ err = atomic_dec_return(next) + 1;
34373+ /* modulo for 0 is meaningless */
34374+ if (unlikely(!err))
34375+ err = atomic_dec_return(next) + 1;
34376+ } else
34377+ err = atomic_read(next);
34378+ AuDbg("%d\n", err);
34379+ u = err;
34380+ err = u % nbr;
34381+ AuDbg("%d\n", err);
34382+ if (!au_br_rdonly(au_sbr(sb, err)))
34383+ break;
34384+ err = -EROFS;
34385+ }
34386+
4a4d8108
AM
34387+ if (err >= 0)
34388+ err = au_wbr_nonopq(dentry, err);
34389+
4f0767ce 34390+out:
1facf9fc 34391+ AuDbg("%d\n", err);
34392+ return err;
34393+}
34394+
34395+/* ---------------------------------------------------------------------- */
34396+
34397+/* most free space */
392086de 34398+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 34399+{
34400+ struct super_block *sb;
34401+ struct au_branch *br;
34402+ struct au_wbr_mfs *mfs;
392086de 34403+ struct dentry *h_parent;
5afbbe0d 34404+ aufs_bindex_t bindex, bbot;
1facf9fc 34405+ int err;
34406+ unsigned long long b, bavail;
7f207e10 34407+ struct path h_path;
1facf9fc 34408+ /* reduce the stack usage */
34409+ struct kstatfs *st;
34410+
34411+ st = kmalloc(sizeof(*st), GFP_NOFS);
34412+ if (unlikely(!st)) {
34413+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
34414+ return;
34415+ }
34416+
34417+ bavail = 0;
34418+ sb = dentry->d_sb;
34419+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 34420+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 34421+ mfs->mfs_bindex = -EROFS;
34422+ mfs->mfsrr_bytes = 0;
392086de
AM
34423+ if (!parent) {
34424+ bindex = 0;
5afbbe0d 34425+ bbot = au_sbbot(sb);
392086de 34426+ } else {
5afbbe0d
AM
34427+ bindex = au_dbtop(parent);
34428+ bbot = au_dbtaildir(parent);
392086de
AM
34429+ }
34430+
5afbbe0d 34431+ for (; bindex <= bbot; bindex++) {
392086de
AM
34432+ if (parent) {
34433+ h_parent = au_h_dptr(parent, bindex);
5527c038 34434+ if (!h_parent || d_is_negative(h_parent))
392086de
AM
34435+ continue;
34436+ }
1facf9fc 34437+ br = au_sbr(sb, bindex);
34438+ if (au_br_rdonly(br))
34439+ continue;
34440+
34441+ /* sb->s_root for NFS is unreliable */
86dc4139 34442+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
34443+ h_path.dentry = h_path.mnt->mnt_root;
34444+ err = vfs_statfs(&h_path, st);
1facf9fc 34445+ if (unlikely(err)) {
34446+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
34447+ continue;
34448+ }
34449+
34450+ /* when the available size is equal, select the lower one */
34451+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
34452+ || sizeof(b) < sizeof(st->f_bsize));
34453+ b = st->f_bavail * st->f_bsize;
34454+ br->br_wbr->wbr_bytes = b;
34455+ if (b >= bavail) {
34456+ bavail = b;
34457+ mfs->mfs_bindex = bindex;
34458+ mfs->mfs_jiffy = jiffies;
34459+ }
34460+ }
34461+
34462+ mfs->mfsrr_bytes = bavail;
34463+ AuDbg("b%d\n", mfs->mfs_bindex);
1c60b727 34464+ kfree(st);
1facf9fc 34465+}
34466+
392086de 34467+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 34468+{
34469+ int err;
392086de 34470+ struct dentry *parent;
1facf9fc 34471+ struct super_block *sb;
34472+ struct au_wbr_mfs *mfs;
34473+
34474+ err = au_wbr_create_exp(dentry);
34475+ if (err >= 0)
34476+ goto out;
34477+
34478+ sb = dentry->d_sb;
392086de
AM
34479+ parent = NULL;
34480+ if (au_ftest_wbr(flags, PARENT))
34481+ parent = dget_parent(dentry);
1facf9fc 34482+ mfs = &au_sbi(sb)->si_wbr_mfs;
34483+ mutex_lock(&mfs->mfs_lock);
34484+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
34485+ || mfs->mfs_bindex < 0
34486+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 34487+ au_mfs(dentry, parent);
1facf9fc 34488+ mutex_unlock(&mfs->mfs_lock);
34489+ err = mfs->mfs_bindex;
392086de 34490+ dput(parent);
1facf9fc 34491+
4a4d8108
AM
34492+ if (err >= 0)
34493+ err = au_wbr_nonopq(dentry, err);
34494+
4f0767ce 34495+out:
1facf9fc 34496+ AuDbg("b%d\n", err);
34497+ return err;
34498+}
34499+
34500+static int au_wbr_create_init_mfs(struct super_block *sb)
34501+{
34502+ struct au_wbr_mfs *mfs;
34503+
34504+ mfs = &au_sbi(sb)->si_wbr_mfs;
34505+ mutex_init(&mfs->mfs_lock);
34506+ mfs->mfs_jiffy = 0;
34507+ mfs->mfs_bindex = -EROFS;
34508+
34509+ return 0;
34510+}
34511+
34512+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
34513+{
34514+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
34515+ return 0;
34516+}
34517+
34518+/* ---------------------------------------------------------------------- */
34519+
f2c43d5f
AM
34520+/* top down regardless parent, and then mfs */
34521+static int au_wbr_create_tdmfs(struct dentry *dentry,
34522+ unsigned int flags __maybe_unused)
34523+{
34524+ int err;
34525+ aufs_bindex_t bwh, btail, bindex, bfound, bmfs;
34526+ unsigned long long watermark;
34527+ struct super_block *sb;
34528+ struct au_wbr_mfs *mfs;
34529+ struct au_branch *br;
34530+ struct dentry *parent;
34531+
34532+ sb = dentry->d_sb;
34533+ mfs = &au_sbi(sb)->si_wbr_mfs;
34534+ mutex_lock(&mfs->mfs_lock);
34535+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
34536+ || mfs->mfs_bindex < 0)
34537+ au_mfs(dentry, /*parent*/NULL);
34538+ watermark = mfs->mfsrr_watermark;
34539+ bmfs = mfs->mfs_bindex;
34540+ mutex_unlock(&mfs->mfs_lock);
34541+
34542+ /* another style of au_wbr_create_exp() */
34543+ bwh = au_dbwh(dentry);
34544+ parent = dget_parent(dentry);
34545+ btail = au_dbtaildir(parent);
34546+ if (bwh >= 0 && bwh < btail)
34547+ btail = bwh;
34548+
34549+ err = au_wbr_nonopq(dentry, btail);
34550+ if (unlikely(err < 0))
34551+ goto out;
34552+ btail = err;
34553+ bfound = -1;
34554+ for (bindex = 0; bindex <= btail; bindex++) {
34555+ br = au_sbr(sb, bindex);
34556+ if (au_br_rdonly(br))
34557+ continue;
34558+ if (br->br_wbr->wbr_bytes > watermark) {
34559+ bfound = bindex;
34560+ break;
34561+ }
34562+ }
34563+ err = bfound;
34564+ if (err < 0)
34565+ err = bmfs;
34566+
34567+out:
34568+ dput(parent);
34569+ AuDbg("b%d\n", err);
34570+ return err;
34571+}
34572+
34573+/* ---------------------------------------------------------------------- */
34574+
1facf9fc 34575+/* most free space and then round robin */
392086de 34576+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 34577+{
34578+ int err;
34579+ struct au_wbr_mfs *mfs;
34580+
392086de 34581+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 34582+ if (err >= 0) {
34583+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 34584+ mutex_lock(&mfs->mfs_lock);
1facf9fc 34585+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 34586+ err = au_wbr_create_rr(dentry, flags);
dece6358 34587+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 34588+ }
34589+
34590+ AuDbg("b%d\n", err);
34591+ return err;
34592+}
34593+
34594+static int au_wbr_create_init_mfsrr(struct super_block *sb)
34595+{
34596+ int err;
34597+
34598+ au_wbr_create_init_mfs(sb); /* ignore */
34599+ err = au_wbr_create_init_rr(sb);
34600+
34601+ return err;
34602+}
34603+
34604+/* ---------------------------------------------------------------------- */
34605+
34606+/* top down parent and most free space */
392086de 34607+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 34608+{
34609+ int err, e2;
34610+ unsigned long long b;
5afbbe0d 34611+ aufs_bindex_t bindex, btop, bbot;
1facf9fc 34612+ struct super_block *sb;
34613+ struct dentry *parent, *h_parent;
34614+ struct au_branch *br;
34615+
392086de 34616+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 34617+ if (unlikely(err < 0))
34618+ goto out;
34619+ parent = dget_parent(dentry);
5afbbe0d
AM
34620+ btop = au_dbtop(parent);
34621+ bbot = au_dbtaildir(parent);
34622+ if (btop == bbot)
1facf9fc 34623+ goto out_parent; /* success */
34624+
392086de 34625+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 34626+ if (e2 < 0)
34627+ goto out_parent; /* success */
34628+
34629+ /* when the available size is equal, select upper one */
34630+ sb = dentry->d_sb;
34631+ br = au_sbr(sb, err);
34632+ b = br->br_wbr->wbr_bytes;
34633+ AuDbg("b%d, %llu\n", err, b);
34634+
5afbbe0d 34635+ for (bindex = btop; bindex <= bbot; bindex++) {
1facf9fc 34636+ h_parent = au_h_dptr(parent, bindex);
5527c038 34637+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 34638+ continue;
34639+
34640+ br = au_sbr(sb, bindex);
34641+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
34642+ b = br->br_wbr->wbr_bytes;
34643+ err = bindex;
34644+ AuDbg("b%d, %llu\n", err, b);
34645+ }
34646+ }
34647+
4a4d8108
AM
34648+ if (err >= 0)
34649+ err = au_wbr_nonopq(dentry, err);
34650+
4f0767ce 34651+out_parent:
1facf9fc 34652+ dput(parent);
4f0767ce 34653+out:
1facf9fc 34654+ AuDbg("b%d\n", err);
34655+ return err;
34656+}
34657+
34658+/* ---------------------------------------------------------------------- */
34659+
392086de
AM
34660+/*
34661+ * - top down parent
34662+ * - most free space with parent
34663+ * - most free space round-robin regardless parent
34664+ */
34665+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
34666+{
34667+ int err;
34668+ unsigned long long watermark;
34669+ struct super_block *sb;
34670+ struct au_branch *br;
34671+ struct au_wbr_mfs *mfs;
34672+
34673+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
34674+ if (unlikely(err < 0))
34675+ goto out;
34676+
34677+ sb = dentry->d_sb;
34678+ br = au_sbr(sb, err);
34679+ mfs = &au_sbi(sb)->si_wbr_mfs;
34680+ mutex_lock(&mfs->mfs_lock);
34681+ watermark = mfs->mfsrr_watermark;
34682+ mutex_unlock(&mfs->mfs_lock);
34683+ if (br->br_wbr->wbr_bytes < watermark)
34684+ /* regardless the parent dir */
34685+ err = au_wbr_create_mfsrr(dentry, flags);
34686+
34687+out:
34688+ AuDbg("b%d\n", err);
34689+ return err;
34690+}
34691+
34692+/* ---------------------------------------------------------------------- */
34693+
1facf9fc 34694+/* policies for copyup */
34695+
34696+/* top down parent */
34697+static int au_wbr_copyup_tdp(struct dentry *dentry)
34698+{
392086de 34699+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 34700+}
34701+
34702+/* bottom up parent */
34703+static int au_wbr_copyup_bup(struct dentry *dentry)
34704+{
34705+ int err;
5afbbe0d 34706+ aufs_bindex_t bindex, btop;
1facf9fc 34707+ struct dentry *parent, *h_parent;
34708+ struct super_block *sb;
34709+
34710+ err = -EROFS;
34711+ sb = dentry->d_sb;
34712+ parent = dget_parent(dentry);
5afbbe0d
AM
34713+ btop = au_dbtop(parent);
34714+ for (bindex = au_dbtop(dentry); bindex >= btop; bindex--) {
1facf9fc 34715+ h_parent = au_h_dptr(parent, bindex);
5527c038 34716+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 34717+ continue;
34718+
34719+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
34720+ err = bindex;
34721+ break;
34722+ }
34723+ }
34724+ dput(parent);
34725+
34726+ /* bottom up here */
34727+ if (unlikely(err < 0))
5afbbe0d 34728+ err = au_wbr_bu(sb, btop - 1);
1facf9fc 34729+
34730+ AuDbg("b%d\n", err);
34731+ return err;
34732+}
34733+
34734+/* bottom up */
5afbbe0d 34735+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop)
1facf9fc 34736+{
34737+ int err;
34738+
5afbbe0d 34739+ err = au_wbr_bu(dentry->d_sb, btop);
4a4d8108 34740+ AuDbg("b%d\n", err);
5afbbe0d 34741+ if (err > btop)
4a4d8108 34742+ err = au_wbr_nonopq(dentry, err);
1facf9fc 34743+
34744+ AuDbg("b%d\n", err);
34745+ return err;
34746+}
34747+
076b876e
AM
34748+static int au_wbr_copyup_bu(struct dentry *dentry)
34749+{
34750+ int err;
5afbbe0d 34751+ aufs_bindex_t btop;
076b876e 34752+
5afbbe0d
AM
34753+ btop = au_dbtop(dentry);
34754+ err = au_wbr_do_copyup_bu(dentry, btop);
076b876e
AM
34755+ return err;
34756+}
34757+
1facf9fc 34758+/* ---------------------------------------------------------------------- */
34759+
34760+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
34761+ [AuWbrCopyup_TDP] = {
34762+ .copyup = au_wbr_copyup_tdp
34763+ },
34764+ [AuWbrCopyup_BUP] = {
34765+ .copyup = au_wbr_copyup_bup
34766+ },
34767+ [AuWbrCopyup_BU] = {
34768+ .copyup = au_wbr_copyup_bu
34769+ }
34770+};
34771+
34772+struct au_wbr_create_operations au_wbr_create_ops[] = {
34773+ [AuWbrCreate_TDP] = {
34774+ .create = au_wbr_create_tdp
34775+ },
34776+ [AuWbrCreate_RR] = {
34777+ .create = au_wbr_create_rr,
34778+ .init = au_wbr_create_init_rr
34779+ },
34780+ [AuWbrCreate_MFS] = {
34781+ .create = au_wbr_create_mfs,
34782+ .init = au_wbr_create_init_mfs,
34783+ .fin = au_wbr_create_fin_mfs
34784+ },
34785+ [AuWbrCreate_MFSV] = {
34786+ .create = au_wbr_create_mfs,
34787+ .init = au_wbr_create_init_mfs,
34788+ .fin = au_wbr_create_fin_mfs
34789+ },
34790+ [AuWbrCreate_MFSRR] = {
34791+ .create = au_wbr_create_mfsrr,
34792+ .init = au_wbr_create_init_mfsrr,
34793+ .fin = au_wbr_create_fin_mfs
34794+ },
34795+ [AuWbrCreate_MFSRRV] = {
34796+ .create = au_wbr_create_mfsrr,
34797+ .init = au_wbr_create_init_mfsrr,
34798+ .fin = au_wbr_create_fin_mfs
34799+ },
f2c43d5f
AM
34800+ [AuWbrCreate_TDMFS] = {
34801+ .create = au_wbr_create_tdmfs,
34802+ .init = au_wbr_create_init_mfs,
34803+ .fin = au_wbr_create_fin_mfs
34804+ },
34805+ [AuWbrCreate_TDMFSV] = {
34806+ .create = au_wbr_create_tdmfs,
34807+ .init = au_wbr_create_init_mfs,
34808+ .fin = au_wbr_create_fin_mfs
34809+ },
1facf9fc 34810+ [AuWbrCreate_PMFS] = {
34811+ .create = au_wbr_create_pmfs,
34812+ .init = au_wbr_create_init_mfs,
34813+ .fin = au_wbr_create_fin_mfs
34814+ },
34815+ [AuWbrCreate_PMFSV] = {
34816+ .create = au_wbr_create_pmfs,
34817+ .init = au_wbr_create_init_mfs,
34818+ .fin = au_wbr_create_fin_mfs
392086de
AM
34819+ },
34820+ [AuWbrCreate_PMFSRR] = {
34821+ .create = au_wbr_create_pmfsrr,
34822+ .init = au_wbr_create_init_mfsrr,
34823+ .fin = au_wbr_create_fin_mfs
34824+ },
34825+ [AuWbrCreate_PMFSRRV] = {
34826+ .create = au_wbr_create_pmfsrr,
34827+ .init = au_wbr_create_init_mfsrr,
34828+ .fin = au_wbr_create_fin_mfs
1facf9fc 34829+ }
34830+};
7f207e10
AM
34831diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
34832--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
acd2b654 34833+++ linux/fs/aufs/whout.c 2018-10-23 12:33:35.599375796 +0200
062440b3 34834@@ -0,0 +1,1062 @@
cd7a4cd9 34835+// SPDX-License-Identifier: GPL-2.0
1facf9fc 34836+/*
b00004a5 34837+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 34838+ *
34839+ * This program, aufs is free software; you can redistribute it and/or modify
34840+ * it under the terms of the GNU General Public License as published by
34841+ * the Free Software Foundation; either version 2 of the License, or
34842+ * (at your option) any later version.
dece6358
AM
34843+ *
34844+ * This program is distributed in the hope that it will be useful,
34845+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34846+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34847+ * GNU General Public License for more details.
34848+ *
34849+ * You should have received a copy of the GNU General Public License
523b37e3 34850+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 34851+ */
34852+
34853+/*
34854+ * whiteout for logical deletion and opaque directory
34855+ */
34856+
1facf9fc 34857+#include "aufs.h"
34858+
cd7a4cd9 34859+#define WH_MASK 0444
1facf9fc 34860+
34861+/*
34862+ * If a directory contains this file, then it is opaque. We start with the
34863+ * .wh. flag so that it is blocked by lookup.
34864+ */
0c3ec466
AM
34865+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
34866+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 34867+
34868+/*
34869+ * generate whiteout name, which is NOT terminated by NULL.
34870+ * @name: original d_name.name
34871+ * @len: original d_name.len
34872+ * @wh: whiteout qstr
34873+ * returns zero when succeeds, otherwise error.
34874+ * succeeded value as wh->name should be freed by kfree().
34875+ */
34876+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
34877+{
34878+ char *p;
34879+
34880+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
34881+ return -ENAMETOOLONG;
34882+
34883+ wh->len = name->len + AUFS_WH_PFX_LEN;
34884+ p = kmalloc(wh->len, GFP_NOFS);
34885+ wh->name = p;
34886+ if (p) {
34887+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
34888+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
34889+ /* smp_mb(); */
34890+ return 0;
34891+ }
34892+ return -ENOMEM;
34893+}
34894+
34895+/* ---------------------------------------------------------------------- */
34896+
34897+/*
34898+ * test if the @wh_name exists under @h_parent.
34899+ * @try_sio specifies the necessary of super-io.
34900+ */
076b876e 34901+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
1facf9fc 34902+{
34903+ int err;
34904+ struct dentry *wh_dentry;
1facf9fc 34905+
1facf9fc 34906+ if (!try_sio)
b4510431 34907+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 34908+ else
076b876e 34909+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
1facf9fc 34910+ err = PTR_ERR(wh_dentry);
2000de60
JR
34911+ if (IS_ERR(wh_dentry)) {
34912+ if (err == -ENAMETOOLONG)
34913+ err = 0;
1facf9fc 34914+ goto out;
2000de60 34915+ }
1facf9fc 34916+
34917+ err = 0;
5527c038 34918+ if (d_is_negative(wh_dentry))
1facf9fc 34919+ goto out_wh; /* success */
34920+
34921+ err = 1;
7e9cd9fe 34922+ if (d_is_reg(wh_dentry))
1facf9fc 34923+ goto out_wh; /* success */
34924+
34925+ err = -EIO;
523b37e3 34926+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
5527c038 34927+ wh_dentry, d_inode(wh_dentry)->i_mode);
1facf9fc 34928+
4f0767ce 34929+out_wh:
1facf9fc 34930+ dput(wh_dentry);
4f0767ce 34931+out:
1facf9fc 34932+ return err;
34933+}
34934+
34935+/*
34936+ * test if the @h_dentry sets opaque or not.
34937+ */
076b876e 34938+int au_diropq_test(struct dentry *h_dentry)
1facf9fc 34939+{
34940+ int err;
34941+ struct inode *h_dir;
34942+
5527c038 34943+ h_dir = d_inode(h_dentry);
076b876e 34944+ err = au_wh_test(h_dentry, &diropq_name,
1facf9fc 34945+ au_test_h_perm_sio(h_dir, MAY_EXEC));
34946+ return err;
34947+}
34948+
34949+/*
34950+ * returns a negative dentry whose name is unique and temporary.
34951+ */
34952+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
34953+ struct qstr *prefix)
34954+{
1facf9fc 34955+ struct dentry *dentry;
34956+ int i;
027c5e7a 34957+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 34958+ *name, *p;
027c5e7a 34959+ /* strict atomic_t is unnecessary here */
1facf9fc 34960+ static unsigned short cnt;
34961+ struct qstr qs;
34962+
4a4d8108
AM
34963+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
34964+
1facf9fc 34965+ name = defname;
027c5e7a
AM
34966+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
34967+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 34968+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 34969+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 34970+ goto out;
34971+ dentry = ERR_PTR(-ENOMEM);
34972+ name = kmalloc(qs.len + 1, GFP_NOFS);
34973+ if (unlikely(!name))
34974+ goto out;
34975+ }
34976+
34977+ /* doubly whiteout-ed */
34978+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
34979+ p = name + AUFS_WH_PFX_LEN * 2;
34980+ memcpy(p, prefix->name, prefix->len);
34981+ p += prefix->len;
34982+ *p++ = '.';
4a4d8108 34983+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 34984+
34985+ qs.name = name;
34986+ for (i = 0; i < 3; i++) {
b752ccd1 34987+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
076b876e 34988+ dentry = au_sio_lkup_one(&qs, h_parent);
5527c038 34989+ if (IS_ERR(dentry) || d_is_negative(dentry))
1facf9fc 34990+ goto out_name;
34991+ dput(dentry);
34992+ }
0c3ec466 34993+ /* pr_warn("could not get random name\n"); */
1facf9fc 34994+ dentry = ERR_PTR(-EEXIST);
34995+ AuDbg("%.*s\n", AuLNPair(&qs));
34996+ BUG();
34997+
4f0767ce 34998+out_name:
1facf9fc 34999+ if (name != defname)
1c60b727 35000+ kfree(name);
4f0767ce 35001+out:
4a4d8108 35002+ AuTraceErrPtr(dentry);
1facf9fc 35003+ return dentry;
1facf9fc 35004+}
35005+
35006+/*
35007+ * rename the @h_dentry on @br to the whiteouted temporary name.
35008+ */
35009+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
35010+{
35011+ int err;
35012+ struct path h_path = {
86dc4139 35013+ .mnt = au_br_mnt(br)
1facf9fc 35014+ };
523b37e3 35015+ struct inode *h_dir, *delegated;
1facf9fc 35016+ struct dentry *h_parent;
35017+
35018+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5527c038 35019+ h_dir = d_inode(h_parent);
1facf9fc 35020+ IMustLock(h_dir);
35021+
35022+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
35023+ err = PTR_ERR(h_path.dentry);
35024+ if (IS_ERR(h_path.dentry))
35025+ goto out;
35026+
35027+ /* under the same dir, no need to lock_rename() */
523b37e3 35028+ delegated = NULL;
f2c43d5f
AM
35029+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated,
35030+ /*flags*/0);
1facf9fc 35031+ AuTraceErr(err);
523b37e3
AM
35032+ if (unlikely(err == -EWOULDBLOCK)) {
35033+ pr_warn("cannot retry for NFSv4 delegation"
35034+ " for an internal rename\n");
35035+ iput(delegated);
35036+ }
1facf9fc 35037+ dput(h_path.dentry);
35038+
4f0767ce 35039+out:
4a4d8108 35040+ AuTraceErr(err);
1facf9fc 35041+ return err;
35042+}
35043+
35044+/* ---------------------------------------------------------------------- */
35045+/*
35046+ * functions for removing a whiteout
35047+ */
35048+
35049+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
35050+{
523b37e3
AM
35051+ int err, force;
35052+ struct inode *delegated;
1facf9fc 35053+
35054+ /*
35055+ * forces superio when the dir has a sticky bit.
35056+ * this may be a violation of unix fs semantics.
35057+ */
35058+ force = (h_dir->i_mode & S_ISVTX)
5527c038 35059+ && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid);
523b37e3
AM
35060+ delegated = NULL;
35061+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
35062+ if (unlikely(err == -EWOULDBLOCK)) {
35063+ pr_warn("cannot retry for NFSv4 delegation"
35064+ " for an internal unlink\n");
35065+ iput(delegated);
35066+ }
35067+ return err;
1facf9fc 35068+}
35069+
35070+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
35071+ struct dentry *dentry)
35072+{
35073+ int err;
35074+
35075+ err = do_unlink_wh(h_dir, h_path);
35076+ if (!err && dentry)
35077+ au_set_dbwh(dentry, -1);
35078+
35079+ return err;
35080+}
35081+
35082+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
35083+ struct au_branch *br)
35084+{
35085+ int err;
35086+ struct path h_path = {
86dc4139 35087+ .mnt = au_br_mnt(br)
1facf9fc 35088+ };
35089+
35090+ err = 0;
b4510431 35091+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 35092+ if (IS_ERR(h_path.dentry))
35093+ err = PTR_ERR(h_path.dentry);
35094+ else {
5527c038
JR
35095+ if (d_is_reg(h_path.dentry))
35096+ err = do_unlink_wh(d_inode(h_parent), &h_path);
1facf9fc 35097+ dput(h_path.dentry);
35098+ }
35099+
35100+ return err;
35101+}
35102+
35103+/* ---------------------------------------------------------------------- */
35104+/*
35105+ * initialize/clean whiteout for a branch
35106+ */
35107+
35108+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
35109+ const int isdir)
35110+{
35111+ int err;
523b37e3 35112+ struct inode *delegated;
1facf9fc 35113+
5527c038 35114+ if (d_is_negative(whpath->dentry))
1facf9fc 35115+ return;
35116+
86dc4139
AM
35117+ if (isdir)
35118+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
35119+ else {
35120+ delegated = NULL;
35121+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
35122+ if (unlikely(err == -EWOULDBLOCK)) {
35123+ pr_warn("cannot retry for NFSv4 delegation"
35124+ " for an internal unlink\n");
35125+ iput(delegated);
35126+ }
35127+ }
1facf9fc 35128+ if (unlikely(err))
523b37e3
AM
35129+ pr_warn("failed removing %pd (%d), ignored.\n",
35130+ whpath->dentry, err);
1facf9fc 35131+}
35132+
35133+static int test_linkable(struct dentry *h_root)
35134+{
5527c038 35135+ struct inode *h_dir = d_inode(h_root);
1facf9fc 35136+
35137+ if (h_dir->i_op->link)
35138+ return 0;
35139+
523b37e3
AM
35140+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
35141+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 35142+ return -ENOSYS;
35143+}
35144+
35145+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
35146+static int au_whdir(struct inode *h_dir, struct path *path)
35147+{
35148+ int err;
35149+
35150+ err = -EEXIST;
5527c038 35151+ if (d_is_negative(path->dentry)) {
cd7a4cd9 35152+ int mode = 0700;
1facf9fc 35153+
35154+ if (au_test_nfs(path->dentry->d_sb))
cd7a4cd9 35155+ mode |= 0111;
86dc4139 35156+ err = vfsub_mkdir(h_dir, path, mode);
2000de60 35157+ } else if (d_is_dir(path->dentry))
1facf9fc 35158+ err = 0;
35159+ else
523b37e3 35160+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 35161+
35162+ return err;
35163+}
35164+
35165+struct au_wh_base {
35166+ const struct qstr *name;
35167+ struct dentry *dentry;
35168+};
35169+
35170+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
35171+ struct path *h_path)
35172+{
35173+ h_path->dentry = base[AuBrWh_BASE].dentry;
35174+ au_wh_clean(h_dir, h_path, /*isdir*/0);
35175+ h_path->dentry = base[AuBrWh_PLINK].dentry;
35176+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35177+ h_path->dentry = base[AuBrWh_ORPH].dentry;
35178+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35179+}
35180+
35181+/*
35182+ * returns tri-state,
c1595e42 35183+ * minus: error, caller should print the message
acd2b654 35184+ * zero: success
c1595e42 35185+ * plus: error, caller should NOT print the message
1facf9fc 35186+ */
35187+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
35188+ int do_plink, struct au_wh_base base[],
35189+ struct path *h_path)
35190+{
35191+ int err;
35192+ struct inode *h_dir;
35193+
5527c038 35194+ h_dir = d_inode(h_root);
1facf9fc 35195+ h_path->dentry = base[AuBrWh_BASE].dentry;
35196+ au_wh_clean(h_dir, h_path, /*isdir*/0);
35197+ h_path->dentry = base[AuBrWh_PLINK].dentry;
35198+ if (do_plink) {
35199+ err = test_linkable(h_root);
35200+ if (unlikely(err)) {
35201+ err = 1;
35202+ goto out;
35203+ }
35204+
35205+ err = au_whdir(h_dir, h_path);
35206+ if (unlikely(err))
35207+ goto out;
35208+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
35209+ } else
35210+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35211+ h_path->dentry = base[AuBrWh_ORPH].dentry;
35212+ err = au_whdir(h_dir, h_path);
35213+ if (unlikely(err))
35214+ goto out;
35215+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
35216+
4f0767ce 35217+out:
1facf9fc 35218+ return err;
35219+}
35220+
35221+/*
35222+ * for the moment, aufs supports the branch filesystem which does not support
35223+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
35224+ * copyup failed. finally, such filesystem will not be used as the writable
35225+ * branch.
35226+ *
35227+ * returns tri-state, see above.
35228+ */
35229+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
35230+ int do_plink, struct au_wh_base base[],
35231+ struct path *h_path)
35232+{
35233+ int err;
35234+ struct inode *h_dir;
35235+
1308ab2a 35236+ WbrWhMustWriteLock(wbr);
35237+
1facf9fc 35238+ err = test_linkable(h_root);
35239+ if (unlikely(err)) {
35240+ err = 1;
35241+ goto out;
35242+ }
35243+
35244+ /*
35245+ * todo: should this create be done in /sbin/mount.aufs helper?
35246+ */
35247+ err = -EEXIST;
5527c038
JR
35248+ h_dir = d_inode(h_root);
35249+ if (d_is_negative(base[AuBrWh_BASE].dentry)) {
86dc4139
AM
35250+ h_path->dentry = base[AuBrWh_BASE].dentry;
35251+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
7e9cd9fe 35252+ } else if (d_is_reg(base[AuBrWh_BASE].dentry))
1facf9fc 35253+ err = 0;
35254+ else
523b37e3 35255+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 35256+ if (unlikely(err))
35257+ goto out;
35258+
35259+ h_path->dentry = base[AuBrWh_PLINK].dentry;
35260+ if (do_plink) {
35261+ err = au_whdir(h_dir, h_path);
35262+ if (unlikely(err))
35263+ goto out;
35264+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
35265+ } else
35266+ au_wh_clean(h_dir, h_path, /*isdir*/1);
35267+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
35268+
35269+ h_path->dentry = base[AuBrWh_ORPH].dentry;
35270+ err = au_whdir(h_dir, h_path);
35271+ if (unlikely(err))
35272+ goto out;
35273+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
35274+
4f0767ce 35275+out:
1facf9fc 35276+ return err;
35277+}
35278+
35279+/*
35280+ * initialize the whiteout base file/dir for @br.
35281+ */
86dc4139 35282+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 35283+{
35284+ int err, i;
35285+ const unsigned char do_plink
35286+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 35287+ struct inode *h_dir;
86dc4139
AM
35288+ struct path path = br->br_path;
35289+ struct dentry *h_root = path.dentry;
1facf9fc 35290+ struct au_wbr *wbr = br->br_wbr;
35291+ static const struct qstr base_name[] = {
0c3ec466
AM
35292+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
35293+ sizeof(AUFS_BASE_NAME) - 1),
35294+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
35295+ sizeof(AUFS_PLINKDIR_NAME) - 1),
35296+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
35297+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 35298+ };
35299+ struct au_wh_base base[] = {
35300+ [AuBrWh_BASE] = {
35301+ .name = base_name + AuBrWh_BASE,
35302+ .dentry = NULL
35303+ },
35304+ [AuBrWh_PLINK] = {
35305+ .name = base_name + AuBrWh_PLINK,
35306+ .dentry = NULL
35307+ },
35308+ [AuBrWh_ORPH] = {
35309+ .name = base_name + AuBrWh_ORPH,
35310+ .dentry = NULL
35311+ }
35312+ };
35313+
1308ab2a 35314+ if (wbr)
35315+ WbrWhMustWriteLock(wbr);
1facf9fc 35316+
1facf9fc 35317+ for (i = 0; i < AuBrWh_Last; i++) {
35318+ /* doubly whiteouted */
35319+ struct dentry *d;
35320+
35321+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
35322+ err = PTR_ERR(d);
35323+ if (IS_ERR(d))
35324+ goto out;
35325+
35326+ base[i].dentry = d;
35327+ AuDebugOn(wbr
35328+ && wbr->wbr_wh[i]
35329+ && wbr->wbr_wh[i] != base[i].dentry);
35330+ }
35331+
35332+ if (wbr)
35333+ for (i = 0; i < AuBrWh_Last; i++) {
35334+ dput(wbr->wbr_wh[i]);
35335+ wbr->wbr_wh[i] = NULL;
35336+ }
35337+
35338+ err = 0;
1e00d052 35339+ if (!au_br_writable(br->br_perm)) {
5527c038 35340+ h_dir = d_inode(h_root);
1facf9fc 35341+ au_wh_init_ro(h_dir, base, &path);
1e00d052 35342+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 35343+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
35344+ if (err > 0)
35345+ goto out;
35346+ else if (err)
35347+ goto out_err;
1e00d052 35348+ } else {
1facf9fc 35349+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
35350+ if (err > 0)
35351+ goto out;
35352+ else if (err)
35353+ goto out_err;
1facf9fc 35354+ }
35355+ goto out; /* success */
35356+
4f0767ce 35357+out_err:
523b37e3
AM
35358+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
35359+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 35360+out:
1facf9fc 35361+ for (i = 0; i < AuBrWh_Last; i++)
35362+ dput(base[i].dentry);
35363+ return err;
35364+}
35365+
35366+/* ---------------------------------------------------------------------- */
35367+/*
35368+ * whiteouts are all hard-linked usually.
35369+ * when its link count reaches a ceiling, we create a new whiteout base
35370+ * asynchronously.
35371+ */
35372+
35373+struct reinit_br_wh {
35374+ struct super_block *sb;
35375+ struct au_branch *br;
35376+};
35377+
35378+static void reinit_br_wh(void *arg)
35379+{
35380+ int err;
35381+ aufs_bindex_t bindex;
35382+ struct path h_path;
35383+ struct reinit_br_wh *a = arg;
35384+ struct au_wbr *wbr;
523b37e3 35385+ struct inode *dir, *delegated;
1facf9fc 35386+ struct dentry *h_root;
35387+ struct au_hinode *hdir;
35388+
35389+ err = 0;
35390+ wbr = a->br->br_wbr;
35391+ /* big aufs lock */
35392+ si_noflush_write_lock(a->sb);
35393+ if (!au_br_writable(a->br->br_perm))
35394+ goto out;
35395+ bindex = au_br_index(a->sb, a->br->br_id);
35396+ if (unlikely(bindex < 0))
35397+ goto out;
35398+
1308ab2a 35399+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
5527c038 35400+ dir = d_inode(a->sb->s_root);
1facf9fc 35401+ hdir = au_hi(dir, bindex);
35402+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 35403+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 35404+
5afbbe0d 35405+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 35406+ wbr_wh_write_lock(wbr);
35407+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
35408+ h_root, a->br);
35409+ if (!err) {
86dc4139
AM
35410+ h_path.dentry = wbr->wbr_whbase;
35411+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
35412+ delegated = NULL;
35413+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
35414+ /*force*/0);
35415+ if (unlikely(err == -EWOULDBLOCK)) {
35416+ pr_warn("cannot retry for NFSv4 delegation"
35417+ " for an internal unlink\n");
35418+ iput(delegated);
35419+ }
1facf9fc 35420+ } else {
523b37e3 35421+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 35422+ err = 0;
35423+ }
35424+ dput(wbr->wbr_whbase);
35425+ wbr->wbr_whbase = NULL;
35426+ if (!err)
86dc4139 35427+ err = au_wh_init(a->br, a->sb);
1facf9fc 35428+ wbr_wh_write_unlock(wbr);
5afbbe0d 35429+ au_hn_inode_unlock(hdir);
1308ab2a 35430+ di_read_unlock(a->sb->s_root, AuLock_IR);
076b876e
AM
35431+ if (!err)
35432+ au_fhsm_wrote(a->sb, bindex, /*force*/0);
1facf9fc 35433+
4f0767ce 35434+out:
1facf9fc 35435+ if (wbr)
35436+ atomic_dec(&wbr->wbr_wh_running);
acd2b654 35437+ au_lcnt_dec(&a->br->br_count);
1facf9fc 35438+ si_write_unlock(a->sb);
027c5e7a 35439+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1c60b727 35440+ kfree(arg);
1facf9fc 35441+ if (unlikely(err))
35442+ AuIOErr("err %d\n", err);
35443+}
35444+
35445+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
35446+{
35447+ int do_dec, wkq_err;
35448+ struct reinit_br_wh *arg;
35449+
35450+ do_dec = 1;
35451+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
35452+ goto out;
35453+
35454+ /* ignore ENOMEM */
35455+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
35456+ if (arg) {
35457+ /*
35458+ * dec(wh_running), kfree(arg) and dec(br_count)
35459+ * in reinit function
35460+ */
35461+ arg->sb = sb;
35462+ arg->br = br;
acd2b654 35463+ au_lcnt_inc(&br->br_count);
53392da6 35464+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 35465+ if (unlikely(wkq_err)) {
35466+ atomic_dec(&br->br_wbr->wbr_wh_running);
acd2b654 35467+ au_lcnt_dec(&br->br_count);
1c60b727 35468+ kfree(arg);
1facf9fc 35469+ }
35470+ do_dec = 0;
35471+ }
35472+
4f0767ce 35473+out:
1facf9fc 35474+ if (do_dec)
35475+ atomic_dec(&br->br_wbr->wbr_wh_running);
35476+}
35477+
35478+/* ---------------------------------------------------------------------- */
35479+
35480+/*
35481+ * create the whiteout @wh.
35482+ */
35483+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
35484+ struct dentry *wh)
35485+{
35486+ int err;
35487+ struct path h_path = {
35488+ .dentry = wh
35489+ };
35490+ struct au_branch *br;
35491+ struct au_wbr *wbr;
35492+ struct dentry *h_parent;
523b37e3 35493+ struct inode *h_dir, *delegated;
1facf9fc 35494+
35495+ h_parent = wh->d_parent; /* dir inode is locked */
5527c038 35496+ h_dir = d_inode(h_parent);
1facf9fc 35497+ IMustLock(h_dir);
35498+
35499+ br = au_sbr(sb, bindex);
86dc4139 35500+ h_path.mnt = au_br_mnt(br);
1facf9fc 35501+ wbr = br->br_wbr;
35502+ wbr_wh_read_lock(wbr);
35503+ if (wbr->wbr_whbase) {
523b37e3
AM
35504+ delegated = NULL;
35505+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
35506+ if (unlikely(err == -EWOULDBLOCK)) {
35507+ pr_warn("cannot retry for NFSv4 delegation"
35508+ " for an internal link\n");
35509+ iput(delegated);
35510+ }
1facf9fc 35511+ if (!err || err != -EMLINK)
35512+ goto out;
35513+
35514+ /* link count full. re-initialize br_whbase. */
35515+ kick_reinit_br_wh(sb, br);
35516+ }
35517+
35518+ /* return this error in this context */
b4510431 35519+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
076b876e
AM
35520+ if (!err)
35521+ au_fhsm_wrote(sb, bindex, /*force*/0);
1facf9fc 35522+
4f0767ce 35523+out:
1facf9fc 35524+ wbr_wh_read_unlock(wbr);
35525+ return err;
35526+}
35527+
35528+/* ---------------------------------------------------------------------- */
35529+
35530+/*
35531+ * create or remove the diropq.
35532+ */
35533+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
35534+ unsigned int flags)
35535+{
35536+ struct dentry *opq_dentry, *h_dentry;
35537+ struct super_block *sb;
35538+ struct au_branch *br;
35539+ int err;
35540+
35541+ sb = dentry->d_sb;
35542+ br = au_sbr(sb, bindex);
35543+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 35544+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 35545+ if (IS_ERR(opq_dentry))
35546+ goto out;
35547+
35548+ if (au_ftest_diropq(flags, CREATE)) {
35549+ err = link_or_create_wh(sb, bindex, opq_dentry);
35550+ if (!err) {
35551+ au_set_dbdiropq(dentry, bindex);
35552+ goto out; /* success */
35553+ }
35554+ } else {
35555+ struct path tmp = {
35556+ .dentry = opq_dentry,
86dc4139 35557+ .mnt = au_br_mnt(br)
1facf9fc 35558+ };
5527c038 35559+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp);
1facf9fc 35560+ if (!err)
35561+ au_set_dbdiropq(dentry, -1);
35562+ }
35563+ dput(opq_dentry);
35564+ opq_dentry = ERR_PTR(err);
35565+
4f0767ce 35566+out:
1facf9fc 35567+ return opq_dentry;
35568+}
35569+
35570+struct do_diropq_args {
35571+ struct dentry **errp;
35572+ struct dentry *dentry;
35573+ aufs_bindex_t bindex;
35574+ unsigned int flags;
35575+};
35576+
35577+static void call_do_diropq(void *args)
35578+{
35579+ struct do_diropq_args *a = args;
35580+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
35581+}
35582+
35583+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
35584+ unsigned int flags)
35585+{
35586+ struct dentry *diropq, *h_dentry;
35587+
35588+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 35589+ if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE))
1facf9fc 35590+ diropq = do_diropq(dentry, bindex, flags);
35591+ else {
35592+ int wkq_err;
35593+ struct do_diropq_args args = {
35594+ .errp = &diropq,
35595+ .dentry = dentry,
35596+ .bindex = bindex,
35597+ .flags = flags
35598+ };
35599+
35600+ wkq_err = au_wkq_wait(call_do_diropq, &args);
35601+ if (unlikely(wkq_err))
35602+ diropq = ERR_PTR(wkq_err);
35603+ }
35604+
35605+ return diropq;
35606+}
35607+
35608+/* ---------------------------------------------------------------------- */
35609+
35610+/*
35611+ * lookup whiteout dentry.
35612+ * @h_parent: lower parent dentry which must exist and be locked
35613+ * @base_name: name of dentry which will be whiteouted
35614+ * returns dentry for whiteout.
35615+ */
35616+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
35617+ struct au_branch *br)
35618+{
35619+ int err;
35620+ struct qstr wh_name;
35621+ struct dentry *wh_dentry;
35622+
35623+ err = au_wh_name_alloc(&wh_name, base_name);
35624+ wh_dentry = ERR_PTR(err);
35625+ if (!err) {
b4510431 35626+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1c60b727 35627+ kfree(wh_name.name);
1facf9fc 35628+ }
35629+ return wh_dentry;
35630+}
35631+
35632+/*
35633+ * link/create a whiteout for @dentry on @bindex.
35634+ */
35635+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
35636+ struct dentry *h_parent)
35637+{
35638+ struct dentry *wh_dentry;
35639+ struct super_block *sb;
35640+ int err;
35641+
35642+ sb = dentry->d_sb;
35643+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
5527c038 35644+ if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) {
1facf9fc 35645+ err = link_or_create_wh(sb, bindex, wh_dentry);
076b876e 35646+ if (!err) {
1facf9fc 35647+ au_set_dbwh(dentry, bindex);
076b876e
AM
35648+ au_fhsm_wrote(sb, bindex, /*force*/0);
35649+ } else {
1facf9fc 35650+ dput(wh_dentry);
35651+ wh_dentry = ERR_PTR(err);
35652+ }
35653+ }
35654+
35655+ return wh_dentry;
35656+}
35657+
35658+/* ---------------------------------------------------------------------- */
35659+
35660+/* Delete all whiteouts in this directory on branch bindex. */
35661+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
35662+ aufs_bindex_t bindex, struct au_branch *br)
35663+{
35664+ int err;
35665+ unsigned long ul, n;
35666+ struct qstr wh_name;
35667+ char *p;
35668+ struct hlist_head *head;
c06a8ce3 35669+ struct au_vdir_wh *pos;
1facf9fc 35670+ struct au_vdir_destr *str;
35671+
35672+ err = -ENOMEM;
537831f9 35673+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 35674+ wh_name.name = p;
35675+ if (unlikely(!wh_name.name))
35676+ goto out;
35677+
35678+ err = 0;
35679+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
35680+ p += AUFS_WH_PFX_LEN;
35681+ n = whlist->nh_num;
35682+ head = whlist->nh_head;
35683+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
35684+ hlist_for_each_entry(pos, head, wh_hash) {
35685+ if (pos->wh_bindex != bindex)
1facf9fc 35686+ continue;
35687+
c06a8ce3 35688+ str = &pos->wh_str;
1facf9fc 35689+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
35690+ memcpy(p, str->name, str->len);
35691+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
35692+ err = unlink_wh_name(h_dentry, &wh_name, br);
35693+ if (!err)
35694+ continue;
35695+ break;
35696+ }
35697+ AuIOErr("whiteout name too long %.*s\n",
35698+ str->len, str->name);
35699+ err = -EIO;
35700+ break;
35701+ }
35702+ }
1c60b727 35703+ free_page((unsigned long)wh_name.name);
1facf9fc 35704+
4f0767ce 35705+out:
1facf9fc 35706+ return err;
35707+}
35708+
35709+struct del_wh_children_args {
35710+ int *errp;
35711+ struct dentry *h_dentry;
1308ab2a 35712+ struct au_nhash *whlist;
1facf9fc 35713+ aufs_bindex_t bindex;
35714+ struct au_branch *br;
35715+};
35716+
35717+static void call_del_wh_children(void *args)
35718+{
35719+ struct del_wh_children_args *a = args;
1308ab2a 35720+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 35721+}
35722+
35723+/* ---------------------------------------------------------------------- */
35724+
35725+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
35726+{
35727+ struct au_whtmp_rmdir *whtmp;
dece6358 35728+ int err;
1308ab2a 35729+ unsigned int rdhash;
dece6358
AM
35730+
35731+ SiMustAnyLock(sb);
1facf9fc 35732+
be52b249 35733+ whtmp = kzalloc(sizeof(*whtmp), gfp);
dece6358
AM
35734+ if (unlikely(!whtmp)) {
35735+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 35736+ goto out;
dece6358 35737+ }
1facf9fc 35738+
1308ab2a 35739+ /* no estimation for dir size */
35740+ rdhash = au_sbi(sb)->si_rdhash;
35741+ if (!rdhash)
35742+ rdhash = AUFS_RDHASH_DEF;
35743+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
35744+ if (unlikely(err)) {
1c60b727 35745+ kfree(whtmp);
1308ab2a 35746+ whtmp = ERR_PTR(err);
35747+ }
dece6358 35748+
4f0767ce 35749+out:
dece6358 35750+ return whtmp;
1facf9fc 35751+}
35752+
35753+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
35754+{
027c5e7a 35755+ if (whtmp->br)
acd2b654 35756+ au_lcnt_dec(&whtmp->br->br_count);
1facf9fc 35757+ dput(whtmp->wh_dentry);
35758+ iput(whtmp->dir);
dece6358 35759+ au_nhash_wh_free(&whtmp->whlist);
1c60b727 35760+ kfree(whtmp);
1facf9fc 35761+}
35762+
35763+/*
35764+ * rmdir the whiteouted temporary named dir @h_dentry.
35765+ * @whlist: whiteouted children.
35766+ */
35767+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
35768+ struct dentry *wh_dentry, struct au_nhash *whlist)
35769+{
35770+ int err;
2000de60 35771+ unsigned int h_nlink;
1facf9fc 35772+ struct path h_tmp;
35773+ struct inode *wh_inode, *h_dir;
35774+ struct au_branch *br;
35775+
5527c038 35776+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
1facf9fc 35777+ IMustLock(h_dir);
35778+
35779+ br = au_sbr(dir->i_sb, bindex);
5527c038 35780+ wh_inode = d_inode(wh_dentry);
febd17d6 35781+ inode_lock_nested(wh_inode, AuLsc_I_CHILD);
1facf9fc 35782+
35783+ /*
35784+ * someone else might change some whiteouts while we were sleeping.
35785+ * it means this whlist may have an obsoleted entry.
35786+ */
35787+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
35788+ err = del_wh_children(wh_dentry, whlist, bindex, br);
35789+ else {
35790+ int wkq_err;
35791+ struct del_wh_children_args args = {
35792+ .errp = &err,
35793+ .h_dentry = wh_dentry,
1308ab2a 35794+ .whlist = whlist,
1facf9fc 35795+ .bindex = bindex,
35796+ .br = br
35797+ };
35798+
35799+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
35800+ if (unlikely(wkq_err))
35801+ err = wkq_err;
35802+ }
febd17d6 35803+ inode_unlock(wh_inode);
1facf9fc 35804+
35805+ if (!err) {
35806+ h_tmp.dentry = wh_dentry;
86dc4139 35807+ h_tmp.mnt = au_br_mnt(br);
2000de60 35808+ h_nlink = h_dir->i_nlink;
1facf9fc 35809+ err = vfsub_rmdir(h_dir, &h_tmp);
2000de60
JR
35810+ /* some fs doesn't change the parent nlink in some cases */
35811+ h_nlink -= h_dir->i_nlink;
1facf9fc 35812+ }
35813+
35814+ if (!err) {
5afbbe0d 35815+ if (au_ibtop(dir) == bindex) {
7f207e10 35816+ /* todo: dir->i_mutex is necessary */
1facf9fc 35817+ au_cpup_attr_timesizes(dir);
2000de60
JR
35818+ if (h_nlink)
35819+ vfsub_drop_nlink(dir);
1facf9fc 35820+ }
35821+ return 0; /* success */
35822+ }
35823+
523b37e3 35824+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 35825+ return err;
35826+}
35827+
35828+static void call_rmdir_whtmp(void *args)
35829+{
35830+ int err;
e49829fe 35831+ aufs_bindex_t bindex;
1facf9fc 35832+ struct au_whtmp_rmdir *a = args;
35833+ struct super_block *sb;
35834+ struct dentry *h_parent;
35835+ struct inode *h_dir;
1facf9fc 35836+ struct au_hinode *hdir;
35837+
35838+ /* rmdir by nfsd may cause deadlock with this i_mutex */
febd17d6 35839+ /* inode_lock(a->dir); */
e49829fe 35840+ err = -EROFS;
1facf9fc 35841+ sb = a->dir->i_sb;
e49829fe
JR
35842+ si_read_lock(sb, !AuLock_FLUSH);
35843+ if (!au_br_writable(a->br->br_perm))
35844+ goto out;
35845+ bindex = au_br_index(sb, a->br->br_id);
35846+ if (unlikely(bindex < 0))
1facf9fc 35847+ goto out;
35848+
35849+ err = -EIO;
1facf9fc 35850+ ii_write_lock_parent(a->dir);
35851+ h_parent = dget_parent(a->wh_dentry);
5527c038 35852+ h_dir = d_inode(h_parent);
e49829fe 35853+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
35854+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
35855+ if (unlikely(err))
35856+ goto out_mnt;
5afbbe0d 35857+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
35858+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
35859+ a->br);
86dc4139
AM
35860+ if (!err)
35861+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
5afbbe0d 35862+ au_hn_inode_unlock(hdir);
86dc4139
AM
35863+ vfsub_mnt_drop_write(au_br_mnt(a->br));
35864+
35865+out_mnt:
1facf9fc 35866+ dput(h_parent);
35867+ ii_write_unlock(a->dir);
4f0767ce 35868+out:
febd17d6 35869+ /* inode_unlock(a->dir); */
1facf9fc 35870+ au_whtmp_rmdir_free(a);
027c5e7a
AM
35871+ si_read_unlock(sb);
35872+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 35873+ if (unlikely(err))
35874+ AuIOErr("err %d\n", err);
35875+}
35876+
35877+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
35878+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
35879+{
35880+ int wkq_err;
e49829fe 35881+ struct super_block *sb;
1facf9fc 35882+
35883+ IMustLock(dir);
35884+
35885+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 35886+ sb = dir->i_sb;
1facf9fc 35887+ args->dir = au_igrab(dir);
e49829fe 35888+ args->br = au_sbr(sb, bindex);
acd2b654 35889+ au_lcnt_inc(&args->br->br_count);
1facf9fc 35890+ args->wh_dentry = dget(wh_dentry);
53392da6 35891+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 35892+ if (unlikely(wkq_err)) {
523b37e3 35893+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 35894+ au_whtmp_rmdir_free(args);
35895+ }
35896+}
7f207e10
AM
35897diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
35898--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 35899+++ linux/fs/aufs/whout.h 2018-08-12 23:43:05.463458173 +0200
062440b3
AM
35900@@ -0,0 +1,86 @@
35901+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 35902+/*
b00004a5 35903+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 35904+ *
35905+ * This program, aufs is free software; you can redistribute it and/or modify
35906+ * it under the terms of the GNU General Public License as published by
35907+ * the Free Software Foundation; either version 2 of the License, or
35908+ * (at your option) any later version.
dece6358
AM
35909+ *
35910+ * This program is distributed in the hope that it will be useful,
35911+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35912+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35913+ * GNU General Public License for more details.
35914+ *
35915+ * You should have received a copy of the GNU General Public License
523b37e3 35916+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 35917+ */
35918+
35919+/*
35920+ * whiteout for logical deletion and opaque directory
35921+ */
35922+
35923+#ifndef __AUFS_WHOUT_H__
35924+#define __AUFS_WHOUT_H__
35925+
35926+#ifdef __KERNEL__
35927+
1facf9fc 35928+#include "dir.h"
35929+
35930+/* whout.c */
35931+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
076b876e
AM
35932+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
35933+int au_diropq_test(struct dentry *h_dentry);
3c1bdaff 35934+struct au_branch;
1facf9fc 35935+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
35936+ struct qstr *prefix);
35937+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
35938+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
35939+ struct dentry *dentry);
86dc4139 35940+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 35941+
35942+/* diropq flags */
35943+#define AuDiropq_CREATE 1
35944+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
35945+#define au_fset_diropq(flags, name) \
35946+ do { (flags) |= AuDiropq_##name; } while (0)
35947+#define au_fclr_diropq(flags, name) \
35948+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 35949+
35950+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
35951+ unsigned int flags);
35952+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
35953+ struct au_branch *br);
35954+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
35955+ struct dentry *h_parent);
35956+
35957+/* real rmdir for the whiteout-ed dir */
35958+struct au_whtmp_rmdir {
35959+ struct inode *dir;
e49829fe 35960+ struct au_branch *br;
1facf9fc 35961+ struct dentry *wh_dentry;
dece6358 35962+ struct au_nhash whlist;
1facf9fc 35963+};
35964+
35965+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
35966+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
35967+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
35968+ struct dentry *wh_dentry, struct au_nhash *whlist);
35969+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
35970+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
35971+
35972+/* ---------------------------------------------------------------------- */
35973+
35974+static inline struct dentry *au_diropq_create(struct dentry *dentry,
35975+ aufs_bindex_t bindex)
35976+{
35977+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
35978+}
35979+
35980+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
35981+{
35982+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
35983+}
35984+
35985+#endif /* __KERNEL__ */
35986+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
35987diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
35988--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
35989+++ linux/fs/aufs/wkq.c 2018-10-23 12:33:35.599375796 +0200
35990@@ -0,0 +1,392 @@
cd7a4cd9 35991+// SPDX-License-Identifier: GPL-2.0
1facf9fc 35992+/*
b00004a5 35993+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 35994+ *
35995+ * This program, aufs is free software; you can redistribute it and/or modify
35996+ * it under the terms of the GNU General Public License as published by
35997+ * the Free Software Foundation; either version 2 of the License, or
35998+ * (at your option) any later version.
dece6358
AM
35999+ *
36000+ * This program is distributed in the hope that it will be useful,
36001+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36002+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36003+ * GNU General Public License for more details.
36004+ *
36005+ * You should have received a copy of the GNU General Public License
523b37e3 36006+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 36007+ */
36008+
36009+/*
36010+ * workqueue for asynchronous/super-io operations
acd2b654 36011+ * todo: try new credential scheme
1facf9fc 36012+ */
36013+
dece6358 36014+#include <linux/module.h>
1facf9fc 36015+#include "aufs.h"
36016+
9dbd164d 36017+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 36018+
9dbd164d 36019+static struct workqueue_struct *au_wkq;
1facf9fc 36020+
36021+struct au_wkinfo {
36022+ struct work_struct wk;
7f207e10 36023+ struct kobject *kobj;
1facf9fc 36024+
36025+ unsigned int flags; /* see wkq.h */
36026+
36027+ au_wkq_func_t func;
36028+ void *args;
36029+
8b6a4947
AM
36030+#ifdef CONFIG_LOCKDEP
36031+ int dont_check;
36032+ struct held_lock **hlock;
36033+#endif
36034+
1facf9fc 36035+ struct completion *comp;
36036+};
36037+
36038+/* ---------------------------------------------------------------------- */
8b6a4947
AM
36039+/*
36040+ * Aufs passes some operations to the workqueue such as the internal copyup.
36041+ * This scheme looks rather unnatural for LOCKDEP debugging feature, since the
36042+ * job run by workqueue depends upon the locks acquired in the other task.
36043+ * Delegating a small operation to the workqueue, aufs passes its lockdep
36044+ * information too. And the job in the workqueue restores the info in order to
36045+ * pretend as if it acquired those locks. This is just to make LOCKDEP work
36046+ * correctly and expectedly.
36047+ */
36048+
36049+#ifndef CONFIG_LOCKDEP
36050+AuStubInt0(au_wkq_lockdep_alloc, struct au_wkinfo *wkinfo);
36051+AuStubVoid(au_wkq_lockdep_free, struct au_wkinfo *wkinfo);
36052+AuStubVoid(au_wkq_lockdep_pre, struct au_wkinfo *wkinfo);
36053+AuStubVoid(au_wkq_lockdep_post, struct au_wkinfo *wkinfo);
36054+AuStubVoid(au_wkq_lockdep_init, struct au_wkinfo *wkinfo);
36055+#else
36056+static void au_wkq_lockdep_init(struct au_wkinfo *wkinfo)
36057+{
36058+ wkinfo->hlock = NULL;
36059+ wkinfo->dont_check = 0;
36060+}
36061+
36062+/*
36063+ * 1: matched
36064+ * 0: unmatched
36065+ */
36066+static int au_wkq_lockdep_test(struct lock_class_key *key, const char *name)
36067+{
36068+ static DEFINE_SPINLOCK(spin);
36069+ static struct {
36070+ char *name;
36071+ struct lock_class_key *key;
36072+ } a[] = {
36073+ { .name = "&sbinfo->si_rwsem" },
36074+ { .name = "&finfo->fi_rwsem" },
36075+ { .name = "&dinfo->di_rwsem" },
36076+ { .name = "&iinfo->ii_rwsem" }
36077+ };
36078+ static int set;
36079+ int i;
36080+
36081+ /* lockless read from 'set.' see below */
36082+ if (set == ARRAY_SIZE(a)) {
36083+ for (i = 0; i < ARRAY_SIZE(a); i++)
36084+ if (a[i].key == key)
36085+ goto match;
36086+ goto unmatch;
36087+ }
36088+
36089+ spin_lock(&spin);
36090+ if (set)
36091+ for (i = 0; i < ARRAY_SIZE(a); i++)
36092+ if (a[i].key == key) {
36093+ spin_unlock(&spin);
36094+ goto match;
36095+ }
36096+ for (i = 0; i < ARRAY_SIZE(a); i++) {
36097+ if (a[i].key) {
36098+ if (unlikely(a[i].key == key)) { /* rare but possible */
36099+ spin_unlock(&spin);
36100+ goto match;
36101+ } else
36102+ continue;
36103+ }
36104+ if (strstr(a[i].name, name)) {
36105+ /*
36106+ * the order of these three lines is important for the
36107+ * lockless read above.
36108+ */
36109+ a[i].key = key;
36110+ spin_unlock(&spin);
36111+ set++;
36112+ /* AuDbg("%d, %s\n", set, name); */
36113+ goto match;
36114+ }
36115+ }
36116+ spin_unlock(&spin);
36117+ goto unmatch;
36118+
36119+match:
36120+ return 1;
36121+unmatch:
36122+ return 0;
36123+}
36124+
36125+static int au_wkq_lockdep_alloc(struct au_wkinfo *wkinfo)
36126+{
36127+ int err, n;
36128+ struct task_struct *curr;
36129+ struct held_lock **hl, *held_locks, *p;
36130+
36131+ err = 0;
36132+ curr = current;
36133+ wkinfo->dont_check = lockdep_recursing(curr);
36134+ if (wkinfo->dont_check)
36135+ goto out;
36136+ n = curr->lockdep_depth;
36137+ if (!n)
36138+ goto out;
36139+
36140+ err = -ENOMEM;
36141+ wkinfo->hlock = kmalloc_array(n + 1, sizeof(*wkinfo->hlock), GFP_NOFS);
36142+ if (unlikely(!wkinfo->hlock))
36143+ goto out;
36144+
36145+ err = 0;
36146+#if 0
36147+ if (0 && au_debug_test()) /* left for debugging */
36148+ lockdep_print_held_locks(curr);
36149+#endif
36150+ held_locks = curr->held_locks;
36151+ hl = wkinfo->hlock;
36152+ while (n--) {
36153+ p = held_locks++;
36154+ if (au_wkq_lockdep_test(p->instance->key, p->instance->name))
36155+ *hl++ = p;
36156+ }
36157+ *hl = NULL;
36158+
36159+out:
36160+ return err;
36161+}
36162+
36163+static void au_wkq_lockdep_free(struct au_wkinfo *wkinfo)
36164+{
36165+ kfree(wkinfo->hlock);
36166+}
36167+
36168+static void au_wkq_lockdep_pre(struct au_wkinfo *wkinfo)
36169+{
36170+ struct held_lock *p, **hl = wkinfo->hlock;
36171+ int subclass;
36172+
36173+ if (wkinfo->dont_check)
36174+ lockdep_off();
36175+ if (!hl)
36176+ return;
36177+ while ((p = *hl++)) { /* assignment */
36178+ subclass = lockdep_hlock_class(p)->subclass;
36179+ /* AuDbg("%s, %d\n", p->instance->name, subclass); */
36180+ if (p->read)
36181+ rwsem_acquire_read(p->instance, subclass, 0,
36182+ /*p->acquire_ip*/_RET_IP_);
36183+ else
36184+ rwsem_acquire(p->instance, subclass, 0,
36185+ /*p->acquire_ip*/_RET_IP_);
36186+ }
36187+}
36188+
36189+static void au_wkq_lockdep_post(struct au_wkinfo *wkinfo)
36190+{
36191+ struct held_lock *p, **hl = wkinfo->hlock;
36192+
36193+ if (wkinfo->dont_check)
36194+ lockdep_on();
36195+ if (!hl)
36196+ return;
36197+ while ((p = *hl++)) /* assignment */
36198+ rwsem_release(p->instance, 0, /*p->acquire_ip*/_RET_IP_);
36199+}
36200+#endif
1facf9fc 36201+
1facf9fc 36202+static void wkq_func(struct work_struct *wk)
36203+{
36204+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
36205+
2dfbb274 36206+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
36207+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
36208+
8b6a4947 36209+ au_wkq_lockdep_pre(wkinfo);
1facf9fc 36210+ wkinfo->func(wkinfo->args);
8b6a4947 36211+ au_wkq_lockdep_post(wkinfo);
1facf9fc 36212+ if (au_ftest_wkq(wkinfo->flags, WAIT))
36213+ complete(wkinfo->comp);
36214+ else {
7f207e10 36215+ kobject_put(wkinfo->kobj);
9dbd164d 36216+ module_put(THIS_MODULE); /* todo: ?? */
1c60b727 36217+ kfree(wkinfo);
1facf9fc 36218+ }
36219+}
36220+
36221+/*
36222+ * Since struct completion is large, try allocating it dynamically.
36223+ */
c2b27bf2 36224+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 36225+#define AuWkqCompDeclare(name) struct completion *comp = NULL
36226+
36227+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
36228+{
36229+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
36230+ if (*comp) {
36231+ init_completion(*comp);
36232+ wkinfo->comp = *comp;
36233+ return 0;
36234+ }
36235+ return -ENOMEM;
36236+}
36237+
36238+static void au_wkq_comp_free(struct completion *comp)
36239+{
1c60b727 36240+ kfree(comp);
1facf9fc 36241+}
36242+
36243+#else
36244+
36245+/* no braces */
36246+#define AuWkqCompDeclare(name) \
36247+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
36248+ struct completion *comp = &_ ## name
36249+
36250+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
36251+{
36252+ wkinfo->comp = *comp;
36253+ return 0;
36254+}
36255+
36256+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
36257+{
36258+ /* empty */
36259+}
36260+#endif /* 4KSTACKS */
36261+
53392da6 36262+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 36263+{
53392da6
AM
36264+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
36265+ if (au_wkq_test()) {
38d290e6 36266+ AuWarn1("wkq from wkq, unless silly-rename on NFS,"
acd2b654
AM
36267+ " due to a dead dir by UDBA,"
36268+ " or async xino write?\n");
53392da6
AM
36269+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
36270+ }
36271+ } else
36272+ au_dbg_verify_kthread();
36273+
36274+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 36275+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 36276+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
36277+ } else {
36278+ INIT_WORK(&wkinfo->wk, wkq_func);
36279+ schedule_work(&wkinfo->wk);
36280+ }
1facf9fc 36281+}
36282+
7f207e10
AM
36283+/*
36284+ * Be careful. It is easy to make deadlock happen.
36285+ * processA: lock, wkq and wait
36286+ * processB: wkq and wait, lock in wkq
36287+ * --> deadlock
36288+ */
b752ccd1 36289+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 36290+{
36291+ int err;
36292+ AuWkqCompDeclare(comp);
36293+ struct au_wkinfo wkinfo = {
b752ccd1 36294+ .flags = flags,
1facf9fc 36295+ .func = func,
36296+ .args = args
36297+ };
36298+
36299+ err = au_wkq_comp_alloc(&wkinfo, &comp);
8b6a4947
AM
36300+ if (unlikely(err))
36301+ goto out;
36302+ err = au_wkq_lockdep_alloc(&wkinfo);
36303+ if (unlikely(err))
36304+ goto out_comp;
1facf9fc 36305+ if (!err) {
53392da6 36306+ au_wkq_run(&wkinfo);
1facf9fc 36307+ /* no timeout, no interrupt */
36308+ wait_for_completion(wkinfo.comp);
1facf9fc 36309+ }
8b6a4947 36310+ au_wkq_lockdep_free(&wkinfo);
1facf9fc 36311+
8b6a4947
AM
36312+out_comp:
36313+ au_wkq_comp_free(comp);
36314+out:
36315+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 36316+ return err;
1facf9fc 36317+}
36318+
027c5e7a
AM
36319+/*
36320+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
36321+ * problem in a concurrent umounting.
36322+ */
53392da6
AM
36323+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
36324+ unsigned int flags)
1facf9fc 36325+{
36326+ int err;
36327+ struct au_wkinfo *wkinfo;
36328+
f0c0a007 36329+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
1facf9fc 36330+
36331+ /*
36332+ * wkq_func() must free this wkinfo.
36333+ * it highly depends upon the implementation of workqueue.
36334+ */
36335+ err = 0;
36336+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
36337+ if (wkinfo) {
7f207e10 36338+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 36339+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 36340+ wkinfo->func = func;
36341+ wkinfo->args = args;
36342+ wkinfo->comp = NULL;
8b6a4947 36343+ au_wkq_lockdep_init(wkinfo);
7f207e10 36344+ kobject_get(wkinfo->kobj);
9dbd164d 36345+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 36346+
53392da6 36347+ au_wkq_run(wkinfo);
1facf9fc 36348+ } else {
36349+ err = -ENOMEM;
e49829fe 36350+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 36351+ }
36352+
36353+ return err;
36354+}
36355+
36356+/* ---------------------------------------------------------------------- */
36357+
36358+void au_nwt_init(struct au_nowait_tasks *nwt)
36359+{
f0c0a007
AM
36360+ atomic_set(&nwt->nw_len, 0);
36361+ /* smp_mb(); */ /* atomic_set */
1facf9fc 36362+ init_waitqueue_head(&nwt->nw_wq);
36363+}
36364+
36365+void au_wkq_fin(void)
36366+{
9dbd164d 36367+ destroy_workqueue(au_wkq);
1facf9fc 36368+}
36369+
36370+int __init au_wkq_init(void)
36371+{
9dbd164d 36372+ int err;
b752ccd1
AM
36373+
36374+ err = 0;
86dc4139 36375+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
36376+ if (IS_ERR(au_wkq))
36377+ err = PTR_ERR(au_wkq);
36378+ else if (!au_wkq)
36379+ err = -ENOMEM;
b752ccd1
AM
36380+
36381+ return err;
1facf9fc 36382+}
7f207e10
AM
36383diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
36384--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
36385+++ linux/fs/aufs/wkq.h 2018-10-23 12:33:35.599375796 +0200
36386@@ -0,0 +1,89 @@
062440b3 36387+/* SPDX-License-Identifier: GPL-2.0 */
1facf9fc 36388+/*
b00004a5 36389+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 36390+ *
36391+ * This program, aufs is free software; you can redistribute it and/or modify
36392+ * it under the terms of the GNU General Public License as published by
36393+ * the Free Software Foundation; either version 2 of the License, or
36394+ * (at your option) any later version.
dece6358
AM
36395+ *
36396+ * This program is distributed in the hope that it will be useful,
36397+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36398+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36399+ * GNU General Public License for more details.
36400+ *
36401+ * You should have received a copy of the GNU General Public License
523b37e3 36402+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 36403+ */
36404+
36405+/*
36406+ * workqueue for asynchronous/super-io operations
36407+ * todo: try new credentials management scheme
36408+ */
36409+
36410+#ifndef __AUFS_WKQ_H__
36411+#define __AUFS_WKQ_H__
36412+
36413+#ifdef __KERNEL__
36414+
8b6a4947 36415+#include <linux/wait.h>
5afbbe0d 36416+
dece6358
AM
36417+struct super_block;
36418+
1facf9fc 36419+/* ---------------------------------------------------------------------- */
36420+
36421+/*
36422+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
36423+ */
36424+struct au_nowait_tasks {
f0c0a007 36425+ atomic_t nw_len;
1facf9fc 36426+ wait_queue_head_t nw_wq;
36427+};
36428+
36429+/* ---------------------------------------------------------------------- */
36430+
36431+typedef void (*au_wkq_func_t)(void *args);
36432+
36433+/* wkq flags */
36434+#define AuWkq_WAIT 1
9dbd164d 36435+#define AuWkq_NEST (1 << 1)
1facf9fc 36436+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
36437+#define au_fset_wkq(flags, name) \
36438+ do { (flags) |= AuWkq_##name; } while (0)
36439+#define au_fclr_wkq(flags, name) \
36440+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 36441+
36442+/* wkq.c */
b752ccd1 36443+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
36444+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
36445+ unsigned int flags);
1facf9fc 36446+void au_nwt_init(struct au_nowait_tasks *nwt);
36447+int __init au_wkq_init(void);
36448+void au_wkq_fin(void);
36449+
36450+/* ---------------------------------------------------------------------- */
36451+
53392da6
AM
36452+static inline int au_wkq_test(void)
36453+{
36454+ return current->flags & PF_WQ_WORKER;
36455+}
36456+
b752ccd1 36457+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 36458+{
b752ccd1 36459+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 36460+}
36461+
36462+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
36463+{
f0c0a007 36464+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 36465+ wake_up_all(&nwt->nw_wq);
36466+}
36467+
36468+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
36469+{
f0c0a007 36470+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
1facf9fc 36471+ return 0;
36472+}
36473+
36474+#endif /* __KERNEL__ */
36475+#endif /* __AUFS_WKQ_H__ */
c1595e42
JR
36476diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
36477--- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100
cd7a4cd9 36478+++ linux/fs/aufs/xattr.c 2018-08-12 23:43:05.466791610 +0200
062440b3 36479@@ -0,0 +1,356 @@
cd7a4cd9 36480+// SPDX-License-Identifier: GPL-2.0
c1595e42 36481+/*
b00004a5 36482+ * Copyright (C) 2014-2018 Junjiro R. Okajima
c1595e42
JR
36483+ *
36484+ * This program, aufs is free software; you can redistribute it and/or modify
36485+ * it under the terms of the GNU General Public License as published by
36486+ * the Free Software Foundation; either version 2 of the License, or
36487+ * (at your option) any later version.
36488+ *
36489+ * This program is distributed in the hope that it will be useful,
36490+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36491+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36492+ * GNU General Public License for more details.
36493+ *
36494+ * You should have received a copy of the GNU General Public License
36495+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
36496+ */
36497+
36498+/*
36499+ * handling xattr functions
36500+ */
36501+
a2654f78
AM
36502+#include <linux/fs.h>
36503+#include <linux/posix_acl_xattr.h>
c1595e42
JR
36504+#include <linux/xattr.h>
36505+#include "aufs.h"
36506+
36507+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
36508+{
36509+ if (!ignore_flags)
36510+ goto out;
36511+ switch (err) {
36512+ case -ENOMEM:
36513+ case -EDQUOT:
36514+ goto out;
36515+ }
36516+
36517+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
36518+ err = 0;
36519+ goto out;
36520+ }
36521+
36522+#define cmp(brattr, prefix) do { \
36523+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \
36524+ XATTR_##prefix##_PREFIX_LEN)) { \
36525+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \
36526+ err = 0; \
36527+ goto out; \
36528+ } \
36529+ } while (0)
36530+
36531+ cmp(SEC, SECURITY);
36532+ cmp(SYS, SYSTEM);
36533+ cmp(TR, TRUSTED);
36534+ cmp(USR, USER);
36535+#undef cmp
36536+
36537+ if (ignore_flags & AuBrAttr_ICEX_OTH)
36538+ err = 0;
36539+
36540+out:
36541+ return err;
36542+}
36543+
36544+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
36545+
36546+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe
AM
36547+ char *name, char **buf, unsigned int ignore_flags,
36548+ unsigned int verbose)
c1595e42
JR
36549+{
36550+ int err;
36551+ ssize_t ssz;
36552+ struct inode *h_idst;
36553+
36554+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
36555+ err = ssz;
36556+ if (unlikely(err <= 0)) {
c1595e42
JR
36557+ if (err == -ENODATA
36558+ || (err == -EOPNOTSUPP
b912730e 36559+ && ((ignore_flags & au_xattr_out_of_list)
5527c038 36560+ || (au_test_nfs_noacl(d_inode(h_src))
b912730e
AM
36561+ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)
36562+ || !strcmp(name,
36563+ XATTR_NAME_POSIX_ACL_DEFAULT))))
36564+ ))
c1595e42 36565+ err = 0;
b912730e
AM
36566+ if (err && (verbose || au_debug_test()))
36567+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
36568+ goto out;
36569+ }
36570+
36571+ /* unlock it temporary */
5527c038 36572+ h_idst = d_inode(h_dst);
febd17d6 36573+ inode_unlock(h_idst);
c1595e42 36574+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
febd17d6 36575+ inode_lock_nested(h_idst, AuLsc_I_CHILD2);
c1595e42 36576+ if (unlikely(err)) {
7e9cd9fe
AM
36577+ if (verbose || au_debug_test())
36578+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
36579+ err = au_xattr_ignore(err, name, ignore_flags);
36580+ }
36581+
36582+out:
36583+ return err;
36584+}
36585+
7e9cd9fe
AM
36586+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
36587+ unsigned int verbose)
c1595e42
JR
36588+{
36589+ int err, unlocked, acl_access, acl_default;
36590+ ssize_t ssz;
36591+ struct inode *h_isrc, *h_idst;
36592+ char *value, *p, *o, *e;
36593+
36594+ /* try stopping to update the source inode while we are referencing */
7e9cd9fe 36595+ /* there should not be the parent-child relationship between them */
5527c038
JR
36596+ h_isrc = d_inode(h_src);
36597+ h_idst = d_inode(h_dst);
febd17d6 36598+ inode_unlock(h_idst);
be118d29 36599+ inode_lock_shared_nested(h_isrc, AuLsc_I_CHILD);
febd17d6 36600+ inode_lock_nested(h_idst, AuLsc_I_CHILD2);
c1595e42
JR
36601+ unlocked = 0;
36602+
36603+ /* some filesystems don't list POSIX ACL, for example tmpfs */
36604+ ssz = vfs_listxattr(h_src, NULL, 0);
36605+ err = ssz;
36606+ if (unlikely(err < 0)) {
36607+ AuTraceErr(err);
36608+ if (err == -ENODATA
36609+ || err == -EOPNOTSUPP)
36610+ err = 0; /* ignore */
36611+ goto out;
36612+ }
36613+
36614+ err = 0;
36615+ p = NULL;
36616+ o = NULL;
36617+ if (ssz) {
36618+ err = -ENOMEM;
36619+ p = kmalloc(ssz, GFP_NOFS);
36620+ o = p;
36621+ if (unlikely(!p))
36622+ goto out;
36623+ err = vfs_listxattr(h_src, p, ssz);
36624+ }
3c1bdaff 36625+ inode_unlock_shared(h_isrc);
c1595e42
JR
36626+ unlocked = 1;
36627+ AuDbg("err %d, ssz %zd\n", err, ssz);
36628+ if (unlikely(err < 0))
36629+ goto out_free;
36630+
36631+ err = 0;
36632+ e = p + ssz;
36633+ value = NULL;
36634+ acl_access = 0;
36635+ acl_default = 0;
36636+ while (!err && p < e) {
36637+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
36638+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
36639+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
36640+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
36641+ - 1);
7e9cd9fe
AM
36642+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags,
36643+ verbose);
c1595e42
JR
36644+ p += strlen(p) + 1;
36645+ }
36646+ AuTraceErr(err);
36647+ ignore_flags |= au_xattr_out_of_list;
36648+ if (!err && !acl_access) {
36649+ err = au_do_cpup_xattr(h_dst, h_src,
36650+ XATTR_NAME_POSIX_ACL_ACCESS, &value,
7e9cd9fe 36651+ ignore_flags, verbose);
c1595e42
JR
36652+ AuTraceErr(err);
36653+ }
36654+ if (!err && !acl_default) {
36655+ err = au_do_cpup_xattr(h_dst, h_src,
36656+ XATTR_NAME_POSIX_ACL_DEFAULT, &value,
7e9cd9fe 36657+ ignore_flags, verbose);
c1595e42
JR
36658+ AuTraceErr(err);
36659+ }
36660+
8b6a4947 36661+ kfree(value);
c1595e42
JR
36662+
36663+out_free:
8b6a4947 36664+ kfree(o);
c1595e42
JR
36665+out:
36666+ if (!unlocked)
3c1bdaff 36667+ inode_unlock_shared(h_isrc);
c1595e42
JR
36668+ AuTraceErr(err);
36669+ return err;
36670+}
36671+
36672+/* ---------------------------------------------------------------------- */
36673+
a2654f78
AM
36674+static int au_smack_reentering(struct super_block *sb)
36675+{
36676+#if IS_ENABLED(CONFIG_SECURITY_SMACK)
36677+ /*
36678+ * as a part of lookup, smack_d_instantiate() is called, and it calls
36679+ * i_op->getxattr(). ouch.
36680+ */
36681+ return si_pid_test(sb);
36682+#else
36683+ return 0;
36684+#endif
36685+}
36686+
c1595e42
JR
36687+enum {
36688+ AU_XATTR_LIST,
36689+ AU_XATTR_GET
36690+};
36691+
36692+struct au_lgxattr {
36693+ int type;
36694+ union {
36695+ struct {
36696+ char *list;
36697+ size_t size;
36698+ } list;
36699+ struct {
36700+ const char *name;
36701+ void *value;
36702+ size_t size;
36703+ } get;
36704+ } u;
36705+};
36706+
36707+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
36708+{
36709+ ssize_t err;
a2654f78 36710+ int reenter;
c1595e42
JR
36711+ struct path h_path;
36712+ struct super_block *sb;
36713+
36714+ sb = dentry->d_sb;
a2654f78
AM
36715+ reenter = au_smack_reentering(sb);
36716+ if (!reenter) {
36717+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
36718+ if (unlikely(err))
36719+ goto out;
36720+ }
36721+ err = au_h_path_getattr(dentry, /*force*/1, &h_path, reenter);
c1595e42
JR
36722+ if (unlikely(err))
36723+ goto out_si;
36724+ if (unlikely(!h_path.dentry))
36725+ /* illegally overlapped or something */
36726+ goto out_di; /* pretending success */
36727+
36728+ /* always topmost entry only */
36729+ switch (arg->type) {
36730+ case AU_XATTR_LIST:
36731+ err = vfs_listxattr(h_path.dentry,
36732+ arg->u.list.list, arg->u.list.size);
36733+ break;
36734+ case AU_XATTR_GET:
5afbbe0d 36735+ AuDebugOn(d_is_negative(h_path.dentry));
c1595e42
JR
36736+ err = vfs_getxattr(h_path.dentry,
36737+ arg->u.get.name, arg->u.get.value,
36738+ arg->u.get.size);
36739+ break;
36740+ }
36741+
36742+out_di:
a2654f78
AM
36743+ if (!reenter)
36744+ di_read_unlock(dentry, AuLock_IR);
c1595e42 36745+out_si:
a2654f78
AM
36746+ if (!reenter)
36747+ si_read_unlock(sb);
c1595e42
JR
36748+out:
36749+ AuTraceErr(err);
36750+ return err;
36751+}
36752+
36753+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
36754+{
36755+ struct au_lgxattr arg = {
36756+ .type = AU_XATTR_LIST,
36757+ .u.list = {
36758+ .list = list,
36759+ .size = size
36760+ },
36761+ };
36762+
36763+ return au_lgxattr(dentry, &arg);
36764+}
36765+
f2c43d5f
AM
36766+static ssize_t au_getxattr(struct dentry *dentry,
36767+ struct inode *inode __maybe_unused,
36768+ const char *name, void *value, size_t size)
c1595e42
JR
36769+{
36770+ struct au_lgxattr arg = {
36771+ .type = AU_XATTR_GET,
36772+ .u.get = {
36773+ .name = name,
36774+ .value = value,
36775+ .size = size
36776+ },
36777+ };
36778+
36779+ return au_lgxattr(dentry, &arg);
36780+}
36781+
f2c43d5f
AM
36782+static int au_setxattr(struct dentry *dentry, struct inode *inode,
36783+ const char *name, const void *value, size_t size,
36784+ int flags)
c1595e42 36785+{
f2c43d5f 36786+ struct au_sxattr arg = {
c1595e42
JR
36787+ .type = AU_XATTR_SET,
36788+ .u.set = {
36789+ .name = name,
36790+ .value = value,
36791+ .size = size,
36792+ .flags = flags
36793+ },
36794+ };
36795+
f2c43d5f 36796+ return au_sxattr(dentry, inode, &arg);
c1595e42
JR
36797+}
36798+
36799+/* ---------------------------------------------------------------------- */
36800+
f2c43d5f
AM
36801+static int au_xattr_get(const struct xattr_handler *handler,
36802+ struct dentry *dentry, struct inode *inode,
36803+ const char *name, void *buffer, size_t size)
c1595e42 36804+{
f2c43d5f 36805+ return au_getxattr(dentry, inode, name, buffer, size);
c1595e42
JR
36806+}
36807+
f2c43d5f
AM
36808+static int au_xattr_set(const struct xattr_handler *handler,
36809+ struct dentry *dentry, struct inode *inode,
36810+ const char *name, const void *value, size_t size,
36811+ int flags)
c1595e42 36812+{
f2c43d5f 36813+ return au_setxattr(dentry, inode, name, value, size, flags);
c1595e42
JR
36814+}
36815+
36816+static const struct xattr_handler au_xattr_handler = {
f2c43d5f
AM
36817+ .name = "",
36818+ .prefix = "",
c1595e42
JR
36819+ .get = au_xattr_get,
36820+ .set = au_xattr_set
c1595e42
JR
36821+};
36822+
36823+static const struct xattr_handler *au_xattr_handlers[] = {
a2654f78
AM
36824+#ifdef CONFIG_FS_POSIX_ACL
36825+ &posix_acl_access_xattr_handler,
36826+ &posix_acl_default_xattr_handler,
36827+#endif
36828+ &au_xattr_handler, /* must be last */
f2c43d5f 36829+ NULL
c1595e42
JR
36830+};
36831+
36832+void au_xattr_init(struct super_block *sb)
36833+{
f2c43d5f 36834+ sb->s_xattr = au_xattr_handlers;
c1595e42 36835+}
7f207e10
AM
36836diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
36837--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
acd2b654
AM
36838+++ linux/fs/aufs/xino.c 2018-10-23 12:33:35.599375796 +0200
36839@@ -0,0 +1,1890 @@
cd7a4cd9 36840+// SPDX-License-Identifier: GPL-2.0
1facf9fc 36841+/*
b00004a5 36842+ * Copyright (C) 2005-2018 Junjiro R. Okajima
1facf9fc 36843+ *
36844+ * This program, aufs is free software; you can redistribute it and/or modify
36845+ * it under the terms of the GNU General Public License as published by
36846+ * the Free Software Foundation; either version 2 of the License, or
36847+ * (at your option) any later version.
dece6358
AM
36848+ *
36849+ * This program is distributed in the hope that it will be useful,
36850+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
36851+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36852+ * GNU General Public License for more details.
36853+ *
36854+ * You should have received a copy of the GNU General Public License
523b37e3 36855+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 36856+ */
36857+
36858+/*
36859+ * external inode number translation table and bitmap
062440b3
AM
36860+ *
36861+ * things to consider
36862+ * - the lifetime
36863+ * + au_xino object
36864+ * + XINO files (xino, xib, xigen)
36865+ * + dynamic debugfs entries (xiN)
36866+ * + static debugfs entries (xib, xigen)
36867+ * + static sysfs entry (xi_path)
36868+ * - several entry points to handle them.
36869+ * + mount(2) without xino option (default)
36870+ * + mount(2) with xino option
36871+ * + mount(2) with noxino option
36872+ * + umount(2)
36873+ * + remount with add/del branches
36874+ * + remount with xino/noxino options
1facf9fc 36875+ */
36876+
36877+#include <linux/seq_file.h>
392086de 36878+#include <linux/statfs.h>
1facf9fc 36879+#include "aufs.h"
36880+
062440b3
AM
36881+static aufs_bindex_t sbr_find_shared(struct super_block *sb, aufs_bindex_t btop,
36882+ aufs_bindex_t bbot,
36883+ struct super_block *h_sb)
1facf9fc 36884+{
062440b3
AM
36885+ /* todo: try binary-search if the branches are many */
36886+ for (; btop <= bbot; btop++)
36887+ if (h_sb == au_sbr_sb(sb, btop))
36888+ return btop;
36889+ return -1;
be52b249
AM
36890+}
36891+
062440b3
AM
36892+/*
36893+ * find another branch who is on the same filesystem of the specified
36894+ * branch{@btgt}. search until @bbot.
36895+ */
36896+static aufs_bindex_t is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
36897+ aufs_bindex_t bbot)
1facf9fc 36898+{
062440b3
AM
36899+ aufs_bindex_t bindex;
36900+ struct super_block *tgt_sb;
1facf9fc 36901+
062440b3
AM
36902+ tgt_sb = au_sbr_sb(sb, btgt);
36903+ bindex = sbr_find_shared(sb, /*btop*/0, btgt - 1, tgt_sb);
36904+ if (bindex < 0)
36905+ bindex = sbr_find_shared(sb, btgt + 1, bbot, tgt_sb);
1facf9fc 36906+
062440b3 36907+ return bindex;
1facf9fc 36908+}
36909+
36910+/* ---------------------------------------------------------------------- */
36911+
36912+/*
062440b3 36913+ * stop unnecessary notify events at creating xino files
1facf9fc 36914+ */
acd2b654
AM
36915+
36916+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry)
36917+{
36918+ aufs_bindex_t bfound, bindex, bbot;
36919+ struct dentry *parent;
36920+ struct au_branch *br;
36921+
36922+ bfound = -1;
36923+ parent = dentry->d_parent; /* safe d_parent access */
36924+ bbot = au_sbbot(sb);
36925+ for (bindex = 0; bindex <= bbot; bindex++) {
36926+ br = au_sbr(sb, bindex);
36927+ if (au_br_dentry(br) == parent) {
36928+ bfound = bindex;
36929+ break;
36930+ }
36931+ }
36932+
36933+ AuDbg("bfound b%d\n", bfound);
36934+ return bfound;
36935+}
36936+
062440b3
AM
36937+struct au_xino_lock_dir {
36938+ struct au_hinode *hdir;
36939+ struct dentry *parent;
36940+ struct inode *dir;
36941+};
36942+
36943+static struct dentry *au_dget_parent_lock(struct dentry *dentry,
36944+ unsigned int lsc)
1facf9fc 36945+{
062440b3
AM
36946+ struct dentry *parent;
36947+ struct inode *dir;
1facf9fc 36948+
062440b3 36949+ parent = dget_parent(dentry);
5527c038 36950+ dir = d_inode(parent);
062440b3
AM
36951+ inode_lock_nested(dir, lsc);
36952+#if 0 /* it should not happen */
36953+ spin_lock(&dentry->d_lock);
36954+ if (unlikely(dentry->d_parent != parent)) {
36955+ spin_unlock(&dentry->d_lock);
36956+ inode_unlock(dir);
36957+ dput(parent);
36958+ parent = NULL;
1facf9fc 36959+ goto out;
36960+ }
062440b3 36961+ spin_unlock(&dentry->d_lock);
1facf9fc 36962+
4f0767ce 36963+out:
062440b3
AM
36964+#endif
36965+ return parent;
1facf9fc 36966+}
36967+
062440b3 36968+static void au_xino_lock_dir(struct super_block *sb, struct path *xipath,
1facf9fc 36969+ struct au_xino_lock_dir *ldir)
36970+{
acd2b654 36971+ aufs_bindex_t bindex;
1facf9fc 36972+
36973+ ldir->hdir = NULL;
acd2b654 36974+ bindex = au_xi_root(sb, xipath->dentry);
1facf9fc 36975+ if (bindex >= 0) {
062440b3 36976+ /* rw branch root */
5527c038 36977+ ldir->hdir = au_hi(d_inode(sb->s_root), bindex);
5afbbe0d 36978+ au_hn_inode_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 36979+ } else {
062440b3
AM
36980+ /* other */
36981+ ldir->parent = au_dget_parent_lock(xipath->dentry,
36982+ AuLsc_I_PARENT);
febd17d6 36983+ ldir->dir = d_inode(ldir->parent);
1facf9fc 36984+ }
36985+}
36986+
36987+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
36988+{
36989+ if (ldir->hdir)
5afbbe0d 36990+ au_hn_inode_unlock(ldir->hdir);
1facf9fc 36991+ else {
febd17d6 36992+ inode_unlock(ldir->dir);
1facf9fc 36993+ dput(ldir->parent);
36994+ }
36995+}
36996+
36997+/* ---------------------------------------------------------------------- */
36998+
062440b3
AM
36999+/*
37000+ * create and set a new xino file
37001+ */
37002+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent)
37003+{
37004+ struct file *file;
37005+ struct dentry *h_parent, *d;
37006+ struct inode *h_dir, *inode;
37007+ int err;
37008+
37009+ /*
37010+ * at mount-time, and the xino file is the default path,
37011+ * hnotify is disabled so we have no notify events to ignore.
37012+ * when a user specified the xino, we cannot get au_hdir to be ignored.
37013+ */
37014+ file = vfsub_filp_open(fpath, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
37015+ /* | __FMODE_NONOTIFY */,
cd7a4cd9 37016+ 0666);
062440b3
AM
37017+ if (IS_ERR(file)) {
37018+ if (!silent)
37019+ pr_err("open %s(%ld)\n", fpath, PTR_ERR(file));
37020+ return file;
37021+ }
37022+
37023+ /* keep file count */
37024+ err = 0;
37025+ d = file->f_path.dentry;
37026+ h_parent = au_dget_parent_lock(d, AuLsc_I_PARENT);
37027+ /* mnt_want_write() is unnecessary here */
37028+ h_dir = d_inode(h_parent);
37029+ inode = file_inode(file);
37030+ /* no delegation since it is just created */
37031+ if (inode->i_nlink)
37032+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL,
37033+ /*force*/0);
37034+ inode_unlock(h_dir);
37035+ dput(h_parent);
37036+ if (unlikely(err)) {
37037+ if (!silent)
37038+ pr_err("unlink %s(%d)\n", fpath, err);
37039+ goto out;
37040+ }
37041+
37042+ err = -EINVAL;
37043+ if (unlikely(sb == d->d_sb)) {
37044+ if (!silent)
37045+ pr_err("%s must be outside\n", fpath);
37046+ goto out;
37047+ }
37048+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
37049+ if (!silent)
37050+ pr_err("xino doesn't support %s(%s)\n",
37051+ fpath, au_sbtype(d->d_sb));
37052+ goto out;
37053+ }
37054+ return file; /* success */
37055+
37056+out:
37057+ fput(file);
37058+ file = ERR_PTR(err);
37059+ return file;
37060+}
37061+
37062+/*
37063+ * create a new xinofile at the same place/path as @base.
37064+ */
37065+struct file *au_xino_create2(struct super_block *sb, struct path *base,
37066+ struct file *copy_src)
37067+{
37068+ struct file *file;
37069+ struct dentry *dentry, *parent;
37070+ struct inode *dir, *delegated;
37071+ struct qstr *name;
37072+ struct path path;
37073+ int err, do_unlock;
37074+ struct au_xino_lock_dir ldir;
37075+
37076+ do_unlock = 1;
37077+ au_xino_lock_dir(sb, base, &ldir);
37078+ dentry = base->dentry;
37079+ parent = dentry->d_parent; /* dir inode is locked */
37080+ dir = d_inode(parent);
37081+ IMustLock(dir);
37082+
37083+ name = &dentry->d_name;
37084+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
37085+ if (IS_ERR(path.dentry)) {
37086+ file = (void *)path.dentry;
37087+ pr_err("%pd lookup err %ld\n", dentry, PTR_ERR(path.dentry));
37088+ goto out;
37089+ }
37090+
37091+ /* no need to mnt_want_write() since we call dentry_open() later */
cd7a4cd9 37092+ err = vfs_create(dir, path.dentry, 0666, NULL);
062440b3
AM
37093+ if (unlikely(err)) {
37094+ file = ERR_PTR(err);
37095+ pr_err("%pd create err %d\n", dentry, err);
37096+ goto out_dput;
37097+ }
37098+
37099+ path.mnt = base->mnt;
37100+ file = vfsub_dentry_open(&path,
37101+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
37102+ /* | __FMODE_NONOTIFY */);
37103+ if (IS_ERR(file)) {
37104+ pr_err("%pd open err %ld\n", dentry, PTR_ERR(file));
37105+ goto out_dput;
37106+ }
37107+
37108+ delegated = NULL;
37109+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
37110+ au_xino_unlock_dir(&ldir);
37111+ do_unlock = 0;
37112+ if (unlikely(err == -EWOULDBLOCK)) {
37113+ pr_warn("cannot retry for NFSv4 delegation"
37114+ " for an internal unlink\n");
37115+ iput(delegated);
37116+ }
37117+ if (unlikely(err)) {
37118+ pr_err("%pd unlink err %d\n", dentry, err);
37119+ goto out_fput;
37120+ }
37121+
37122+ if (copy_src) {
37123+ /* no one can touch copy_src xino */
37124+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
37125+ if (unlikely(err)) {
37126+ pr_err("%pd copy err %d\n", dentry, err);
37127+ goto out_fput;
37128+ }
37129+ }
37130+ goto out_dput; /* success */
1facf9fc 37131+
062440b3
AM
37132+out_fput:
37133+ fput(file);
37134+ file = ERR_PTR(err);
37135+out_dput:
37136+ dput(path.dentry);
37137+out:
37138+ if (do_unlock)
37139+ au_xino_unlock_dir(&ldir);
37140+ return file;
37141+}
37142+
acd2b654
AM
37143+struct file *au_xino_file1(struct au_xino *xi)
37144+{
37145+ struct file *file;
37146+ unsigned int u, nfile;
37147+
37148+ file = NULL;
37149+ nfile = xi->xi_nfile;
37150+ for (u = 0; u < nfile; u++) {
37151+ file = xi->xi_file[u];
37152+ if (file)
37153+ break;
37154+ }
37155+
37156+ return file;
37157+}
37158+
37159+static int au_xino_file_set(struct au_xino *xi, int idx, struct file *file)
37160+{
37161+ int err;
37162+ struct file *f;
37163+ void *p;
37164+
37165+ if (file)
37166+ get_file(file);
37167+
37168+ err = 0;
37169+ f = NULL;
37170+ if (idx < xi->xi_nfile) {
37171+ f = xi->xi_file[idx];
37172+ if (f)
37173+ fput(f);
37174+ } else {
37175+ p = au_kzrealloc(xi->xi_file,
37176+ sizeof(*xi->xi_file) * xi->xi_nfile,
37177+ sizeof(*xi->xi_file) * (idx + 1),
37178+ GFP_NOFS, /*may_shrink*/0);
37179+ if (p) {
37180+ MtxMustLock(&xi->xi_mtx);
37181+ xi->xi_file = p;
37182+ xi->xi_nfile = idx + 1;
37183+ } else {
37184+ err = -ENOMEM;
37185+ if (file)
37186+ fput(file);
37187+ goto out;
37188+ }
37189+ }
37190+ xi->xi_file[idx] = file;
37191+
37192+out:
37193+ return err;
37194+}
37195+
37196+/*
37197+ * if @xinew->xi is not set, then create new xigen file.
37198+ */
37199+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew)
37200+{
37201+ struct file *file;
37202+ int err;
37203+
37204+ SiMustAnyLock(sb);
37205+
37206+ file = au_xino_create2(sb, xinew->base, xinew->copy_src);
37207+ if (IS_ERR(file)) {
37208+ err = PTR_ERR(file);
37209+ pr_err("%s[%d], err %d\n",
37210+ xinew->xi ? "xino" : "xigen",
37211+ xinew->idx, err);
37212+ goto out;
37213+ }
37214+
37215+ if (xinew->xi)
37216+ err = au_xino_file_set(xinew->xi, xinew->idx, file);
37217+ else {
37218+ BUG();
37219+ /* todo: make xigen file an array */
37220+ /* err = au_xigen_file_set(sb, xinew->idx, file); */
37221+ }
37222+ fput(file);
37223+ if (unlikely(err))
37224+ file = ERR_PTR(err);
37225+
37226+out:
37227+ return file;
37228+}
37229+
062440b3
AM
37230+/* ---------------------------------------------------------------------- */
37231+
37232+/*
37233+ * truncate xino files
37234+ */
acd2b654
AM
37235+static int au_xino_do_trunc(struct super_block *sb, aufs_bindex_t bindex,
37236+ int idx, struct kstatfs *st)
1facf9fc 37237+{
37238+ int err;
392086de 37239+ blkcnt_t blocks;
acd2b654
AM
37240+ struct file *file, *new_xino;
37241+ struct au_xi_new xinew = {
37242+ .idx = idx
37243+ };
37244+
37245+ err = 0;
37246+ xinew.xi = au_sbr(sb, bindex)->br_xino;
37247+ file = au_xino_file(xinew.xi, idx);
37248+ if (!file)
37249+ goto out;
37250+
37251+ xinew.base = &file->f_path;
37252+ err = vfs_statfs(xinew.base, st);
37253+ if (unlikely(err)) {
37254+ AuErr1("statfs err %d, ignored\n", err);
37255+ err = 0;
37256+ goto out;
37257+ }
37258+
37259+ blocks = file_inode(file)->i_blocks;
37260+ pr_info("begin truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n",
37261+ bindex, idx, (u64)blocks, st->f_bfree, st->f_blocks);
37262+
37263+ xinew.copy_src = file;
37264+ new_xino = au_xi_new(sb, &xinew);
37265+ if (IS_ERR(new_xino)) {
37266+ err = PTR_ERR(new_xino);
37267+ pr_err("xino(b%d-%d), err %d, ignored\n", bindex, idx, err);
37268+ goto out;
37269+ }
37270+
37271+ err = vfs_statfs(&new_xino->f_path, st);
37272+ if (!err)
37273+ pr_info("end truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n",
37274+ bindex, idx, (u64)file_inode(new_xino)->i_blocks,
37275+ st->f_bfree, st->f_blocks);
37276+ else {
37277+ AuErr1("statfs err %d, ignored\n", err);
37278+ err = 0;
37279+ }
37280+
37281+out:
37282+ return err;
37283+}
37284+
37285+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin)
37286+{
37287+ int err, i;
37288+ unsigned long jiffy;
062440b3 37289+ aufs_bindex_t bbot;
392086de 37290+ struct kstatfs *st;
1facf9fc 37291+ struct au_branch *br;
acd2b654 37292+ struct au_xino *xi;
1facf9fc 37293+
392086de 37294+ err = -ENOMEM;
be52b249 37295+ st = kmalloc(sizeof(*st), GFP_NOFS);
392086de
AM
37296+ if (unlikely(!st))
37297+ goto out;
37298+
1facf9fc 37299+ err = -EINVAL;
5afbbe0d
AM
37300+ bbot = au_sbbot(sb);
37301+ if (unlikely(bindex < 0 || bbot < bindex))
392086de 37302+ goto out_st;
392086de 37303+
1facf9fc 37304+ err = 0;
acd2b654
AM
37305+ jiffy = jiffies;
37306+ br = au_sbr(sb, bindex);
37307+ xi = br->br_xino;
37308+ for (i = idx_begin; !err && i < xi->xi_nfile; i++)
37309+ err = au_xino_do_trunc(sb, bindex, i, st);
37310+ if (!err)
37311+ au_sbi(sb)->si_xino_jiffy = jiffy;
392086de
AM
37312+
37313+out_st:
1c60b727 37314+ kfree(st);
4f0767ce 37315+out:
1facf9fc 37316+ return err;
37317+}
37318+
37319+struct xino_do_trunc_args {
37320+ struct super_block *sb;
37321+ struct au_branch *br;
acd2b654 37322+ int idx;
1facf9fc 37323+};
37324+
37325+static void xino_do_trunc(void *_args)
37326+{
37327+ struct xino_do_trunc_args *args = _args;
37328+ struct super_block *sb;
37329+ struct au_branch *br;
37330+ struct inode *dir;
acd2b654 37331+ int err, idx;
1facf9fc 37332+ aufs_bindex_t bindex;
37333+
37334+ err = 0;
37335+ sb = args->sb;
5527c038 37336+ dir = d_inode(sb->s_root);
1facf9fc 37337+ br = args->br;
acd2b654 37338+ idx = args->idx;
1facf9fc 37339+
37340+ si_noflush_write_lock(sb);
37341+ ii_read_lock_parent(dir);
37342+ bindex = au_br_index(sb, br->br_id);
acd2b654 37343+ err = au_xino_trunc(sb, bindex, idx);
1facf9fc 37344+ ii_read_unlock(dir);
37345+ if (unlikely(err))
392086de 37346+ pr_warn("err b%d, (%d)\n", bindex, err);
062440b3 37347+ atomic_dec(&br->br_xino->xi_truncating);
acd2b654 37348+ au_lcnt_dec(&br->br_count);
1facf9fc 37349+ si_write_unlock(sb);
027c5e7a 37350+ au_nwt_done(&au_sbi(sb)->si_nowait);
1c60b727 37351+ kfree(args);
1facf9fc 37352+}
37353+
acd2b654
AM
37354+/*
37355+ * returns the index in the xi_file array whose corresponding file is necessary
37356+ * to truncate, or -1 which means no need to truncate.
37357+ */
392086de
AM
37358+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
37359+{
37360+ int err;
acd2b654 37361+ unsigned int u;
392086de
AM
37362+ struct kstatfs st;
37363+ struct au_sbinfo *sbinfo;
acd2b654 37364+ struct au_xino *xi;
062440b3 37365+ struct file *file;
392086de
AM
37366+
37367+ /* todo: si_xino_expire and the ratio should be customizable */
37368+ sbinfo = au_sbi(sb);
37369+ if (time_before(jiffies,
37370+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
acd2b654 37371+ return -1;
392086de
AM
37372+
37373+ /* truncation border */
acd2b654
AM
37374+ xi = br->br_xino;
37375+ for (u = 0; u < xi->xi_nfile; u++) {
37376+ file = au_xino_file(xi, u);
37377+ if (!file)
37378+ continue;
37379+
37380+ err = vfs_statfs(&file->f_path, &st);
37381+ if (unlikely(err)) {
37382+ AuErr1("statfs err %d, ignored\n", err);
37383+ return -1;
37384+ }
37385+ if (div64_u64(st.f_bfree * 100, st.f_blocks)
37386+ >= AUFS_XINO_DEF_TRUNC)
37387+ return u;
392086de 37388+ }
392086de 37389+
acd2b654 37390+ return -1;
392086de
AM
37391+}
37392+
1facf9fc 37393+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
37394+{
acd2b654 37395+ int idx;
1facf9fc 37396+ struct xino_do_trunc_args *args;
37397+ int wkq_err;
37398+
acd2b654
AM
37399+ idx = xino_trunc_test(sb, br);
37400+ if (idx < 0)
1facf9fc 37401+ return;
37402+
062440b3 37403+ if (atomic_inc_return(&br->br_xino->xi_truncating) > 1)
1facf9fc 37404+ goto out;
37405+
37406+ /* lock and kfree() will be called in trunc_xino() */
37407+ args = kmalloc(sizeof(*args), GFP_NOFS);
37408+ if (unlikely(!args)) {
37409+ AuErr1("no memory\n");
f0c0a007 37410+ goto out;
1facf9fc 37411+ }
37412+
acd2b654 37413+ au_lcnt_inc(&br->br_count);
1facf9fc 37414+ args->sb = sb;
37415+ args->br = br;
acd2b654 37416+ args->idx = idx;
53392da6 37417+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 37418+ if (!wkq_err)
37419+ return; /* success */
37420+
4a4d8108 37421+ pr_err("wkq %d\n", wkq_err);
acd2b654 37422+ au_lcnt_dec(&br->br_count);
1c60b727 37423+ kfree(args);
1facf9fc 37424+
4f0767ce 37425+out:
062440b3 37426+ atomic_dec(&br->br_xino->xi_truncating);
1facf9fc 37427+}
37428+
37429+/* ---------------------------------------------------------------------- */
37430+
acd2b654
AM
37431+struct au_xi_calc {
37432+ int idx;
37433+ loff_t pos;
37434+};
37435+
37436+static void au_xi_calc(struct super_block *sb, ino_t h_ino,
37437+ struct au_xi_calc *calc)
37438+{
37439+ loff_t maxent;
37440+
37441+ maxent = au_xi_maxent(sb);
37442+ calc->idx = div64_u64_rem(h_ino, maxent, &calc->pos);
37443+ calc->pos *= sizeof(ino_t);
37444+}
37445+
37446+static int au_xino_do_new_async(struct super_block *sb, struct au_branch *br,
37447+ struct au_xi_calc *calc)
37448+{
37449+ int err;
37450+ struct file *file;
37451+ struct au_xino *xi = br->br_xino;
37452+ struct au_xi_new xinew = {
37453+ .xi = xi
37454+ };
37455+
37456+ SiMustAnyLock(sb);
37457+
37458+ err = 0;
37459+ if (!xi)
37460+ goto out;
37461+
37462+ mutex_lock(&xi->xi_mtx);
37463+ file = au_xino_file(xi, calc->idx);
37464+ if (file)
37465+ goto out_mtx;
37466+
37467+ file = au_xino_file(xi, /*idx*/-1);
37468+ AuDebugOn(!file);
37469+ xinew.idx = calc->idx;
37470+ xinew.base = &file->f_path;
37471+ /* xinew.copy_src = NULL; */
37472+ file = au_xi_new(sb, &xinew);
37473+ if (IS_ERR(file))
37474+ err = PTR_ERR(file);
37475+
37476+out_mtx:
37477+ mutex_unlock(&xi->xi_mtx);
37478+out:
37479+ return err;
37480+}
37481+
37482+struct au_xino_do_new_async_args {
37483+ struct super_block *sb;
37484+ struct au_branch *br;
37485+ struct au_xi_calc calc;
37486+ ino_t ino;
37487+};
37488+
37489+static int au_xino_do_write(vfs_writef_t write, struct file *file,
37490+ struct au_xi_calc *calc, ino_t ino);
37491+
37492+static void au_xino_call_do_new_async(void *args)
37493+{
37494+ struct au_xino_do_new_async_args *a = args;
37495+ struct au_branch *br;
37496+ struct super_block *sb;
37497+ struct au_sbinfo *sbi;
37498+ struct inode *root;
37499+ struct file *file;
37500+ int err;
37501+
37502+ br = a->br;
37503+ sb = a->sb;
37504+ sbi = au_sbi(sb);
37505+ si_noflush_read_lock(sb);
37506+ root = d_inode(sb->s_root);
37507+ ii_read_lock_child(root);
37508+ err = au_xino_do_new_async(sb, br, &a->calc);
37509+ if (!err) {
37510+ file = au_xino_file(br->br_xino, a->calc.idx);
37511+ if (file)
37512+ err = au_xino_do_write(sbi->si_xwrite, file, &a->calc,
37513+ a->ino);
37514+ if (unlikely(err))
37515+ AuIOErr("err %d\n", err);
37516+ } else
37517+ AuIOErr("err %d\n", err);
37518+ au_lcnt_dec(&br->br_count);
37519+ ii_read_unlock(root);
37520+ si_read_unlock(sb);
37521+ au_nwt_done(&sbi->si_nowait);
37522+ kfree(args);
37523+}
37524+
37525+/*
37526+ * create a new xino file asynchronously
37527+ */
37528+static int au_xino_new_async(struct super_block *sb, struct au_branch *br,
37529+ struct au_xi_calc *calc, ino_t ino)
37530+{
37531+ int err;
37532+ struct au_xino_do_new_async_args *arg;
37533+
37534+ err = -ENOMEM;
37535+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
37536+ if (unlikely(!arg))
37537+ goto out;
37538+
37539+ arg->sb = sb;
37540+ arg->br = br;
37541+ arg->calc = *calc;
37542+ arg->ino = ino;
37543+ au_lcnt_inc(&br->br_count);
37544+ err = au_wkq_nowait(au_xino_call_do_new_async, arg, sb, AuWkq_NEST);
37545+ if (unlikely(err)) {
37546+ pr_err("wkq %d\n", err);
37547+ au_lcnt_dec(&br->br_count);
37548+ kfree(arg);
37549+ }
37550+
37551+out:
37552+ return err;
37553+}
37554+
062440b3
AM
37555+/*
37556+ * read @ino from xinofile for the specified branch{@sb, @bindex}
37557+ * at the position of @h_ino.
37558+ */
37559+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
37560+ ino_t *ino)
37561+{
37562+ int err;
37563+ ssize_t sz;
acd2b654 37564+ struct au_xi_calc calc;
062440b3 37565+ struct au_sbinfo *sbinfo;
acd2b654 37566+ struct file *file;
062440b3
AM
37567+
37568+ *ino = 0;
37569+ if (!au_opt_test(au_mntflags(sb), XINO))
37570+ return 0; /* no xino */
37571+
37572+ err = 0;
acd2b654
AM
37573+ au_xi_calc(sb, h_ino, &calc);
37574+ file = au_xino_file(au_sbr(sb, bindex)->br_xino, calc.idx);
37575+ if (!file
37576+ || vfsub_f_size_read(file) < calc.pos + sizeof(*ino))
062440b3
AM
37577+ return 0; /* no ino */
37578+
acd2b654
AM
37579+ sbinfo = au_sbi(sb);
37580+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &calc.pos);
062440b3
AM
37581+ if (sz == sizeof(*ino))
37582+ return 0; /* success */
37583+
37584+ err = sz;
37585+ if (unlikely(sz >= 0)) {
37586+ err = -EIO;
37587+ AuIOErr("xino read error (%zd)\n", sz);
37588+ }
062440b3
AM
37589+ return err;
37590+}
37591+
5527c038 37592+static int au_xino_do_write(vfs_writef_t write, struct file *file,
acd2b654 37593+ struct au_xi_calc *calc, ino_t ino)
1facf9fc 37594+{
1facf9fc 37595+ ssize_t sz;
37596+
acd2b654 37597+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &calc->pos);
1facf9fc 37598+ if (sz == sizeof(ino))
37599+ return 0; /* success */
37600+
37601+ AuIOErr("write failed (%zd)\n", sz);
37602+ return -EIO;
37603+}
37604+
37605+/*
37606+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
37607+ * at the position of @h_ino.
37608+ * even if @ino is zero, it is written to the xinofile and means no entry.
37609+ * if the size of the xino file on a specific filesystem exceeds the watermark,
37610+ * try truncating it.
37611+ */
37612+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
37613+ ino_t ino)
37614+{
37615+ int err;
37616+ unsigned int mnt_flags;
acd2b654
AM
37617+ struct au_xi_calc calc;
37618+ struct file *file;
1facf9fc 37619+ struct au_branch *br;
acd2b654 37620+ struct au_xino *xi;
1facf9fc 37621+
dece6358 37622+ SiMustAnyLock(sb);
1facf9fc 37623+
37624+ mnt_flags = au_mntflags(sb);
37625+ if (!au_opt_test(mnt_flags, XINO))
37626+ return 0;
37627+
acd2b654 37628+ au_xi_calc(sb, h_ino, &calc);
1facf9fc 37629+ br = au_sbr(sb, bindex);
acd2b654
AM
37630+ xi = br->br_xino;
37631+ file = au_xino_file(xi, calc.idx);
37632+ if (!file) {
37633+ /* create and write a new xino file asynchronously */
37634+ err = au_xino_new_async(sb, br, &calc, ino);
37635+ if (!err)
37636+ return 0; /* success */
37637+ goto out;
37638+ }
37639+
37640+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, file, &calc, ino);
1facf9fc 37641+ if (!err) {
acd2b654 37642+ br = au_sbr(sb, bindex);
1facf9fc 37643+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 37644+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 37645+ xino_try_trunc(sb, br);
37646+ return 0; /* success */
37647+ }
37648+
acd2b654 37649+out:
1facf9fc 37650+ AuIOErr("write failed (%d)\n", err);
37651+ return -EIO;
37652+}
37653+
062440b3
AM
37654+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf,
37655+ size_t size, loff_t *pos);
1facf9fc 37656+
062440b3
AM
37657+/* todo: unnecessary to support mmap_sem since kernel-space? */
37658+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size,
37659+ loff_t *pos)
37660+{
37661+ ssize_t err;
37662+ mm_segment_t oldfs;
37663+ union {
37664+ void *k;
37665+ char __user *u;
37666+ } buf;
37667+ int i;
37668+ const int prevent_endless = 10;
1facf9fc 37669+
062440b3
AM
37670+ i = 0;
37671+ buf.k = kbuf;
37672+ oldfs = get_fs();
37673+ set_fs(KERNEL_DS);
37674+ do {
37675+ err = func(file, buf.u, size, pos);
37676+ if (err == -EINTR
37677+ && !au_wkq_test()
37678+ && fatal_signal_pending(current)) {
37679+ set_fs(oldfs);
37680+ err = xino_fread_wkq(func, file, kbuf, size, pos);
37681+ BUG_ON(err == -EINTR);
37682+ oldfs = get_fs();
37683+ set_fs(KERNEL_DS);
37684+ }
37685+ } while (i++ < prevent_endless
37686+ && (err == -EAGAIN || err == -EINTR));
37687+ set_fs(oldfs);
37688+
37689+#if 0 /* reserved for future use */
37690+ if (err > 0)
37691+ fsnotify_access(file->f_path.dentry);
37692+#endif
37693+
37694+ return err;
37695+}
37696+
37697+struct xino_fread_args {
37698+ ssize_t *errp;
37699+ vfs_readf_t func;
37700+ struct file *file;
37701+ void *buf;
37702+ size_t size;
37703+ loff_t *pos;
37704+};
37705+
37706+static void call_xino_fread(void *args)
37707+{
37708+ struct xino_fread_args *a = args;
37709+ *a->errp = xino_fread(a->func, a->file, a->buf, a->size, a->pos);
37710+}
37711+
37712+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf,
37713+ size_t size, loff_t *pos)
37714+{
37715+ ssize_t err;
37716+ int wkq_err;
37717+ struct xino_fread_args args = {
37718+ .errp = &err,
37719+ .func = func,
37720+ .file = file,
37721+ .buf = buf,
37722+ .size = size,
37723+ .pos = pos
37724+ };
37725+
37726+ wkq_err = au_wkq_wait(call_xino_fread, &args);
37727+ if (unlikely(wkq_err))
37728+ err = wkq_err;
37729+
37730+ return err;
37731+}
37732+
37733+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
37734+ size_t size, loff_t *pos);
37735+
37736+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf,
37737+ size_t size, loff_t *pos)
37738+{
37739+ ssize_t err;
37740+ mm_segment_t oldfs;
37741+ union {
37742+ void *k;
37743+ const char __user *u;
37744+ } buf;
37745+ int i;
37746+ const int prevent_endless = 10;
37747+
37748+ i = 0;
37749+ buf.k = kbuf;
37750+ oldfs = get_fs();
37751+ set_fs(KERNEL_DS);
37752+ do {
37753+ err = func(file, buf.u, size, pos);
37754+ if (err == -EINTR
37755+ && !au_wkq_test()
37756+ && fatal_signal_pending(current)) {
37757+ set_fs(oldfs);
37758+ err = xino_fwrite_wkq(func, file, kbuf, size, pos);
37759+ BUG_ON(err == -EINTR);
37760+ oldfs = get_fs();
37761+ set_fs(KERNEL_DS);
37762+ }
37763+ } while (i++ < prevent_endless
37764+ && (err == -EAGAIN || err == -EINTR));
37765+ set_fs(oldfs);
37766+
37767+#if 0 /* reserved for future use */
37768+ if (err > 0)
37769+ fsnotify_modify(file->f_path.dentry);
37770+#endif
37771+
37772+ return err;
37773+}
37774+
37775+struct do_xino_fwrite_args {
37776+ ssize_t *errp;
37777+ vfs_writef_t func;
37778+ struct file *file;
37779+ void *buf;
37780+ size_t size;
37781+ loff_t *pos;
37782+};
37783+
37784+static void call_do_xino_fwrite(void *args)
37785+{
37786+ struct do_xino_fwrite_args *a = args;
37787+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
37788+}
37789+
37790+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
37791+ size_t size, loff_t *pos)
37792+{
37793+ ssize_t err;
37794+ int wkq_err;
37795+ struct do_xino_fwrite_args args = {
37796+ .errp = &err,
37797+ .func = func,
37798+ .file = file,
37799+ .buf = buf,
37800+ .size = size,
37801+ .pos = pos
37802+ };
37803+
37804+ /*
37805+ * it breaks RLIMIT_FSIZE and normal user's limit,
37806+ * users should care about quota and real 'filesystem full.'
37807+ */
37808+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
37809+ if (unlikely(wkq_err))
37810+ err = wkq_err;
37811+
37812+ return err;
37813+}
37814+
37815+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
37816+ size_t size, loff_t *pos)
37817+{
37818+ ssize_t err;
37819+
37820+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
37821+ lockdep_off();
37822+ err = do_xino_fwrite(func, file, buf, size, pos);
37823+ lockdep_on();
37824+ } else {
37825+ lockdep_off();
37826+ err = xino_fwrite_wkq(func, file, buf, size, pos);
37827+ lockdep_on();
37828+ }
37829+
37830+ return err;
37831+}
37832+
37833+/* ---------------------------------------------------------------------- */
37834+
37835+/*
37836+ * inode number bitmap
37837+ */
1facf9fc 37838+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
37839+static ino_t xib_calc_ino(unsigned long pindex, int bit)
37840+{
37841+ ino_t ino;
37842+
37843+ AuDebugOn(bit < 0 || page_bits <= bit);
37844+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
37845+ return ino;
37846+}
37847+
37848+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
37849+{
37850+ AuDebugOn(ino < AUFS_FIRST_INO);
37851+ ino -= AUFS_FIRST_INO;
37852+ *pindex = ino / page_bits;
37853+ *bit = ino % page_bits;
37854+}
37855+
37856+static int xib_pindex(struct super_block *sb, unsigned long pindex)
37857+{
37858+ int err;
37859+ loff_t pos;
37860+ ssize_t sz;
37861+ struct au_sbinfo *sbinfo;
37862+ struct file *xib;
37863+ unsigned long *p;
37864+
37865+ sbinfo = au_sbi(sb);
37866+ MtxMustLock(&sbinfo->si_xib_mtx);
37867+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
37868+ || !au_opt_test(sbinfo->si_mntflags, XINO));
37869+
37870+ if (pindex == sbinfo->si_xib_last_pindex)
37871+ return 0;
37872+
37873+ xib = sbinfo->si_xib;
37874+ p = sbinfo->si_xib_buf;
37875+ pos = sbinfo->si_xib_last_pindex;
37876+ pos *= PAGE_SIZE;
37877+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
37878+ if (unlikely(sz != PAGE_SIZE))
37879+ goto out;
37880+
37881+ pos = pindex;
37882+ pos *= PAGE_SIZE;
c06a8ce3 37883+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 37884+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
37885+ else {
37886+ memset(p, 0, PAGE_SIZE);
37887+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
37888+ }
37889+ if (sz == PAGE_SIZE) {
37890+ sbinfo->si_xib_last_pindex = pindex;
37891+ return 0; /* success */
37892+ }
37893+
4f0767ce 37894+out:
b752ccd1
AM
37895+ AuIOErr1("write failed (%zd)\n", sz);
37896+ err = sz;
37897+ if (sz >= 0)
37898+ err = -EIO;
37899+ return err;
37900+}
37901+
b752ccd1
AM
37902+static void au_xib_clear_bit(struct inode *inode)
37903+{
37904+ int err, bit;
37905+ unsigned long pindex;
37906+ struct super_block *sb;
37907+ struct au_sbinfo *sbinfo;
37908+
37909+ AuDebugOn(inode->i_nlink);
37910+
37911+ sb = inode->i_sb;
37912+ xib_calc_bit(inode->i_ino, &pindex, &bit);
37913+ AuDebugOn(page_bits <= bit);
37914+ sbinfo = au_sbi(sb);
37915+ mutex_lock(&sbinfo->si_xib_mtx);
37916+ err = xib_pindex(sb, pindex);
37917+ if (!err) {
37918+ clear_bit(bit, sbinfo->si_xib_buf);
37919+ sbinfo->si_xib_next_bit = bit;
37920+ }
37921+ mutex_unlock(&sbinfo->si_xib_mtx);
37922+}
37923+
1facf9fc 37924+/* ---------------------------------------------------------------------- */
37925+
1facf9fc 37926+/*
062440b3 37927+ * truncate a xino bitmap file
1facf9fc 37928+ */
1facf9fc 37929+
37930+/* todo: slow */
37931+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
37932+{
37933+ int err, bit;
37934+ ssize_t sz;
37935+ unsigned long pindex;
37936+ loff_t pos, pend;
37937+ struct au_sbinfo *sbinfo;
5527c038 37938+ vfs_readf_t func;
1facf9fc 37939+ ino_t *ino;
37940+ unsigned long *p;
37941+
37942+ err = 0;
37943+ sbinfo = au_sbi(sb);
dece6358 37944+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 37945+ p = sbinfo->si_xib_buf;
37946+ func = sbinfo->si_xread;
c06a8ce3 37947+ pend = vfsub_f_size_read(file);
1facf9fc 37948+ pos = 0;
37949+ while (pos < pend) {
37950+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
37951+ err = sz;
37952+ if (unlikely(sz <= 0))
37953+ goto out;
37954+
37955+ err = 0;
37956+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
37957+ if (unlikely(*ino < AUFS_FIRST_INO))
37958+ continue;
37959+
37960+ xib_calc_bit(*ino, &pindex, &bit);
37961+ AuDebugOn(page_bits <= bit);
37962+ err = xib_pindex(sb, pindex);
37963+ if (!err)
37964+ set_bit(bit, p);
37965+ else
37966+ goto out;
37967+ }
37968+ }
37969+
4f0767ce 37970+out:
1facf9fc 37971+ return err;
37972+}
37973+
37974+static int xib_restore(struct super_block *sb)
37975+{
acd2b654
AM
37976+ int err, i;
37977+ unsigned int nfile;
5afbbe0d 37978+ aufs_bindex_t bindex, bbot;
1facf9fc 37979+ void *page;
062440b3 37980+ struct au_branch *br;
acd2b654
AM
37981+ struct au_xino *xi;
37982+ struct file *file;
1facf9fc 37983+
37984+ err = -ENOMEM;
37985+ page = (void *)__get_free_page(GFP_NOFS);
37986+ if (unlikely(!page))
37987+ goto out;
37988+
37989+ err = 0;
5afbbe0d
AM
37990+ bbot = au_sbbot(sb);
37991+ for (bindex = 0; !err && bindex <= bbot; bindex++)
062440b3
AM
37992+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) {
37993+ br = au_sbr(sb, bindex);
acd2b654
AM
37994+ xi = br->br_xino;
37995+ nfile = xi->xi_nfile;
37996+ for (i = 0; i < nfile; i++) {
37997+ file = au_xino_file(xi, i);
37998+ if (file)
37999+ err = do_xib_restore(sb, file, page);
38000+ }
062440b3
AM
38001+ } else
38002+ AuDbg("skip shared b%d\n", bindex);
1c60b727 38003+ free_page((unsigned long)page);
1facf9fc 38004+
4f0767ce 38005+out:
1facf9fc 38006+ return err;
38007+}
38008+
38009+int au_xib_trunc(struct super_block *sb)
38010+{
38011+ int err;
38012+ ssize_t sz;
38013+ loff_t pos;
1facf9fc 38014+ struct au_sbinfo *sbinfo;
38015+ unsigned long *p;
38016+ struct file *file;
38017+
dece6358
AM
38018+ SiMustWriteLock(sb);
38019+
1facf9fc 38020+ err = 0;
38021+ sbinfo = au_sbi(sb);
38022+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
38023+ goto out;
38024+
38025+ file = sbinfo->si_xib;
c06a8ce3 38026+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 38027+ goto out;
38028+
062440b3 38029+ file = au_xino_create2(sb, &sbinfo->si_xib->f_path, NULL);
1facf9fc 38030+ err = PTR_ERR(file);
38031+ if (IS_ERR(file))
38032+ goto out;
38033+ fput(sbinfo->si_xib);
38034+ sbinfo->si_xib = file;
38035+
38036+ p = sbinfo->si_xib_buf;
38037+ memset(p, 0, PAGE_SIZE);
38038+ pos = 0;
38039+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
38040+ if (unlikely(sz != PAGE_SIZE)) {
38041+ err = sz;
38042+ AuIOErr("err %d\n", err);
38043+ if (sz >= 0)
38044+ err = -EIO;
38045+ goto out;
38046+ }
38047+
38048+ mutex_lock(&sbinfo->si_xib_mtx);
38049+ /* mnt_want_write() is unnecessary here */
38050+ err = xib_restore(sb);
38051+ mutex_unlock(&sbinfo->si_xib_mtx);
38052+
38053+out:
38054+ return err;
38055+}
38056+
38057+/* ---------------------------------------------------------------------- */
38058+
acd2b654 38059+struct au_xino *au_xino_alloc(unsigned int nfile)
062440b3
AM
38060+{
38061+ struct au_xino *xi;
38062+
38063+ xi = kzalloc(sizeof(*xi), GFP_NOFS);
38064+ if (unlikely(!xi))
38065+ goto out;
acd2b654
AM
38066+ xi->xi_nfile = nfile;
38067+ xi->xi_file = kcalloc(nfile, sizeof(*xi->xi_file), GFP_NOFS);
38068+ if (unlikely(!xi->xi_file))
38069+ goto out_free;
062440b3
AM
38070+
38071+ xi->xi_nondir.total = 8; /* initial size */
38072+ xi->xi_nondir.array = kcalloc(xi->xi_nondir.total, sizeof(ino_t),
38073+ GFP_NOFS);
38074+ if (unlikely(!xi->xi_nondir.array))
acd2b654 38075+ goto out_file;
062440b3
AM
38076+
38077+ spin_lock_init(&xi->xi_nondir.spin);
38078+ init_waitqueue_head(&xi->xi_nondir.wqh);
acd2b654
AM
38079+ mutex_init(&xi->xi_mtx);
38080+ /* init_waitqueue_head(&xi->xi_wq); */
38081+ /* atomic_set(&xi->xi_pending, 0); */
062440b3
AM
38082+ atomic_set(&xi->xi_truncating, 0);
38083+ kref_init(&xi->xi_kref);
38084+ goto out; /* success */
38085+
acd2b654
AM
38086+out_file:
38087+ kfree(xi->xi_file);
062440b3
AM
38088+out_free:
38089+ kfree(xi);
38090+ xi = NULL;
38091+out:
38092+ return xi;
38093+}
38094+
acd2b654 38095+static int au_xino_init(struct au_branch *br, int idx, struct file *file)
062440b3
AM
38096+{
38097+ int err;
38098+ struct au_xino *xi;
38099+
38100+ err = 0;
acd2b654 38101+ xi = au_xino_alloc(idx + 1);
062440b3
AM
38102+ if (unlikely(!xi)) {
38103+ err = -ENOMEM;
38104+ goto out;
38105+ }
38106+
acd2b654
AM
38107+ if (file)
38108+ get_file(file);
38109+ xi->xi_file[idx] = file;
062440b3
AM
38110+ AuDebugOn(br->br_xino);
38111+ br->br_xino = xi;
38112+
38113+out:
38114+ return err;
38115+}
38116+
38117+static void au_xino_release(struct kref *kref)
38118+{
38119+ struct au_xino *xi;
38120+ int i;
38121+
38122+ xi = container_of(kref, struct au_xino, xi_kref);
acd2b654
AM
38123+ for (i = 0; i < xi->xi_nfile; i++)
38124+ if (xi->xi_file[i])
38125+ fput(xi->xi_file[i]);
062440b3
AM
38126+ for (i = xi->xi_nondir.total - 1; i >= 0; i--)
38127+ AuDebugOn(xi->xi_nondir.array[i]);
acd2b654
AM
38128+ mutex_destroy(&xi->xi_mtx);
38129+ kfree(xi->xi_file);
062440b3
AM
38130+ kfree(xi->xi_nondir.array);
38131+ kfree(xi);
38132+}
38133+
38134+int au_xino_put(struct au_branch *br)
38135+{
38136+ int ret;
38137+ struct au_xino *xi;
38138+
38139+ ret = 0;
38140+ xi = br->br_xino;
38141+ if (xi) {
38142+ br->br_xino = NULL;
38143+ ret = kref_put(&xi->xi_kref, au_xino_release);
38144+ }
38145+
38146+ return ret;
38147+}
38148+
062440b3
AM
38149+/* ---------------------------------------------------------------------- */
38150+
1facf9fc 38151+/*
38152+ * xino mount option handlers
38153+ */
1facf9fc 38154+
38155+/* xino bitmap */
38156+static void xino_clear_xib(struct super_block *sb)
38157+{
38158+ struct au_sbinfo *sbinfo;
38159+
dece6358
AM
38160+ SiMustWriteLock(sb);
38161+
1facf9fc 38162+ sbinfo = au_sbi(sb);
062440b3 38163+ /* unnecessary to clear sbinfo->si_xread and ->si_xwrite */
1facf9fc 38164+ if (sbinfo->si_xib)
38165+ fput(sbinfo->si_xib);
38166+ sbinfo->si_xib = NULL;
f0c0a007 38167+ if (sbinfo->si_xib_buf)
1c60b727 38168+ free_page((unsigned long)sbinfo->si_xib_buf);
1facf9fc 38169+ sbinfo->si_xib_buf = NULL;
38170+}
38171+
062440b3 38172+static int au_xino_set_xib(struct super_block *sb, struct path *path)
1facf9fc 38173+{
38174+ int err;
38175+ loff_t pos;
38176+ struct au_sbinfo *sbinfo;
38177+ struct file *file;
acd2b654 38178+ struct super_block *xi_sb;
1facf9fc 38179+
dece6358
AM
38180+ SiMustWriteLock(sb);
38181+
1facf9fc 38182+ sbinfo = au_sbi(sb);
062440b3 38183+ file = au_xino_create2(sb, path, sbinfo->si_xib);
1facf9fc 38184+ err = PTR_ERR(file);
38185+ if (IS_ERR(file))
38186+ goto out;
38187+ if (sbinfo->si_xib)
38188+ fput(sbinfo->si_xib);
38189+ sbinfo->si_xib = file;
5527c038
JR
38190+ sbinfo->si_xread = vfs_readf(file);
38191+ sbinfo->si_xwrite = vfs_writef(file);
acd2b654
AM
38192+ xi_sb = file_inode(file)->i_sb;
38193+ sbinfo->si_ximaxent = xi_sb->s_maxbytes;
38194+ if (unlikely(sbinfo->si_ximaxent < PAGE_SIZE)) {
38195+ err = -EIO;
38196+ pr_err("s_maxbytes(%llu) on %s is too small\n",
38197+ (u64)sbinfo->si_ximaxent, au_sbtype(xi_sb));
38198+ goto out_unset;
38199+ }
38200+ sbinfo->si_ximaxent /= sizeof(ino_t);
1facf9fc 38201+
38202+ err = -ENOMEM;
38203+ if (!sbinfo->si_xib_buf)
38204+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
38205+ if (unlikely(!sbinfo->si_xib_buf))
38206+ goto out_unset;
38207+
38208+ sbinfo->si_xib_last_pindex = 0;
38209+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 38210+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 38211+ pos = 0;
38212+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
38213+ PAGE_SIZE, &pos);
38214+ if (unlikely(err != PAGE_SIZE))
38215+ goto out_free;
38216+ }
38217+ err = 0;
38218+ goto out; /* success */
38219+
4f0767ce 38220+out_free:
f0c0a007 38221+ if (sbinfo->si_xib_buf)
1c60b727 38222+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
38223+ sbinfo->si_xib_buf = NULL;
38224+ if (err >= 0)
38225+ err = -EIO;
4f0767ce 38226+out_unset:
b752ccd1
AM
38227+ fput(sbinfo->si_xib);
38228+ sbinfo->si_xib = NULL;
4f0767ce 38229+out:
062440b3 38230+ AuTraceErr(err);
b752ccd1 38231+ return err;
1facf9fc 38232+}
38233+
b752ccd1
AM
38234+/* xino for each branch */
38235+static void xino_clear_br(struct super_block *sb)
38236+{
5afbbe0d 38237+ aufs_bindex_t bindex, bbot;
b752ccd1 38238+ struct au_branch *br;
1facf9fc 38239+
5afbbe0d
AM
38240+ bbot = au_sbbot(sb);
38241+ for (bindex = 0; bindex <= bbot; bindex++) {
b752ccd1 38242+ br = au_sbr(sb, bindex);
062440b3
AM
38243+ AuDebugOn(!br);
38244+ au_xino_put(br);
38245+ }
38246+}
38247+
38248+static void au_xino_set_br_shared(struct super_block *sb, struct au_branch *br,
38249+ aufs_bindex_t bshared)
38250+{
38251+ struct au_branch *brshared;
b752ccd1 38252+
062440b3
AM
38253+ brshared = au_sbr(sb, bshared);
38254+ AuDebugOn(!brshared->br_xino);
38255+ AuDebugOn(!brshared->br_xino->xi_file);
38256+ if (br->br_xino != brshared->br_xino) {
38257+ au_xino_get(brshared);
38258+ au_xino_put(br);
38259+ br->br_xino = brshared->br_xino;
b752ccd1
AM
38260+ }
38261+}
38262+
062440b3
AM
38263+struct au_xino_do_set_br {
38264+ vfs_writef_t writef;
38265+ struct au_branch *br;
38266+ ino_t h_ino;
38267+ aufs_bindex_t bshared;
38268+};
38269+
38270+static int au_xino_do_set_br(struct super_block *sb, struct path *path,
38271+ struct au_xino_do_set_br *args)
1facf9fc 38272+{
38273+ int err;
acd2b654 38274+ struct au_xi_calc calc;
062440b3 38275+ struct file *file;
acd2b654
AM
38276+ struct au_branch *br;
38277+ struct au_xi_new xinew = {
38278+ .base = path
38279+ };
062440b3 38280+
acd2b654
AM
38281+ br = args->br;
38282+ xinew.xi = br->br_xino;
38283+ au_xi_calc(sb, args->h_ino, &calc);
38284+ xinew.copy_src = au_xino_file(xinew.xi, calc.idx);
38285+ if (args->bshared >= 0)
062440b3 38286+ /* shared xino */
acd2b654
AM
38287+ au_xino_set_br_shared(sb, br, args->bshared);
38288+ else if (!xinew.xi) {
38289+ /* new xino */
38290+ err = au_xino_init(br, calc.idx, xinew.copy_src);
38291+ if (unlikely(err))
38292+ goto out;
062440b3
AM
38293+ }
38294+
acd2b654
AM
38295+ /* force re-creating */
38296+ xinew.xi = br->br_xino;
38297+ xinew.idx = calc.idx;
38298+ mutex_lock(&xinew.xi->xi_mtx);
38299+ file = au_xi_new(sb, &xinew);
38300+ mutex_unlock(&xinew.xi->xi_mtx);
062440b3
AM
38301+ err = PTR_ERR(file);
38302+ if (IS_ERR(file))
38303+ goto out;
acd2b654
AM
38304+ AuDebugOn(!file);
38305+
38306+ err = au_xino_do_write(args->writef, file, &calc, AUFS_ROOT_INO);
38307+ if (unlikely(err))
38308+ au_xino_put(br);
062440b3 38309+
062440b3
AM
38310+out:
38311+ AuTraceErr(err);
38312+ return err;
38313+}
38314+
38315+static int au_xino_set_br(struct super_block *sb, struct path *path)
38316+{
38317+ int err;
38318+ aufs_bindex_t bindex, bbot;
38319+ struct au_xino_do_set_br args;
b752ccd1 38320+ struct inode *inode;
1facf9fc 38321+
b752ccd1
AM
38322+ SiMustWriteLock(sb);
38323+
5afbbe0d 38324+ bbot = au_sbbot(sb);
5527c038 38325+ inode = d_inode(sb->s_root);
062440b3
AM
38326+ args.writef = au_sbi(sb)->si_xwrite;
38327+ for (bindex = 0; bindex <= bbot; bindex++) {
38328+ args.h_ino = au_h_iptr(inode, bindex)->i_ino;
38329+ args.br = au_sbr(sb, bindex);
38330+ args.bshared = is_sb_shared(sb, bindex, bindex - 1);
38331+ err = au_xino_do_set_br(sb, path, &args);
b752ccd1 38332+ if (unlikely(err))
062440b3 38333+ break;
b752ccd1 38334+ }
1facf9fc 38335+
062440b3 38336+ AuTraceErr(err);
1facf9fc 38337+ return err;
38338+}
b752ccd1
AM
38339+
38340+void au_xino_clr(struct super_block *sb)
38341+{
38342+ struct au_sbinfo *sbinfo;
38343+
38344+ au_xigen_clr(sb);
38345+ xino_clear_xib(sb);
38346+ xino_clear_br(sb);
062440b3 38347+ dbgaufs_brs_del(sb, 0);
b752ccd1
AM
38348+ sbinfo = au_sbi(sb);
38349+ /* lvalue, do not call au_mntflags() */
38350+ au_opt_clr(sbinfo->si_mntflags, XINO);
38351+}
38352+
062440b3 38353+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount)
b752ccd1
AM
38354+{
38355+ int err, skip;
062440b3 38356+ struct dentry *dentry, *parent, *cur_dentry, *cur_parent;
b752ccd1
AM
38357+ struct qstr *dname, *cur_name;
38358+ struct file *cur_xino;
b752ccd1 38359+ struct au_sbinfo *sbinfo;
062440b3 38360+ struct path *path, *cur_path;
b752ccd1
AM
38361+
38362+ SiMustWriteLock(sb);
38363+
38364+ err = 0;
38365+ sbinfo = au_sbi(sb);
062440b3
AM
38366+ path = &xiopt->file->f_path;
38367+ dentry = path->dentry;
38368+ parent = dget_parent(dentry);
b752ccd1
AM
38369+ if (remount) {
38370+ skip = 0;
b752ccd1
AM
38371+ cur_xino = sbinfo->si_xib;
38372+ if (cur_xino) {
062440b3
AM
38373+ cur_path = &cur_xino->f_path;
38374+ cur_dentry = cur_path->dentry;
38375+ cur_parent = dget_parent(cur_dentry);
38376+ cur_name = &cur_dentry->d_name;
38377+ dname = &dentry->d_name;
b752ccd1 38378+ skip = (cur_parent == parent
38d290e6 38379+ && au_qstreq(dname, cur_name));
b752ccd1
AM
38380+ dput(cur_parent);
38381+ }
38382+ if (skip)
38383+ goto out;
38384+ }
38385+
38386+ au_opt_set(sbinfo->si_mntflags, XINO);
062440b3
AM
38387+ err = au_xino_set_xib(sb, path);
38388+ /* si_x{read,write} are set */
b752ccd1 38389+ if (!err)
062440b3 38390+ err = au_xigen_set(sb, path);
b752ccd1 38391+ if (!err)
062440b3
AM
38392+ err = au_xino_set_br(sb, path);
38393+ if (!err) {
38394+ dbgaufs_brs_add(sb, 0, /*topdown*/1);
b752ccd1 38395+ goto out; /* success */
062440b3 38396+ }
b752ccd1
AM
38397+
38398+ /* reset all */
062440b3
AM
38399+ AuIOErr("failed setting xino(%d).\n", err);
38400+ au_xino_clr(sb);
b752ccd1 38401+
4f0767ce 38402+out:
b752ccd1
AM
38403+ dput(parent);
38404+ return err;
38405+}
38406+
b752ccd1
AM
38407+/*
38408+ * create a xinofile at the default place/path.
38409+ */
38410+struct file *au_xino_def(struct super_block *sb)
38411+{
38412+ struct file *file;
38413+ char *page, *p;
38414+ struct au_branch *br;
38415+ struct super_block *h_sb;
38416+ struct path path;
5afbbe0d 38417+ aufs_bindex_t bbot, bindex, bwr;
b752ccd1
AM
38418+
38419+ br = NULL;
5afbbe0d 38420+ bbot = au_sbbot(sb);
b752ccd1 38421+ bwr = -1;
5afbbe0d 38422+ for (bindex = 0; bindex <= bbot; bindex++) {
b752ccd1
AM
38423+ br = au_sbr(sb, bindex);
38424+ if (au_br_writable(br->br_perm)
86dc4139 38425+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
38426+ bwr = bindex;
38427+ break;
38428+ }
38429+ }
38430+
7f207e10
AM
38431+ if (bwr >= 0) {
38432+ file = ERR_PTR(-ENOMEM);
537831f9 38433+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
38434+ if (unlikely(!page))
38435+ goto out;
86dc4139 38436+ path.mnt = au_br_mnt(br);
7f207e10
AM
38437+ path.dentry = au_h_dptr(sb->s_root, bwr);
38438+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
38439+ file = (void *)p;
38440+ if (!IS_ERR(p)) {
38441+ strcat(p, "/" AUFS_XINO_FNAME);
38442+ AuDbg("%s\n", p);
38443+ file = au_xino_create(sb, p, /*silent*/0);
7f207e10 38444+ }
1c60b727 38445+ free_page((unsigned long)page);
7f207e10
AM
38446+ } else {
38447+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
38448+ if (IS_ERR(file))
38449+ goto out;
2000de60 38450+ h_sb = file->f_path.dentry->d_sb;
7f207e10
AM
38451+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
38452+ pr_err("xino doesn't support %s(%s)\n",
38453+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
38454+ fput(file);
38455+ file = ERR_PTR(-EINVAL);
38456+ }
7f207e10 38457+ }
0c5527e5 38458+
7f207e10
AM
38459+out:
38460+ return file;
38461+}
38462+
38463+/* ---------------------------------------------------------------------- */
38464+
062440b3
AM
38465+/*
38466+ * initialize the xinofile for the specified branch @br
38467+ * at the place/path where @base_file indicates.
38468+ * test whether another branch is on the same filesystem or not,
38469+ * if found then share the xinofile with another branch.
38470+ */
38471+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
38472+ struct path *base)
7f207e10
AM
38473+{
38474+ int err;
062440b3
AM
38475+ struct au_xino_do_set_br args = {
38476+ .h_ino = h_ino,
38477+ .br = br
38478+ };
7f207e10 38479+
062440b3
AM
38480+ args.writef = au_sbi(sb)->si_xwrite;
38481+ args.bshared = sbr_find_shared(sb, /*btop*/0, au_sbbot(sb),
38482+ au_br_sb(br));
38483+ err = au_xino_do_set_br(sb, base, &args);
79b8bda9 38484+ if (unlikely(err))
062440b3 38485+ au_xino_put(br);
7f207e10 38486+
7f207e10
AM
38487+ return err;
38488+}
521ced18
JR
38489+
38490+/* ---------------------------------------------------------------------- */
38491+
062440b3
AM
38492+/*
38493+ * get an unused inode number from bitmap
38494+ */
38495+ino_t au_xino_new_ino(struct super_block *sb)
38496+{
38497+ ino_t ino;
38498+ unsigned long *p, pindex, ul, pend;
38499+ struct au_sbinfo *sbinfo;
38500+ struct file *file;
38501+ int free_bit, err;
38502+
38503+ if (!au_opt_test(au_mntflags(sb), XINO))
38504+ return iunique(sb, AUFS_FIRST_INO);
38505+
38506+ sbinfo = au_sbi(sb);
38507+ mutex_lock(&sbinfo->si_xib_mtx);
38508+ p = sbinfo->si_xib_buf;
38509+ free_bit = sbinfo->si_xib_next_bit;
38510+ if (free_bit < page_bits && !test_bit(free_bit, p))
38511+ goto out; /* success */
38512+ free_bit = find_first_zero_bit(p, page_bits);
38513+ if (free_bit < page_bits)
38514+ goto out; /* success */
38515+
38516+ pindex = sbinfo->si_xib_last_pindex;
38517+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
38518+ err = xib_pindex(sb, ul);
38519+ if (unlikely(err))
38520+ goto out_err;
38521+ free_bit = find_first_zero_bit(p, page_bits);
38522+ if (free_bit < page_bits)
38523+ goto out; /* success */
38524+ }
38525+
38526+ file = sbinfo->si_xib;
38527+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
38528+ for (ul = pindex + 1; ul <= pend; ul++) {
38529+ err = xib_pindex(sb, ul);
38530+ if (unlikely(err))
38531+ goto out_err;
38532+ free_bit = find_first_zero_bit(p, page_bits);
38533+ if (free_bit < page_bits)
38534+ goto out; /* success */
38535+ }
38536+ BUG();
38537+
38538+out:
38539+ set_bit(free_bit, p);
38540+ sbinfo->si_xib_next_bit = free_bit + 1;
38541+ pindex = sbinfo->si_xib_last_pindex;
38542+ mutex_unlock(&sbinfo->si_xib_mtx);
38543+ ino = xib_calc_ino(pindex, free_bit);
38544+ AuDbg("i%lu\n", (unsigned long)ino);
38545+ return ino;
38546+out_err:
38547+ mutex_unlock(&sbinfo->si_xib_mtx);
38548+ AuDbg("i0\n");
38549+ return 0;
38550+}
38551+
38552+/* for s_op->delete_inode() */
38553+void au_xino_delete_inode(struct inode *inode, const int unlinked)
521ced18 38554+{
062440b3
AM
38555+ int err;
38556+ unsigned int mnt_flags;
38557+ aufs_bindex_t bindex, bbot, bi;
38558+ unsigned char try_trunc;
38559+ struct au_iinfo *iinfo;
38560+ struct super_block *sb;
38561+ struct au_hinode *hi;
38562+ struct inode *h_inode;
38563+ struct au_branch *br;
38564+ vfs_writef_t xwrite;
acd2b654
AM
38565+ struct au_xi_calc calc;
38566+ struct file *file;
521ced18 38567+
062440b3 38568+ AuDebugOn(au_is_bad_inode(inode));
521ced18 38569+
062440b3
AM
38570+ sb = inode->i_sb;
38571+ mnt_flags = au_mntflags(sb);
38572+ if (!au_opt_test(mnt_flags, XINO)
38573+ || inode->i_ino == AUFS_ROOT_INO)
38574+ return;
38575+
38576+ if (unlinked) {
38577+ au_xigen_inc(inode);
38578+ au_xib_clear_bit(inode);
38579+ }
38580+
38581+ iinfo = au_ii(inode);
38582+ bindex = iinfo->ii_btop;
38583+ if (bindex < 0)
38584+ return;
38585+
38586+ xwrite = au_sbi(sb)->si_xwrite;
38587+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
38588+ hi = au_hinode(iinfo, bindex);
38589+ bbot = iinfo->ii_bbot;
38590+ for (; bindex <= bbot; bindex++, hi++) {
38591+ h_inode = hi->hi_inode;
38592+ if (!h_inode
38593+ || (!unlinked && h_inode->i_nlink))
38594+ continue;
38595+
38596+ /* inode may not be revalidated */
38597+ bi = au_br_index(sb, hi->hi_id);
38598+ if (bi < 0)
38599+ continue;
38600+
38601+ br = au_sbr(sb, bi);
acd2b654
AM
38602+ au_xi_calc(sb, h_inode->i_ino, &calc);
38603+ file = au_xino_file(br->br_xino, calc.idx);
38604+ if (IS_ERR_OR_NULL(file))
38605+ continue;
38606+
38607+ err = au_xino_do_write(xwrite, file, &calc, /*ino*/0);
062440b3
AM
38608+ if (!err && try_trunc
38609+ && au_test_fs_trunc_xino(au_br_sb(br)))
38610+ xino_try_trunc(sb, br);
38611+ }
521ced18
JR
38612+}
38613+
062440b3
AM
38614+/* ---------------------------------------------------------------------- */
38615+
38616+static int au_xinondir_find(struct au_xino *xi, ino_t h_ino)
521ced18
JR
38617+{
38618+ int found, total, i;
38619+
38620+ found = -1;
062440b3 38621+ total = xi->xi_nondir.total;
521ced18 38622+ for (i = 0; i < total; i++) {
062440b3 38623+ if (xi->xi_nondir.array[i] != h_ino)
521ced18
JR
38624+ continue;
38625+ found = i;
38626+ break;
38627+ }
38628+
38629+ return found;
38630+}
38631+
062440b3 38632+static int au_xinondir_expand(struct au_xino *xi)
521ced18
JR
38633+{
38634+ int err, sz;
38635+ ino_t *p;
38636+
38637+ BUILD_BUG_ON(KMALLOC_MAX_SIZE > INT_MAX);
38638+
38639+ err = -ENOMEM;
062440b3 38640+ sz = xi->xi_nondir.total * sizeof(ino_t);
521ced18
JR
38641+ if (unlikely(sz > KMALLOC_MAX_SIZE / 2))
38642+ goto out;
062440b3 38643+ p = au_kzrealloc(xi->xi_nondir.array, sz, sz << 1, GFP_ATOMIC,
521ced18
JR
38644+ /*may_shrink*/0);
38645+ if (p) {
062440b3
AM
38646+ xi->xi_nondir.array = p;
38647+ xi->xi_nondir.total <<= 1;
38648+ AuDbg("xi_nondir.total %d\n", xi->xi_nondir.total);
521ced18
JR
38649+ err = 0;
38650+ }
38651+
38652+out:
38653+ return err;
38654+}
38655+
062440b3
AM
38656+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
38657+ ino_t h_ino, int idx)
38658+{
38659+ struct au_xino *xi;
38660+
38661+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
38662+ xi = au_sbr(sb, bindex)->br_xino;
38663+ AuDebugOn(idx < 0 || xi->xi_nondir.total <= idx);
38664+
38665+ spin_lock(&xi->xi_nondir.spin);
38666+ AuDebugOn(xi->xi_nondir.array[idx] != h_ino);
38667+ xi->xi_nondir.array[idx] = 0;
38668+ spin_unlock(&xi->xi_nondir.spin);
38669+ wake_up_all(&xi->xi_nondir.wqh);
38670+}
38671+
521ced18
JR
38672+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
38673+ int *idx)
38674+{
38675+ int err, found, empty;
062440b3 38676+ struct au_xino *xi;
521ced18
JR
38677+
38678+ err = 0;
38679+ *idx = -1;
38680+ if (!au_opt_test(au_mntflags(sb), XINO))
38681+ goto out; /* no xino */
38682+
062440b3 38683+ xi = au_sbr(sb, bindex)->br_xino;
521ced18
JR
38684+
38685+again:
062440b3
AM
38686+ spin_lock(&xi->xi_nondir.spin);
38687+ found = au_xinondir_find(xi, h_ino);
521ced18 38688+ if (found == -1) {
062440b3 38689+ empty = au_xinondir_find(xi, /*h_ino*/0);
521ced18 38690+ if (empty == -1) {
062440b3
AM
38691+ empty = xi->xi_nondir.total;
38692+ err = au_xinondir_expand(xi);
521ced18
JR
38693+ if (unlikely(err))
38694+ goto out_unlock;
38695+ }
062440b3 38696+ xi->xi_nondir.array[empty] = h_ino;
521ced18
JR
38697+ *idx = empty;
38698+ } else {
062440b3
AM
38699+ spin_unlock(&xi->xi_nondir.spin);
38700+ wait_event(xi->xi_nondir.wqh,
38701+ xi->xi_nondir.array[found] != h_ino);
521ced18
JR
38702+ goto again;
38703+ }
38704+
38705+out_unlock:
062440b3
AM
38706+ spin_unlock(&xi->xi_nondir.spin);
38707+out:
38708+ return err;
38709+}
38710+
38711+/* ---------------------------------------------------------------------- */
38712+
38713+int au_xino_path(struct seq_file *seq, struct file *file)
38714+{
38715+ int err;
38716+
38717+ err = au_seq_path(seq, &file->f_path);
38718+ if (unlikely(err))
38719+ goto out;
38720+
38721+#define Deleted "\\040(deleted)"
38722+ seq->count -= sizeof(Deleted) - 1;
38723+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
38724+ sizeof(Deleted) - 1));
38725+#undef Deleted
38726+
521ced18
JR
38727+out:
38728+ return err;
38729+}
537831f9
AM
38730diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
38731--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
acd2b654 38732+++ linux/include/uapi/linux/aufs_type.h 2018-10-23 12:33:35.602709228 +0200
062440b3
AM
38733@@ -0,0 +1,448 @@
38734+/* SPDX-License-Identifier: GPL-2.0 */
7f207e10 38735+/*
b00004a5 38736+ * Copyright (C) 2005-2018 Junjiro R. Okajima
7f207e10
AM
38737+ *
38738+ * This program, aufs is free software; you can redistribute it and/or modify
38739+ * it under the terms of the GNU General Public License as published by
38740+ * the Free Software Foundation; either version 2 of the License, or
38741+ * (at your option) any later version.
38742+ *
38743+ * This program is distributed in the hope that it will be useful,
38744+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
38745+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38746+ * GNU General Public License for more details.
38747+ *
38748+ * You should have received a copy of the GNU General Public License
523b37e3 38749+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
38750+ */
38751+
38752+#ifndef __AUFS_TYPE_H__
38753+#define __AUFS_TYPE_H__
38754+
f6c5ef8b
AM
38755+#define AUFS_NAME "aufs"
38756+
9dbd164d 38757+#ifdef __KERNEL__
f6c5ef8b
AM
38758+/*
38759+ * define it before including all other headers.
38760+ * sched.h may use pr_* macros before defining "current", so define the
38761+ * no-current version first, and re-define later.
38762+ */
38763+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
38764+#include <linux/sched.h>
38765+#undef pr_fmt
a2a7ad62
AM
38766+#define pr_fmt(fmt) \
38767+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
38768+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
38769+#else
38770+#include <stdint.h>
38771+#include <sys/types.h>
f6c5ef8b 38772+#endif /* __KERNEL__ */
7f207e10 38773+
f6c5ef8b
AM
38774+#include <linux/limits.h>
38775+
acd2b654 38776+#define AUFS_VERSION "4.x-rcN-20181022"
7f207e10
AM
38777+
38778+/* todo? move this to linux-2.6.19/include/magic.h */
38779+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
38780+
38781+/* ---------------------------------------------------------------------- */
38782+
38783+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 38784+typedef int8_t aufs_bindex_t;
7f207e10
AM
38785+#define AUFS_BRANCH_MAX 127
38786+#else
9dbd164d 38787+typedef int16_t aufs_bindex_t;
7f207e10
AM
38788+#ifdef CONFIG_AUFS_BRANCH_MAX_511
38789+#define AUFS_BRANCH_MAX 511
38790+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
38791+#define AUFS_BRANCH_MAX 1023
38792+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
38793+#define AUFS_BRANCH_MAX 32767
38794+#endif
38795+#endif
38796+
38797+#ifdef __KERNEL__
38798+#ifndef AUFS_BRANCH_MAX
38799+#error unknown CONFIG_AUFS_BRANCH_MAX value
38800+#endif
38801+#endif /* __KERNEL__ */
38802+
38803+/* ---------------------------------------------------------------------- */
38804+
7f207e10
AM
38805+#define AUFS_FSTYPE AUFS_NAME
38806+
38807+#define AUFS_ROOT_INO 2
38808+#define AUFS_FIRST_INO 11
38809+
38810+#define AUFS_WH_PFX ".wh."
38811+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
38812+#define AUFS_WH_TMP_LEN 4
86dc4139 38813+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
38814+#define AUFS_MAX_NAMELEN (NAME_MAX \
38815+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
38816+ - 1 /* dot */\
38817+ - AUFS_WH_TMP_LEN) /* hex */
38818+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
38819+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
38820+#define AUFS_XINO_DEF_SEC 30 /* seconds */
38821+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
38822+#define AUFS_DIRWH_DEF 3
38823+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 38824+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
38825+#define AUFS_RDBLK_DEF 512 /* bytes */
38826+#define AUFS_RDHASH_DEF 32
38827+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
38828+#define AUFS_MFS_DEF_SEC 30 /* seconds */
38829+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
076b876e 38830+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
86dc4139 38831+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
38832+
38833+/* pseudo-link maintenace under /proc */
38834+#define AUFS_PLINK_MAINT_NAME "plink_maint"
38835+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
38836+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
38837+
8b6a4947
AM
38838+/* dirren, renamed dir */
38839+#define AUFS_DR_INFO_PFX AUFS_WH_PFX ".dr."
38840+#define AUFS_DR_BRHINO_NAME AUFS_WH_PFX "hino"
38841+/* whiteouted doubly */
38842+#define AUFS_WH_DR_INFO_PFX AUFS_WH_PFX AUFS_DR_INFO_PFX
38843+#define AUFS_WH_DR_BRHINO AUFS_WH_PFX AUFS_DR_BRHINO_NAME
38844+
7f207e10
AM
38845+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
38846+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
38847+
38848+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
38849+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
38850+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
38851+
38852+/* doubly whiteouted */
38853+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
38854+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
38855+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
38856+
1e00d052 38857+/* branch permissions and attributes */
7f207e10
AM
38858+#define AUFS_BRPERM_RW "rw"
38859+#define AUFS_BRPERM_RO "ro"
38860+#define AUFS_BRPERM_RR "rr"
076b876e
AM
38861+#define AUFS_BRATTR_COO_REG "coo_reg"
38862+#define AUFS_BRATTR_COO_ALL "coo_all"
38863+#define AUFS_BRATTR_FHSM "fhsm"
38864+#define AUFS_BRATTR_UNPIN "unpin"
c1595e42
JR
38865+#define AUFS_BRATTR_ICEX "icex"
38866+#define AUFS_BRATTR_ICEX_SEC "icexsec"
38867+#define AUFS_BRATTR_ICEX_SYS "icexsys"
38868+#define AUFS_BRATTR_ICEX_TR "icextr"
38869+#define AUFS_BRATTR_ICEX_USR "icexusr"
38870+#define AUFS_BRATTR_ICEX_OTH "icexoth"
1e00d052
AM
38871+#define AUFS_BRRATTR_WH "wh"
38872+#define AUFS_BRWATTR_NLWH "nolwh"
076b876e
AM
38873+#define AUFS_BRWATTR_MOO "moo"
38874+
38875+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
38876+#define AuBrPerm_RO (1 << 1) /* readonly */
38877+#define AuBrPerm_RR (1 << 2) /* natively readonly */
38878+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
38879+
38880+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
38881+#define AuBrAttr_COO_ALL (1 << 4)
38882+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
38883+
38884+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
38885+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
c1595e42
JR
38886+ branch. meaningless since
38887+ linux-3.18-rc1 */
38888+
38889+/* ignore error in copying XATTR */
38890+#define AuBrAttr_ICEX_SEC (1 << 7)
38891+#define AuBrAttr_ICEX_SYS (1 << 8)
38892+#define AuBrAttr_ICEX_TR (1 << 9)
38893+#define AuBrAttr_ICEX_USR (1 << 10)
38894+#define AuBrAttr_ICEX_OTH (1 << 11)
38895+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \
38896+ | AuBrAttr_ICEX_SYS \
38897+ | AuBrAttr_ICEX_TR \
38898+ | AuBrAttr_ICEX_USR \
38899+ | AuBrAttr_ICEX_OTH)
38900+
38901+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */
076b876e
AM
38902+#define AuBrRAttr_Mask AuBrRAttr_WH
38903+
c1595e42
JR
38904+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */
38905+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */
076b876e
AM
38906+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
38907+
38908+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
38909+
c1595e42 38910+/* #warning test userspace */
076b876e
AM
38911+#ifdef __KERNEL__
38912+#ifndef CONFIG_AUFS_FHSM
38913+#undef AuBrAttr_FHSM
38914+#define AuBrAttr_FHSM 0
38915+#endif
c1595e42
JR
38916+#ifndef CONFIG_AUFS_XATTR
38917+#undef AuBrAttr_ICEX
38918+#define AuBrAttr_ICEX 0
38919+#undef AuBrAttr_ICEX_SEC
38920+#define AuBrAttr_ICEX_SEC 0
38921+#undef AuBrAttr_ICEX_SYS
38922+#define AuBrAttr_ICEX_SYS 0
38923+#undef AuBrAttr_ICEX_TR
38924+#define AuBrAttr_ICEX_TR 0
38925+#undef AuBrAttr_ICEX_USR
38926+#define AuBrAttr_ICEX_USR 0
38927+#undef AuBrAttr_ICEX_OTH
38928+#define AuBrAttr_ICEX_OTH 0
38929+#endif
076b876e
AM
38930+#endif
38931+
38932+/* the longest combination */
c1595e42
JR
38933+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
38934+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
38935+ "+" AUFS_BRATTR_COO_REG \
38936+ "+" AUFS_BRATTR_FHSM \
38937+ "+" AUFS_BRATTR_UNPIN \
7e9cd9fe
AM
38938+ "+" AUFS_BRATTR_ICEX_SEC \
38939+ "+" AUFS_BRATTR_ICEX_SYS \
38940+ "+" AUFS_BRATTR_ICEX_USR \
38941+ "+" AUFS_BRATTR_ICEX_OTH \
076b876e
AM
38942+ "+" AUFS_BRWATTR_NLWH)
38943+
38944+typedef struct {
38945+ char a[AuBrPermStrSz];
38946+} au_br_perm_str_t;
38947+
38948+static inline int au_br_writable(int brperm)
38949+{
38950+ return brperm & AuBrPerm_RW;
38951+}
38952+
38953+static inline int au_br_whable(int brperm)
38954+{
38955+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
38956+}
38957+
38958+static inline int au_br_wh_linkable(int brperm)
38959+{
38960+ return !(brperm & AuBrWAttr_NoLinkWH);
38961+}
38962+
38963+static inline int au_br_cmoo(int brperm)
38964+{
38965+ return brperm & AuBrAttr_CMOO_Mask;
38966+}
38967+
38968+static inline int au_br_fhsm(int brperm)
38969+{
38970+ return brperm & AuBrAttr_FHSM;
38971+}
7f207e10
AM
38972+
38973+/* ---------------------------------------------------------------------- */
38974+
38975+/* ioctl */
38976+enum {
38977+ /* readdir in userspace */
38978+ AuCtl_RDU,
38979+ AuCtl_RDU_INO,
38980+
076b876e
AM
38981+ AuCtl_WBR_FD, /* pathconf wrapper */
38982+ AuCtl_IBUSY, /* busy inode */
38983+ AuCtl_MVDOWN, /* move-down */
38984+ AuCtl_BR, /* info about branches */
38985+ AuCtl_FHSM_FD /* connection for fhsm */
7f207e10
AM
38986+};
38987+
38988+/* borrowed from linux/include/linux/kernel.h */
38989+#ifndef ALIGN
38990+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
38991+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
38992+#endif
38993+
38994+/* borrowed from linux/include/linux/compiler-gcc3.h */
38995+#ifndef __aligned
38996+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
38997+#endif
38998+
38999+#ifdef __KERNEL__
39000+#ifndef __packed
7f207e10
AM
39001+#define __packed __attribute__((packed))
39002+#endif
53392da6 39003+#endif
7f207e10
AM
39004+
39005+struct au_rdu_cookie {
9dbd164d
AM
39006+ uint64_t h_pos;
39007+ int16_t bindex;
39008+ uint8_t flags;
39009+ uint8_t pad;
39010+ uint32_t generation;
7f207e10
AM
39011+} __aligned(8);
39012+
39013+struct au_rdu_ent {
9dbd164d
AM
39014+ uint64_t ino;
39015+ int16_t bindex;
39016+ uint8_t type;
39017+ uint8_t nlen;
39018+ uint8_t wh;
7f207e10
AM
39019+ char name[0];
39020+} __aligned(8);
39021+
39022+static inline int au_rdu_len(int nlen)
39023+{
39024+ /* include the terminating NULL */
39025+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 39026+ sizeof(uint64_t));
7f207e10
AM
39027+}
39028+
39029+union au_rdu_ent_ul {
39030+ struct au_rdu_ent __user *e;
9dbd164d 39031+ uint64_t ul;
7f207e10
AM
39032+};
39033+
39034+enum {
39035+ AufsCtlRduV_SZ,
39036+ AufsCtlRduV_End
39037+};
39038+
39039+struct aufs_rdu {
39040+ /* input */
39041+ union {
9dbd164d
AM
39042+ uint64_t sz; /* AuCtl_RDU */
39043+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
39044+ };
39045+ union au_rdu_ent_ul ent;
9dbd164d 39046+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
39047+
39048+ /* input/output */
9dbd164d 39049+ uint32_t blk;
7f207e10
AM
39050+
39051+ /* output */
39052+ union au_rdu_ent_ul tail;
39053+ /* number of entries which were added in a single call */
9dbd164d
AM
39054+ uint64_t rent;
39055+ uint8_t full;
39056+ uint8_t shwh;
7f207e10
AM
39057+
39058+ struct au_rdu_cookie cookie;
39059+} __aligned(8);
39060+
1e00d052
AM
39061+/* ---------------------------------------------------------------------- */
39062+
8b6a4947
AM
39063+/* dirren. the branch is identified by the filename who contains this */
39064+struct au_drinfo {
39065+ uint64_t ino;
39066+ union {
39067+ uint8_t oldnamelen;
39068+ uint64_t _padding;
39069+ };
39070+ uint8_t oldname[0];
39071+} __aligned(8);
39072+
39073+struct au_drinfo_fdata {
39074+ uint32_t magic;
39075+ struct au_drinfo drinfo;
39076+} __aligned(8);
39077+
39078+#define AUFS_DRINFO_MAGIC_V1 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x01)
39079+/* future */
39080+#define AUFS_DRINFO_MAGIC_V2 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x02)
39081+
39082+/* ---------------------------------------------------------------------- */
39083+
1e00d052 39084+struct aufs_wbr_fd {
9dbd164d
AM
39085+ uint32_t oflags;
39086+ int16_t brid;
1e00d052
AM
39087+} __aligned(8);
39088+
39089+/* ---------------------------------------------------------------------- */
39090+
027c5e7a 39091+struct aufs_ibusy {
9dbd164d
AM
39092+ uint64_t ino, h_ino;
39093+ int16_t bindex;
027c5e7a
AM
39094+} __aligned(8);
39095+
1e00d052
AM
39096+/* ---------------------------------------------------------------------- */
39097+
392086de
AM
39098+/* error code for move-down */
39099+/* the actual message strings are implemented in aufs-util.git */
39100+enum {
39101+ EAU_MVDOWN_OPAQUE = 1,
39102+ EAU_MVDOWN_WHITEOUT,
39103+ EAU_MVDOWN_UPPER,
39104+ EAU_MVDOWN_BOTTOM,
39105+ EAU_MVDOWN_NOUPPER,
39106+ EAU_MVDOWN_NOLOWERBR,
39107+ EAU_Last
39108+};
39109+
c2b27bf2 39110+/* flags for move-down */
392086de
AM
39111+#define AUFS_MVDOWN_DMSG 1
39112+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
39113+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
39114+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
39115+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
39116+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
39117+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
39118+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
39119+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
076b876e
AM
39120+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
39121+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
39122+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
39123+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
c2b27bf2 39124+
076b876e 39125+/* index for move-down */
392086de
AM
39126+enum {
39127+ AUFS_MVDOWN_UPPER,
39128+ AUFS_MVDOWN_LOWER,
39129+ AUFS_MVDOWN_NARRAY
39130+};
39131+
076b876e
AM
39132+/*
39133+ * additional info of move-down
39134+ * number of free blocks and inodes.
39135+ * subset of struct kstatfs, but smaller and always 64bit.
39136+ */
39137+struct aufs_stfs {
39138+ uint64_t f_blocks;
39139+ uint64_t f_bavail;
39140+ uint64_t f_files;
39141+ uint64_t f_ffree;
39142+};
39143+
39144+struct aufs_stbr {
39145+ int16_t brid; /* optional input */
39146+ int16_t bindex; /* output */
39147+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
39148+} __aligned(8);
39149+
c2b27bf2 39150+struct aufs_mvdown {
076b876e
AM
39151+ uint32_t flags; /* input/output */
39152+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
39153+ int8_t au_errno; /* output */
39154+} __aligned(8);
39155+
39156+/* ---------------------------------------------------------------------- */
39157+
39158+union aufs_brinfo {
39159+ /* PATH_MAX may differ between kernel-space and user-space */
39160+ char _spacer[4096];
392086de 39161+ struct {
076b876e
AM
39162+ int16_t id;
39163+ int perm;
39164+ char path[0];
39165+ };
c2b27bf2
AM
39166+} __aligned(8);
39167+
39168+/* ---------------------------------------------------------------------- */
39169+
7f207e10
AM
39170+#define AuCtlType 'A'
39171+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
39172+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
39173+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
39174+ struct aufs_wbr_fd)
027c5e7a 39175+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
39176+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
39177+ struct aufs_mvdown)
076b876e
AM
39178+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
39179+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
7f207e10
AM
39180+
39181+#endif /* __AUFS_TYPE_H__ */
2121bcd9 39182SPDX-License-Identifier: GPL-2.0
cd7a4cd9 39183aufs4.x-rcN loopback patch
5527c038
JR
39184
39185diff --git a/drivers/block/loop.c b/drivers/block/loop.c
acd2b654 39186index 9e534a3..74cd74e 100644
5527c038
JR
39187--- a/drivers/block/loop.c
39188+++ b/drivers/block/loop.c
cd7a4cd9 39189@@ -626,6 +626,15 @@ static inline void loop_update_dio(struct loop_device *lo)
8b6a4947 39190 lo->use_dio);
5527c038
JR
39191 }
39192
5527c038
JR
39193+static struct file *loop_real_file(struct file *file)
39194+{
39195+ struct file *f = NULL;
39196+
39197+ if (file->f_path.dentry->d_sb->s_op->real_loop)
39198+ f = file->f_path.dentry->d_sb->s_op->real_loop(file);
39199+ return f;
8b6a4947
AM
39200+}
39201+
c2c0f25c 39202 static void loop_reread_partitions(struct loop_device *lo,
8b6a4947
AM
39203 struct block_device *bdev)
39204 {
cd7a4cd9 39205@@ -690,6 +699,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
39206 unsigned int arg)
39207 {
39208 struct file *file, *old_file;
39209+ struct file *f, *virt_file = NULL, *old_virt_file;
5527c038
JR
39210 int error;
39211
acd2b654
AM
39212 error = -ENXIO;
39213@@ -705,12 +715,19 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
cd7a4cd9
AM
39214 file = fget(arg);
39215 if (!file)
39216 goto out;
5527c038
JR
39217+ f = loop_real_file(file);
39218+ if (f) {
39219+ virt_file = file;
39220+ file = f;
39221+ get_file(file);
39222+ }
39223
cd7a4cd9
AM
39224 error = loop_validate_file(file, bdev);
39225 if (error)
acd2b654 39226 goto out_putf;
cd7a4cd9 39227
5527c038
JR
39228 old_file = lo->lo_backing_file;
39229+ old_virt_file = lo->lo_backing_virt_file;
39230
39231 error = -EINVAL;
39232
acd2b654 39233@@ -722,6 +739,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
8b6a4947
AM
39234 blk_mq_freeze_queue(lo->lo_queue);
39235 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
39236 lo->lo_backing_file = file;
39237+ lo->lo_backing_virt_file = virt_file;
39238 lo->old_gfp_mask = mapping_gfp_mask(file->f_mapping);
39239 mapping_set_gfp_mask(file->f_mapping,
39240 lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
acd2b654 39241@@ -729,12 +747,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
8b6a4947 39242 blk_mq_unfreeze_queue(lo->lo_queue);
5527c038
JR
39243
39244 fput(old_file);
39245+ if (old_virt_file)
39246+ fput(old_virt_file);
39247 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
c2c0f25c 39248 loop_reread_partitions(lo, bdev);
5527c038
JR
39249 return 0;
39250
39251 out_putf:
39252 fput(file);
39253+ if (virt_file)
39254+ fput(virt_file);
39255 out:
39256 return error;
39257 }
acd2b654 39258@@ -922,7 +944,7 @@ static int loop_prepare_queue(struct loop_device *lo)
5527c038
JR
39259 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
39260 struct block_device *bdev, unsigned int arg)
39261 {
062440b3 39262- struct file *file;
5527c038
JR
39263+ struct file *file, *f, *virt_file = NULL;
39264 struct inode *inode;
39265 struct address_space *mapping;
8b6a4947 39266 int lo_flags = 0;
acd2b654 39267@@ -936,6 +958,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
39268 file = fget(arg);
39269 if (!file)
39270 goto out;
39271+ f = loop_real_file(file);
39272+ if (f) {
39273+ virt_file = file;
39274+ file = f;
39275+ get_file(file);
39276+ }
39277
39278 error = -EBUSY;
39279 if (lo->lo_state != Lo_unbound)
acd2b654 39280@@ -968,6 +996,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
39281 lo->lo_device = bdev;
39282 lo->lo_flags = lo_flags;
39283 lo->lo_backing_file = file;
39284+ lo->lo_backing_virt_file = virt_file;
39285 lo->transfer = NULL;
39286 lo->ioctl = NULL;
39287 lo->lo_sizelimit = 0;
acd2b654 39288@@ -1001,6 +1030,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
39289
39290 out_putf:
39291 fput(file);
39292+ if (virt_file)
39293+ fput(virt_file);
39294 out:
39295 /* This is safe: open() is still holding a reference. */
39296 module_put(THIS_MODULE);
acd2b654 39297@@ -1047,6 +1078,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
5527c038
JR
39298 static int loop_clr_fd(struct loop_device *lo)
39299 {
39300 struct file *filp = lo->lo_backing_file;
39301+ struct file *virt_filp = lo->lo_backing_virt_file;
39302 gfp_t gfp = lo->old_gfp_mask;
39303 struct block_device *bdev = lo->lo_device;
39304
acd2b654 39305@@ -1078,6 +1110,7 @@ static int loop_clr_fd(struct loop_device *lo)
5527c038
JR
39306 spin_lock_irq(&lo->lo_lock);
39307 lo->lo_state = Lo_rundown;
39308 lo->lo_backing_file = NULL;
39309+ lo->lo_backing_virt_file = NULL;
39310 spin_unlock_irq(&lo->lo_lock);
39311
39312 loop_release_xfer(lo);
acd2b654 39313@@ -1126,6 +1159,8 @@ static int loop_clr_fd(struct loop_device *lo)
5527c038
JR
39314 * bd_mutex which is usually taken before lo_ctl_mutex.
39315 */
39316 fput(filp);
39317+ if (virt_filp)
39318+ fput(virt_filp);
39319 return 0;
39320 }
39321
39322diff --git a/drivers/block/loop.h b/drivers/block/loop.h
cd7a4cd9 39323index 4d42c7a..a4974ee 100644
5527c038
JR
39324--- a/drivers/block/loop.h
39325+++ b/drivers/block/loop.h
39326@@ -46,7 +46,7 @@ struct loop_device {
39327 int (*ioctl)(struct loop_device *, int cmd,
39328 unsigned long arg);
39329
39330- struct file * lo_backing_file;
39331+ struct file * lo_backing_file, *lo_backing_virt_file;
39332 struct block_device *lo_device;
5527c038 39333 void *key_data;
8b6a4947 39334
5527c038 39335diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
acd2b654 39336index 5309874..1a334cf 100644
5527c038
JR
39337--- a/fs/aufs/f_op.c
39338+++ b/fs/aufs/f_op.c
acd2b654 39339@@ -359,7 +359,7 @@ static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
5527c038
JR
39340 if (IS_ERR(h_file))
39341 goto out;
39342
39343- if (au_test_loopback_kthread()) {
39344+ if (0 && au_test_loopback_kthread()) {
39345 au_warn_loopback(h_file->f_path.dentry->d_sb);
39346 if (file->f_mapping != h_file->f_mapping) {
39347 file->f_mapping = h_file->f_mapping;
39348diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
cd7a4cd9 39349index 3d84349..a642de5 100644
5527c038
JR
39350--- a/fs/aufs/loop.c
39351+++ b/fs/aufs/loop.c
2121bcd9 39352@@ -133,3 +133,19 @@ void au_loopback_fin(void)
79b8bda9 39353 symbol_put(loop_backing_file);
1c60b727 39354 kfree(au_warn_loopback_array);
5527c038
JR
39355 }
39356+
39357+/* ---------------------------------------------------------------------- */
39358+
39359+/* support the loopback block device insude aufs */
39360+
39361+struct file *aufs_real_loop(struct file *file)
39362+{
39363+ struct file *f;
39364+
39365+ BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
39366+ fi_read_lock(file);
39367+ f = au_hf_top(file);
39368+ fi_read_unlock(file);
39369+ AuDebugOn(!f);
39370+ return f;
39371+}
39372diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
062440b3 39373index 05d703d..6bb23c8 100644
5527c038
JR
39374--- a/fs/aufs/loop.h
39375+++ b/fs/aufs/loop.h
2121bcd9 39376@@ -26,7 +26,11 @@ void au_warn_loopback(struct super_block *h_sb);
5527c038
JR
39377
39378 int au_loopback_init(void);
39379 void au_loopback_fin(void);
39380+
39381+struct file *aufs_real_loop(struct file *file);
39382 #else
39383+AuStub(struct file *, loop_backing_file, return NULL)
39384+
39385 AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
39386 struct dentry *h_adding)
39387 AuStubInt0(au_test_loopback_kthread, void)
2121bcd9 39388@@ -34,6 +38,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
5527c038
JR
39389
39390 AuStubInt0(au_loopback_init, void)
39391 AuStubVoid(au_loopback_fin, void)
39392+
39393+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
39394 #endif /* BLK_DEV_LOOP */
39395
39396 #endif /* __KERNEL__ */
39397diff --git a/fs/aufs/super.c b/fs/aufs/super.c
acd2b654 39398index 777503e..7130061 100644
5527c038
JR
39399--- a/fs/aufs/super.c
39400+++ b/fs/aufs/super.c
acd2b654 39401@@ -845,7 +845,10 @@ static const struct super_operations aufs_sop = {
5527c038
JR
39402 .statfs = aufs_statfs,
39403 .put_super = aufs_put_super,
39404 .sync_fs = aufs_sync_fs,
39405- .remount_fs = aufs_remount_fs
39406+ .remount_fs = aufs_remount_fs,
39407+#ifdef CONFIG_AUFS_BDEV_LOOP
39408+ .real_loop = aufs_real_loop
39409+#endif
39410 };
39411
39412 /* ---------------------------------------------------------------------- */
39413diff --git a/include/linux/fs.h b/include/linux/fs.h
acd2b654 39414index 7fb92a9..cff3ca3 100644
5527c038
JR
39415--- a/include/linux/fs.h
39416+++ b/include/linux/fs.h
acd2b654 39417@@ -1882,6 +1882,10 @@ struct super_operations {
5527c038
JR
39418 struct shrink_control *);
39419 long (*free_cached_objects)(struct super_block *,
39420 struct shrink_control *);
39421+#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
39422+ /* and aufs */
39423+ struct file *(*real_loop)(struct file *);
39424+#endif
39425 };
39426
39427 /*
This page took 7.063945 seconds and 4 git commands to generate.