]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs4.patch
- up to 4.13.2
[packages/kernel.git] / kernel-aufs4.patch
CommitLineData
ffa93bbd 1aufs4.x-rcN kbuild patch
7f207e10
AM
2
3diff --git a/fs/Kconfig b/fs/Kconfig
3c1bdaff 4index 7aee6d6..ec92031 100644
7f207e10
AM
5--- a/fs/Kconfig
6+++ b/fs/Kconfig
3c1bdaff 7@@ -248,6 +248,7 @@ source "fs/pstore/Kconfig"
5527c038 8 source "fs/sysv/Kconfig"
7e9cd9fe 9 source "fs/ufs/Kconfig"
7f207e10
AM
10 source "fs/exofs/Kconfig"
11+source "fs/aufs/Kconfig"
12
13 endif # MISC_FILESYSTEMS
14
15diff --git a/fs/Makefile b/fs/Makefile
a2654f78 16index 7bbaca9..a026491 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
a2654f78 19@@ -128,3 +128,4 @@ obj-y += exofs/ # Multiple modules
7f207e10 20 obj-$(CONFIG_CEPH_FS) += ceph/
bf0370f2 21 obj-$(CONFIG_PSTORE) += pstore/
c06a8ce3 22 obj-$(CONFIG_EFIVAR_FS) += efivarfs/
86dc4139 23+obj-$(CONFIG_AUFS_FS) += aufs/
ffa93bbd 24aufs4.x-rcN base patch
7f207e10 25
c1595e42 26diff --git a/MAINTAINERS b/MAINTAINERS
3c1bdaff 27index 1c3feff..1a12137 100644
c1595e42
JR
28--- a/MAINTAINERS
29+++ b/MAINTAINERS
3c1bdaff 30@@ -2392,6 +2392,19 @@ F: include/linux/audit.h
c1595e42
JR
31 F: include/uapi/linux/audit.h
32 F: kernel/audit*
33
34+AUFS (advanced multi layered unification filesystem) FILESYSTEM
35+M: "J. R. Okajima" <hooanon05g@gmail.com>
36+L: linux-unionfs@vger.kernel.org
37+L: aufs-users@lists.sourceforge.net (members only)
38+W: http://aufs.sourceforge.net
5527c038 39+T: git://github.com/sfjro/aufs4-linux.git
c1595e42
JR
40+S: Supported
41+F: Documentation/filesystems/aufs/
42+F: Documentation/ABI/testing/debugfs-aufs
43+F: Documentation/ABI/testing/sysfs-aufs
44+F: fs/aufs/
45+F: include/uapi/linux/aufs_type.h
46+
47 AUXILIARY DISPLAY DRIVERS
48 M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
49 W: http://miguelojeda.es/auxdisplay.htm
392086de 50diff --git a/drivers/block/loop.c b/drivers/block/loop.c
3c1bdaff 51index f321b96..10707c3 100644
392086de
AM
52--- a/drivers/block/loop.c
53+++ b/drivers/block/loop.c
ffa93bbd 54@@ -700,6 +700,24 @@ static inline int is_loop_device(struct file *file)
392086de
AM
55 return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
56 }
57
58+/*
59+ * for AUFS
60+ * no get/put for file.
61+ */
62+struct file *loop_backing_file(struct super_block *sb)
63+{
64+ struct file *ret;
65+ struct loop_device *l;
66+
67+ ret = NULL;
68+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
69+ l = sb->s_bdev->bd_disk->private_data;
70+ ret = l->lo_backing_file;
71+ }
72+ return ret;
73+}
febd17d6 74+EXPORT_SYMBOL_GPL(loop_backing_file);
392086de
AM
75+
76 /* loop sysfs attributes */
77
78 static ssize_t loop_attr_show(struct device *dev, char *page,
c1595e42 79diff --git a/fs/dcache.c b/fs/dcache.c
3c1bdaff 80index f901413..e3719a5 100644
c1595e42
JR
81--- a/fs/dcache.c
82+++ b/fs/dcache.c
3c1bdaff 83@@ -1197,7 +1197,7 @@ enum d_walk_ret {
c1595e42
JR
84 *
85 * The @enter() and @finish() callbacks are called with d_lock held.
86 */
87-static void d_walk(struct dentry *parent, void *data,
88+void d_walk(struct dentry *parent, void *data,
89 enum d_walk_ret (*enter)(void *, struct dentry *),
90 void (*finish)(void *))
91 {
febd17d6 92diff --git a/fs/fcntl.c b/fs/fcntl.c
3c1bdaff 93index 3b01b64..659760e 100644
febd17d6
JR
94--- a/fs/fcntl.c
95+++ b/fs/fcntl.c
ffa93bbd 96@@ -31,7 +31,7 @@
febd17d6
JR
97
98 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
99
100-static int setfl(int fd, struct file * filp, unsigned long arg)
101+int setfl(int fd, struct file * filp, unsigned long arg)
102 {
103 struct inode * inode = file_inode(filp);
104 int error = 0;
ffa93bbd 105@@ -62,6 +62,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
febd17d6
JR
106
107 if (filp->f_op->check_flags)
108 error = filp->f_op->check_flags(arg);
109+ if (!error && filp->f_op->setfl)
110+ error = filp->f_op->setfl(filp, arg);
111 if (error)
112 return error;
113
5afbbe0d 114diff --git a/fs/inode.c b/fs/inode.c
3c1bdaff 115index 5037059..73820bf 100644
5afbbe0d
AM
116--- a/fs/inode.c
117+++ b/fs/inode.c
3c1bdaff 118@@ -1641,7 +1641,7 @@ EXPORT_SYMBOL(generic_update_time);
5afbbe0d
AM
119 * This does the actual work of updating an inodes time or version. Must have
120 * had called mnt_want_write() before calling this.
121 */
122-static int update_time(struct inode *inode, struct timespec *time, int flags)
123+int update_time(struct inode *inode, struct timespec *time, int flags)
124 {
125 int (*update_time)(struct inode *, struct timespec *, int);
126
5527c038 127diff --git a/fs/read_write.c b/fs/read_write.c
3c1bdaff 128index 0cc7033..6e542f0 100644
5527c038
JR
129--- a/fs/read_write.c
130+++ b/fs/read_write.c
3c1bdaff 131@@ -473,6 +473,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
5527c038
JR
132 }
133 EXPORT_SYMBOL(__vfs_write);
134
135+vfs_readf_t vfs_readf(struct file *file)
136+{
137+ const struct file_operations *fop = file->f_op;
138+
139+ if (fop->read)
140+ return fop->read;
141+ if (fop->read_iter)
142+ return new_sync_read;
143+ return ERR_PTR(-ENOSYS);
144+}
145+
146+vfs_writef_t vfs_writef(struct file *file)
147+{
148+ const struct file_operations *fop = file->f_op;
149+
150+ if (fop->write)
151+ return fop->write;
152+ if (fop->write_iter)
153+ return new_sync_write;
154+ return ERR_PTR(-ENOSYS);
155+}
156+
157 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
158 {
159 mm_segment_t old_fs;
7f207e10 160diff --git a/fs/splice.c b/fs/splice.c
3c1bdaff 161index ae41201..9753304 100644
7f207e10
AM
162--- a/fs/splice.c
163+++ b/fs/splice.c
ffa93bbd 164@@ -853,8 +853,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
165 /*
166 * Attempt to initiate a splice from pipe to file.
167 */
168-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
169- loff_t *ppos, size_t len, unsigned int flags)
170+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
171+ loff_t *ppos, size_t len, unsigned int flags)
172 {
173 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
174 loff_t *, size_t, unsigned int);
ffa93bbd 175@@ -870,9 +870,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
176 /*
177 * Attempt to initiate a splice from a file to a pipe.
178 */
179-static long do_splice_to(struct file *in, loff_t *ppos,
180- struct pipe_inode_info *pipe, size_t len,
181- unsigned int flags)
182+long do_splice_to(struct file *in, loff_t *ppos,
183+ struct pipe_inode_info *pipe, size_t len,
184+ unsigned int flags)
185 {
186 ssize_t (*splice_read)(struct file *, loff_t *,
187 struct pipe_inode_info *, size_t, unsigned int);
a2654f78 188diff --git a/fs/sync.c b/fs/sync.c
3c1bdaff 189index 2a54c1f..7a5fa3f 100644
a2654f78
AM
190--- a/fs/sync.c
191+++ b/fs/sync.c
192@@ -27,7 +27,7 @@
193 * wait == 1 case since in that case write_inode() functions do
194 * sync_dirty_buffer() and thus effectively write one block at a time.
195 */
196-static int __sync_filesystem(struct super_block *sb, int wait)
197+int __sync_filesystem(struct super_block *sb, int wait)
198 {
199 if (wait)
200 sync_inodes_sb(sb);
b912730e 201diff --git a/include/linux/file.h b/include/linux/file.h
a2654f78 202index 61eb82c..e700888 100644
b912730e
AM
203--- a/include/linux/file.h
204+++ b/include/linux/file.h
a2654f78 205@@ -19,6 +19,7 @@ struct dentry;
b912730e 206 struct path;
a2654f78 207 extern struct file *alloc_file(const struct path *, fmode_t mode,
b912730e
AM
208 const struct file_operations *fop);
209+extern struct file *get_empty_filp(void);
210
211 static inline void fput_light(struct file *file, int fput_needed)
212 {
5527c038 213diff --git a/include/linux/fs.h b/include/linux/fs.h
3c1bdaff 214index cbfe127..9b21bb5 100644
5527c038
JR
215--- a/include/linux/fs.h
216+++ b/include/linux/fs.h
3c1bdaff 217@@ -1262,6 +1262,7 @@ extern void fasync_free(struct fasync_struct *);
febd17d6
JR
218 /* can be called from interrupts */
219 extern void kill_fasync(struct fasync_struct **, int, int);
220
221+extern int setfl(int fd, struct file * filp, unsigned long arg);
222 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
3c1bdaff 223 extern int f_setown(struct file *filp, unsigned long arg, int force);
febd17d6 224 extern void f_delown(struct file *filp);
3c1bdaff 225@@ -1683,6 +1684,7 @@ struct file_operations {
febd17d6
JR
226 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
227 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
228 int (*check_flags)(int);
229+ int (*setfl)(struct file *, unsigned long);
230 int (*flock) (struct file *, int, struct file_lock *);
231 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
232 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
3c1bdaff 233@@ -1753,6 +1755,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
5527c038
JR
234 struct iovec *fast_pointer,
235 struct iovec **ret_pointer);
236
237+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *);
238+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t,
239+ loff_t *);
240+vfs_readf_t vfs_readf(struct file *file);
241+vfs_writef_t vfs_writef(struct file *file);
242+
243 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
244 extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
245 extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
3c1bdaff 246@@ -2157,6 +2165,7 @@ extern int current_umask(void);
5afbbe0d
AM
247 extern void ihold(struct inode * inode);
248 extern void iput(struct inode *);
249 extern int generic_update_time(struct inode *, struct timespec *, int);
250+extern int update_time(struct inode *, struct timespec *, int);
251
252 /* /sys/fs */
253 extern struct kobject *fs_kobj;
3c1bdaff 254@@ -2437,6 +2446,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb)
a2654f78
AM
255 return false;
256 }
257 #endif
258+extern int __sync_filesystem(struct super_block *, int);
259 extern int sync_filesystem(struct super_block *);
260 extern const struct file_operations def_blk_fops;
261 extern const struct file_operations def_chr_fops;
1e00d052 262diff --git a/include/linux/splice.h b/include/linux/splice.h
ffa93bbd 263index db42746..12f3a5a 100644
1e00d052
AM
264--- a/include/linux/splice.h
265+++ b/include/linux/splice.h
ffa93bbd 266@@ -86,4 +86,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
267
268 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
106341ce 269 extern const struct pipe_buf_operations default_pipe_buf_ops;
1e00d052
AM
270+
271+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
272+ loff_t *ppos, size_t len, unsigned int flags);
273+extern long do_splice_to(struct file *in, loff_t *ppos,
274+ struct pipe_inode_info *pipe, size_t len,
275+ unsigned int flags);
276 #endif
ffa93bbd 277aufs4.x-rcN mmap patch
fb47a38f 278
c1595e42 279diff --git a/fs/proc/base.c b/fs/proc/base.c
3c1bdaff 280index 719c2e9..a1b7968 100644
c1595e42
JR
281--- a/fs/proc/base.c
282+++ b/fs/proc/base.c
3c1bdaff 283@@ -1986,7 +1986,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
c1595e42
JR
284 down_read(&mm->mmap_sem);
285 vma = find_exact_vma(mm, vm_start, vm_end);
286 if (vma && vma->vm_file) {
287- *path = vma->vm_file->f_path;
288+ *path = vma_pr_or_file(vma)->f_path;
289 path_get(path);
290 rc = 0;
291 }
fb47a38f 292diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
a2654f78 293index 7563437..7c0dc0f 100644
fb47a38f
JR
294--- a/fs/proc/nommu.c
295+++ b/fs/proc/nommu.c
076b876e 296@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
fb47a38f
JR
297 file = region->vm_file;
298
299 if (file) {
300- struct inode *inode = file_inode(region->vm_file);
301+ struct inode *inode;
076b876e 302+
fb47a38f
JR
303+ file = vmr_pr_or_file(region);
304+ inode = file_inode(file);
305 dev = inode->i_sb->s_dev;
306 ino = inode->i_ino;
307 }
308diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
3c1bdaff 309index fe8f326..b2f7f1a 100644
fb47a38f
JR
310--- a/fs/proc/task_mmu.c
311+++ b/fs/proc/task_mmu.c
3c1bdaff 312@@ -293,7 +293,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
fb47a38f
JR
313 const char *name = NULL;
314
315 if (file) {
316- struct inode *inode = file_inode(vma->vm_file);
317+ struct inode *inode;
076b876e 318+
fb47a38f
JR
319+ file = vma_pr_or_file(vma);
320+ inode = file_inode(file);
321 dev = inode->i_sb->s_dev;
322 ino = inode->i_ino;
323 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
3c1bdaff 324@@ -1640,7 +1643,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
076b876e
AM
325 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
326 struct vm_area_struct *vma = v;
327 struct numa_maps *md = &numa_priv->md;
328- struct file *file = vma->vm_file;
329+ struct file *file = vma_pr_or_file(vma);
076b876e 330 struct mm_struct *mm = vma->vm_mm;
7e9cd9fe
AM
331 struct mm_walk walk = {
332 .hugetlb_entry = gather_hugetlb_stats,
fb47a38f 333diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
521ced18 334index 23266694..58e59b6 100644
fb47a38f
JR
335--- a/fs/proc/task_nommu.c
336+++ b/fs/proc/task_nommu.c
521ced18 337@@ -157,7 +157,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
fb47a38f
JR
338 file = vma->vm_file;
339
340 if (file) {
341- struct inode *inode = file_inode(vma->vm_file);
342+ struct inode *inode;
076b876e 343+
b912730e 344+ file = vma_pr_or_file(vma);
fb47a38f
JR
345+ inode = file_inode(file);
346 dev = inode->i_sb->s_dev;
347 ino = inode->i_ino;
348 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
349diff --git a/include/linux/mm.h b/include/linux/mm.h
3c1bdaff 350index 46b9ac5..62ba1c3 100644
fb47a38f
JR
351--- a/include/linux/mm.h
352+++ b/include/linux/mm.h
ffa93bbd 353@@ -1306,6 +1306,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
fb47a38f
JR
354 }
355 #endif
356
076b876e
AM
357+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
358+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
f2c43d5f 359+ int);
076b876e
AM
360+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
361+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
fb47a38f 362+
f2c43d5f
AM
363+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
364+ __LINE__)
365+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
366+ __LINE__)
367+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
368+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
b912730e
AM
369+
370+#ifndef CONFIG_MMU
076b876e
AM
371+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
372+extern void vmr_do_fput(struct vm_region *, const char[], int);
373+
f2c43d5f
AM
374+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
375+ __LINE__)
376+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
b912730e 377+#endif /* !CONFIG_MMU */
fb47a38f 378+
106341ce
AM
379 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len,
380 unsigned int gup_flags);
fb47a38f 381 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
fb47a38f 382diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
3c1bdaff 383index 3cadee0..d0142c1 100644
fb47a38f
JR
384--- a/include/linux/mm_types.h
385+++ b/include/linux/mm_types.h
521ced18 386@@ -259,6 +259,7 @@ struct vm_region {
fb47a38f
JR
387 unsigned long vm_top; /* region allocated to here */
388 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
389 struct file *vm_file; /* the backing file or NULL */
390+ struct file *vm_prfile; /* the virtual backing file or NULL */
391
392 int vm_usage; /* region usage count (access under nommu_region_sem) */
393 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
521ced18 394@@ -333,6 +334,7 @@ struct vm_area_struct {
fb47a38f 395 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
5afbbe0d 396 units */
fb47a38f
JR
397 struct file * vm_file; /* File we map to (can be NULL). */
398+ struct file *vm_prfile; /* shadow of vm_file */
399 void * vm_private_data; /* was vm_pte (shared mem) */
400
401 #ifndef CONFIG_MMU
402diff --git a/kernel/fork.c b/kernel/fork.c
3c1bdaff 403index cbbea27..f0fd8a1 100644
fb47a38f
JR
404--- a/kernel/fork.c
405+++ b/kernel/fork.c
3c1bdaff 406@@ -663,7 +663,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
fb47a38f
JR
407 struct inode *inode = file_inode(file);
408 struct address_space *mapping = file->f_mapping;
409
410- get_file(file);
411+ vma_get_file(tmp);
412 if (tmp->vm_flags & VM_DENYWRITE)
413 atomic_dec(&inode->i_writecount);
2000de60 414 i_mmap_lock_write(mapping);
076b876e 415diff --git a/mm/Makefile b/mm/Makefile
3c1bdaff 416index 411bd24..e7de927 100644
076b876e
AM
417--- a/mm/Makefile
418+++ b/mm/Makefile
521ced18 419@@ -39,7 +39,7 @@ obj-y := filemap.o mempool.o oom_kill.o \
076b876e 420 mm_init.o mmu_context.o percpu.o slab_common.o \
521ced18 421 compaction.o vmacache.o swap_slots.o \
076b876e 422 interval_tree.o list_lru.o workingset.o \
7e9cd9fe
AM
423- debug.o $(mmu-y)
424+ prfile.o debug.o $(mmu-y)
076b876e
AM
425
426 obj-y += init-mm.o
427
fb47a38f 428diff --git a/mm/filemap.c b/mm/filemap.c
3c1bdaff 429index 0b41c8c..c5262ff 100644
fb47a38f
JR
430--- a/mm/filemap.c
431+++ b/mm/filemap.c
3c1bdaff 432@@ -2543,7 +2543,7 @@ int filemap_page_mkwrite(struct vm_fault *vmf)
fb47a38f
JR
433 int ret = VM_FAULT_LOCKED;
434
435 sb_start_pagefault(inode->i_sb);
521ced18
JR
436- file_update_time(vmf->vma->vm_file);
437+ vma_file_update_time(vmf->vma);
fb47a38f
JR
438 lock_page(page);
439 if (page->mapping != inode->i_mapping) {
440 unlock_page(page);
fb47a38f 441diff --git a/mm/mmap.c b/mm/mmap.c
3c1bdaff 442index f19efcf..7fdd59e 100644
fb47a38f
JR
443--- a/mm/mmap.c
444+++ b/mm/mmap.c
f2c43d5f 445@@ -170,7 +170,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
fb47a38f
JR
446 if (vma->vm_ops && vma->vm_ops->close)
447 vma->vm_ops->close(vma);
448 if (vma->vm_file)
449- fput(vma->vm_file);
450+ vma_fput(vma);
451 mpol_put(vma_policy(vma));
452 kmem_cache_free(vm_area_cachep, vma);
453 return next;
1c60b727 454@@ -895,7 +895,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
fb47a38f
JR
455 if (remove_next) {
456 if (file) {
457 uprobe_munmap(next, next->vm_start, next->vm_end);
458- fput(file);
459+ vma_fput(vma);
460 }
461 if (next->anon_vma)
462 anon_vma_merge(vma, next);
1c60b727 463@@ -1745,8 +1745,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
35939ee7
JR
464 return addr;
465
fb47a38f 466 unmap_and_free_vma:
fb47a38f
JR
467+ vma_fput(vma);
468 vma->vm_file = NULL;
469- fput(file);
470
471 /* Undo any partial mapping done by a device driver. */
472 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
3c1bdaff 473@@ -2568,7 +2568,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
474 goto out_free_mpol;
475
476 if (new->vm_file)
477- get_file(new->vm_file);
478+ vma_get_file(new);
479
480 if (new->vm_ops && new->vm_ops->open)
481 new->vm_ops->open(new);
3c1bdaff 482@@ -2587,7 +2587,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
483 if (new->vm_ops && new->vm_ops->close)
484 new->vm_ops->close(new);
485 if (new->vm_file)
486- fput(new->vm_file);
487+ vma_fput(new);
488 unlink_anon_vmas(new);
489 out_free_mpol:
490 mpol_put(vma_policy(new));
3c1bdaff 491@@ -2741,7 +2741,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
7e9cd9fe
AM
492 struct vm_area_struct *vma;
493 unsigned long populate = 0;
494 unsigned long ret = -EINVAL;
495- struct file *file;
5afbbe0d 496+ struct file *file, *prfile;
7e9cd9fe 497
5afbbe0d
AM
498 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.txt.\n",
499 current->comm, current->pid);
3c1bdaff 500@@ -2816,10 +2816,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
febd17d6 501 }
7e9cd9fe
AM
502 }
503
504- file = get_file(vma->vm_file);
505+ vma_get_file(vma);
5afbbe0d
AM
506+ file = vma->vm_file;
507+ prfile = vma->vm_prfile;
7e9cd9fe 508 ret = do_mmap_pgoff(vma->vm_file, start, size,
521ced18 509 prot, flags, pgoff, &populate, NULL);
5afbbe0d
AM
510+ if (!IS_ERR_VALUE(ret) && file && prfile) {
511+ struct vm_area_struct *new_vma;
512+
513+ new_vma = find_vma(mm, ret);
514+ if (!new_vma->vm_prfile)
515+ new_vma->vm_prfile = prfile;
516+ if (new_vma != vma)
517+ get_file(prfile);
518+ }
519+ /*
520+ * two fput()s instead of vma_fput(vma),
521+ * coz vma may not be available anymore.
522+ */
523 fput(file);
524+ if (prfile)
525+ fput(prfile);
7e9cd9fe
AM
526 out:
527 up_write(&mm->mmap_sem);
528 if (populate)
3c1bdaff 529@@ -3110,7 +3127,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
79b8bda9
AM
530 if (anon_vma_clone(new_vma, vma))
531 goto out_free_mempol;
532 if (new_vma->vm_file)
533- get_file(new_vma->vm_file);
534+ vma_get_file(new_vma);
535 if (new_vma->vm_ops && new_vma->vm_ops->open)
536 new_vma->vm_ops->open(new_vma);
537 vma_link(mm, new_vma, prev, rb_link, rb_parent);
fb47a38f 538diff --git a/mm/nommu.c b/mm/nommu.c
ffa93bbd 539index fc184f5..637ea81 100644
fb47a38f
JR
540--- a/mm/nommu.c
541+++ b/mm/nommu.c
ffa93bbd 542@@ -641,7 +641,7 @@ static void __put_nommu_region(struct vm_region *region)
fb47a38f
JR
543 up_write(&nommu_region_sem);
544
545 if (region->vm_file)
546- fput(region->vm_file);
547+ vmr_fput(region);
548
549 /* IO memory and memory shared directly out of the pagecache
550 * from ramfs/tmpfs mustn't be released here */
ffa93bbd 551@@ -799,7 +799,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
fb47a38f
JR
552 if (vma->vm_ops && vma->vm_ops->close)
553 vma->vm_ops->close(vma);
554 if (vma->vm_file)
555- fput(vma->vm_file);
556+ vma_fput(vma);
557 put_nommu_region(vma->vm_region);
558 kmem_cache_free(vm_area_cachep, vma);
559 }
ffa93bbd 560@@ -1326,7 +1326,7 @@ unsigned long do_mmap(struct file *file,
fb47a38f
JR
561 goto error_just_free;
562 }
563 }
564- fput(region->vm_file);
565+ vmr_fput(region);
566 kmem_cache_free(vm_region_jar, region);
567 region = pregion;
568 result = start;
ffa93bbd 569@@ -1401,10 +1401,10 @@ unsigned long do_mmap(struct file *file,
fb47a38f
JR
570 up_write(&nommu_region_sem);
571 error:
572 if (region->vm_file)
573- fput(region->vm_file);
574+ vmr_fput(region);
575 kmem_cache_free(vm_region_jar, region);
576 if (vma->vm_file)
577- fput(vma->vm_file);
578+ vma_fput(vma);
579 kmem_cache_free(vm_area_cachep, vma);
fb47a38f 580 return ret;
c2c0f25c 581
076b876e
AM
582diff --git a/mm/prfile.c b/mm/prfile.c
583new file mode 100644
1c60b727 584index 0000000..1ef053b
076b876e
AM
585--- /dev/null
586+++ b/mm/prfile.c
1c60b727 587@@ -0,0 +1,85 @@
076b876e 588+/*
1c60b727
AM
589+ * Mainly for aufs which mmap(2) different file and wants to print different
590+ * path in /proc/PID/maps.
076b876e
AM
591+ * Call these functions via macros defined in linux/mm.h.
592+ *
593+ * See Documentation/filesystems/aufs/design/06mmap.txt
594+ *
1c60b727 595+ * Copyright (c) 2014-2017 Junjro R. Okajima
076b876e
AM
596+ * Copyright (c) 2014 Ian Campbell
597+ */
598+
599+#include <linux/mm.h>
600+#include <linux/file.h>
601+#include <linux/fs.h>
602+
603+/* #define PRFILE_TRACE */
604+static inline void prfile_trace(struct file *f, struct file *pr,
605+ const char func[], int line, const char func2[])
606+{
607+#ifdef PRFILE_TRACE
608+ if (pr)
1c60b727 609+ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f);
076b876e
AM
610+#endif
611+}
612+
076b876e
AM
613+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
614+ int line)
615+{
616+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
617+
618+ prfile_trace(f, pr, func, line, __func__);
619+ file_update_time(f);
620+ if (f && pr)
621+ file_update_time(pr);
622+}
623+
624+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
625+ int line)
626+{
627+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
628+
629+ prfile_trace(f, pr, func, line, __func__);
630+ return (f && pr) ? pr : f;
631+}
632+
633+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
634+{
635+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
636+
637+ prfile_trace(f, pr, func, line, __func__);
638+ get_file(f);
639+ if (f && pr)
640+ get_file(pr);
641+}
642+
643+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
644+{
645+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
646+
647+ prfile_trace(f, pr, func, line, __func__);
648+ fput(f);
649+ if (f && pr)
650+ fput(pr);
651+}
b912730e
AM
652+
653+#ifndef CONFIG_MMU
076b876e
AM
654+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
655+ int line)
656+{
657+ struct file *f = region->vm_file, *pr = region->vm_prfile;
658+
659+ prfile_trace(f, pr, func, line, __func__);
660+ return (f && pr) ? pr : f;
661+}
662+
663+void vmr_do_fput(struct vm_region *region, const char func[], int line)
664+{
665+ struct file *f = region->vm_file, *pr = region->vm_prfile;
666+
667+ prfile_trace(f, pr, func, line, __func__);
668+ fput(f);
669+ if (f && pr)
670+ fput(pr);
671+}
b912730e 672+#endif /* !CONFIG_MMU */
ffa93bbd 673aufs4.x-rcN standalone patch
7f207e10 674
c1595e42 675diff --git a/fs/dcache.c b/fs/dcache.c
3c1bdaff 676index e3719a5..3203470 100644
c1595e42
JR
677--- a/fs/dcache.c
678+++ b/fs/dcache.c
3c1bdaff 679@@ -1305,6 +1305,7 @@ void d_walk(struct dentry *parent, void *data,
c1595e42
JR
680 seq = 1;
681 goto again;
682 }
febd17d6 683+EXPORT_SYMBOL_GPL(d_walk);
c1595e42 684
a2654f78
AM
685 struct check_mount {
686 struct vfsmount *mnt;
3c1bdaff 687@@ -2894,6 +2895,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2)
f2c43d5f
AM
688
689 write_sequnlock(&rename_lock);
690 }
691+EXPORT_SYMBOL_GPL(d_exchange);
692
693 /**
694 * d_ancestor - search for an ancestor
79b8bda9 695diff --git a/fs/exec.c b/fs/exec.c
3c1bdaff 696index 62175cb..f0b6fdd 100644
79b8bda9
AM
697--- a/fs/exec.c
698+++ b/fs/exec.c
521ced18 699@@ -109,6 +109,7 @@ bool path_noexec(const struct path *path)
79b8bda9
AM
700 return (path->mnt->mnt_flags & MNT_NOEXEC) ||
701 (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
702 }
febd17d6 703+EXPORT_SYMBOL_GPL(path_noexec);
79b8bda9
AM
704
705 #ifdef CONFIG_USELIB
706 /*
febd17d6 707diff --git a/fs/fcntl.c b/fs/fcntl.c
3c1bdaff 708index 659760e..5c37087 100644
febd17d6
JR
709--- a/fs/fcntl.c
710+++ b/fs/fcntl.c
ffa93bbd 711@@ -84,6 +84,7 @@ int setfl(int fd, struct file * filp, unsigned long arg)
febd17d6
JR
712 out:
713 return error;
714 }
715+EXPORT_SYMBOL_GPL(setfl);
716
717 static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
718 int force)
b912730e 719diff --git a/fs/file_table.c b/fs/file_table.c
3c1bdaff 720index 72e861a..01ae52f 100644
b912730e
AM
721--- a/fs/file_table.c
722+++ b/fs/file_table.c
521ced18 723@@ -148,6 +148,7 @@ struct file *get_empty_filp(void)
b912730e
AM
724 }
725 return ERR_PTR(-ENFILE);
726 }
febd17d6 727+EXPORT_SYMBOL_GPL(get_empty_filp);
b912730e
AM
728
729 /**
730 * alloc_file - allocate and initialize a 'struct file'
3c1bdaff 731@@ -260,6 +261,7 @@ void flush_delayed_fput(void)
8cdd5066
JR
732 {
733 delayed_fput(NULL);
734 }
febd17d6 735+EXPORT_SYMBOL_GPL(flush_delayed_fput);
8cdd5066
JR
736
737 static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
738
3c1bdaff 739@@ -302,6 +304,7 @@ void __fput_sync(struct file *file)
8cdd5066
JR
740 }
741
742 EXPORT_SYMBOL(fput);
febd17d6 743+EXPORT_SYMBOL_GPL(__fput_sync);
8cdd5066
JR
744
745 void put_filp(struct file *file)
746 {
3c1bdaff 747@@ -310,6 +313,7 @@ void put_filp(struct file *file)
b912730e
AM
748 file_free(file);
749 }
750 }
febd17d6 751+EXPORT_SYMBOL_GPL(put_filp);
b912730e 752
79b8bda9 753 void __init files_init(void)
b912730e 754 {
5afbbe0d 755diff --git a/fs/inode.c b/fs/inode.c
3c1bdaff 756index 73820bf..7db829e 100644
5afbbe0d
AM
757--- a/fs/inode.c
758+++ b/fs/inode.c
3c1bdaff 759@@ -1650,6 +1650,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
5afbbe0d
AM
760
761 return update_time(inode, time, flags);
762 }
763+EXPORT_SYMBOL_GPL(update_time);
764
765 /**
766 * touch_atime - update the access time
7f207e10 767diff --git a/fs/namespace.c b/fs/namespace.c
3c1bdaff 768index f8893dc..c55d949 100644
7f207e10
AM
769--- a/fs/namespace.c
770+++ b/fs/namespace.c
3c1bdaff 771@@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
772 mnt_dec_writers(real_mount(mnt));
773 preempt_enable();
774 }
775+EXPORT_SYMBOL_GPL(__mnt_drop_write);
776
777 /**
778 * mnt_drop_write - give up write access to a mount
3c1bdaff 779@@ -1823,6 +1824,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
780 }
781 return 0;
782 }
febd17d6 783+EXPORT_SYMBOL_GPL(iterate_mounts);
7f207e10 784
7eafdf33 785 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
786 {
787diff --git a/fs/notify/group.c b/fs/notify/group.c
ffa93bbd 788index 3235753..14a2d48 100644
7f207e10
AM
789--- a/fs/notify/group.c
790+++ b/fs/notify/group.c
791@@ -22,6 +22,7 @@
792 #include <linux/srcu.h>
793 #include <linux/rculist.h>
794 #include <linux/wait.h>
795+#include <linux/module.h>
796
797 #include <linux/fsnotify_backend.h>
798 #include "fsnotify.h"
ffa93bbd 799@@ -109,6 +110,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
1716fcea
AM
800 {
801 atomic_inc(&group->refcnt);
802 }
febd17d6 803+EXPORT_SYMBOL_GPL(fsnotify_get_group);
1716fcea
AM
804
805 /*
806 * Drop a reference to a group. Free it if it's through.
ffa93bbd 807@@ -118,6 +120,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
7f207e10 808 if (atomic_dec_and_test(&group->refcnt))
1716fcea 809 fsnotify_final_destroy_group(group);
7f207e10 810 }
febd17d6 811+EXPORT_SYMBOL_GPL(fsnotify_put_group);
7f207e10
AM
812
813 /*
814 * Create a new fsnotify_group and hold a reference for the group returned.
ffa93bbd 815@@ -147,6 +150,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
816
817 return group;
818 }
febd17d6 819+EXPORT_SYMBOL_GPL(fsnotify_alloc_group);
1716fcea
AM
820
821 int fsnotify_fasync(int fd, struct file *file, int on)
822 {
7f207e10 823diff --git a/fs/notify/mark.c b/fs/notify/mark.c
ffa93bbd 824index 9991f88..117042c 100644
7f207e10
AM
825--- a/fs/notify/mark.c
826+++ b/fs/notify/mark.c
ffa93bbd
AM
827@@ -118,6 +118,7 @@ static bool fsnotify_get_mark_safe(struct fsnotify_mark *mark)
828 {
829 return atomic_inc_not_zero(&mark->refcnt);
7f207e10 830 }
febd17d6 831+EXPORT_SYMBOL_GPL(fsnotify_put_mark);
7f207e10 832
ffa93bbd
AM
833 static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
834 {
835@@ -395,6 +396,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea 836 mutex_unlock(&group->mark_mutex);
79b8bda9 837 fsnotify_free_mark(mark);
7f207e10 838 }
febd17d6 839+EXPORT_SYMBOL_GPL(fsnotify_destroy_mark);
7f207e10 840
ffa93bbd
AM
841 /*
842 * Sorting function for lists of fsnotify marks.
843@@ -607,6 +609,7 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark, struct inode *inode,
844 fsnotify_put_mark(mark);
7f207e10
AM
845 return ret;
846 }
febd17d6 847+EXPORT_SYMBOL_GPL(fsnotify_add_mark);
7f207e10 848
ffa93bbd
AM
849 int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode,
850 struct vfsmount *mnt, int allow_dups)
851@@ -742,6 +745,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
852 fsnotify_get_group(group);
853 mark->group = group;
7f207e10 854 }
febd17d6 855+EXPORT_SYMBOL_GPL(fsnotify_init_mark);
7f207e10 856
5afbbe0d
AM
857 /*
858 * Destroy all marks in destroy_list, waits for SRCU period to finish before
7f207e10 859diff --git a/fs/open.c b/fs/open.c
3c1bdaff 860index 35bb784..92e08c5 100644
7f207e10
AM
861--- a/fs/open.c
862+++ b/fs/open.c
c2c0f25c 863@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
febd17d6 864 inode_unlock(dentry->d_inode);
7f207e10
AM
865 return ret;
866 }
febd17d6 867+EXPORT_SYMBOL_GPL(do_truncate);
7f207e10 868
5afbbe0d 869 long vfs_truncate(const struct path *path, loff_t length)
7f207e10 870 {
ffa93bbd 871@@ -691,6 +692,7 @@ int open_check_o_direct(struct file *f)
b912730e
AM
872 }
873 return 0;
874 }
febd17d6 875+EXPORT_SYMBOL_GPL(open_check_o_direct);
b912730e
AM
876
877 static int do_dentry_open(struct file *f,
c2c0f25c 878 struct inode *inode,
5527c038 879diff --git a/fs/read_write.c b/fs/read_write.c
3c1bdaff 880index 6e542f0..c6fa090 100644
5527c038
JR
881--- a/fs/read_write.c
882+++ b/fs/read_write.c
3c1bdaff 883@@ -483,6 +483,7 @@ vfs_readf_t vfs_readf(struct file *file)
5527c038
JR
884 return new_sync_read;
885 return ERR_PTR(-ENOSYS);
886 }
febd17d6 887+EXPORT_SYMBOL_GPL(vfs_readf);
5527c038
JR
888
889 vfs_writef_t vfs_writef(struct file *file)
890 {
3c1bdaff 891@@ -494,6 +495,7 @@ vfs_writef_t vfs_writef(struct file *file)
5527c038
JR
892 return new_sync_write;
893 return ERR_PTR(-ENOSYS);
894 }
febd17d6 895+EXPORT_SYMBOL_GPL(vfs_writef);
5527c038
JR
896
897 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
898 {
7f207e10 899diff --git a/fs/splice.c b/fs/splice.c
3c1bdaff 900index 9753304..b38e036 100644
7f207e10
AM
901--- a/fs/splice.c
902+++ b/fs/splice.c
ffa93bbd 903@@ -866,6 +866,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
392086de
AM
904
905 return splice_write(pipe, out, ppos, len, flags);
7f207e10 906 }
febd17d6 907+EXPORT_SYMBOL_GPL(do_splice_from);
7f207e10
AM
908
909 /*
910 * Attempt to initiate a splice from a file to a pipe.
ffa93bbd 911@@ -895,6 +896,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
912
913 return splice_read(in, ppos, pipe, len, flags);
914 }
febd17d6 915+EXPORT_SYMBOL_GPL(do_splice_to);
7f207e10
AM
916
917 /**
918 * splice_direct_to_actor - splices data directly between two non-pipes
a2654f78 919diff --git a/fs/sync.c b/fs/sync.c
3c1bdaff 920index 7a5fa3f..c9b9d46 100644
a2654f78
AM
921--- a/fs/sync.c
922+++ b/fs/sync.c
923@@ -38,6 +38,7 @@ int __sync_filesystem(struct super_block *sb, int wait)
924 sb->s_op->sync_fs(sb, wait);
925 return __sync_blockdev(sb->s_bdev, wait);
926 }
927+EXPORT_SYMBOL_GPL(__sync_filesystem);
928
929 /*
930 * Write out and wait upon all dirty data associated with this
c1595e42 931diff --git a/fs/xattr.c b/fs/xattr.c
ffa93bbd 932index 464c94b..0234d49 100644
c1595e42
JR
933--- a/fs/xattr.c
934+++ b/fs/xattr.c
a2654f78 935@@ -296,6 +296,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
c1595e42
JR
936 *xattr_value = value;
937 return error;
938 }
febd17d6 939+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);
c1595e42 940
febd17d6 941 ssize_t
f2c43d5f 942 __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
8cdd5066 943diff --git a/kernel/task_work.c b/kernel/task_work.c
e2f27e51 944index d513051..e056d54 100644
8cdd5066
JR
945--- a/kernel/task_work.c
946+++ b/kernel/task_work.c
e2f27e51 947@@ -119,3 +119,4 @@ void task_work_run(void)
8cdd5066
JR
948 } while (work);
949 }
950 }
febd17d6 951+EXPORT_SYMBOL_GPL(task_work_run);
7f207e10 952diff --git a/security/commoncap.c b/security/commoncap.c
ffa93bbd 953index 7abebd7..c079ce4 100644
7f207e10
AM
954--- a/security/commoncap.c
955+++ b/security/commoncap.c
521ced18 956@@ -1062,12 +1062,14 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 957 }
7f207e10
AM
958 return ret;
959 }
febd17d6 960+EXPORT_SYMBOL_GPL(cap_mmap_addr);
0c3ec466
AM
961
962 int cap_mmap_file(struct file *file, unsigned long reqprot,
963 unsigned long prot, unsigned long flags)
964 {
965 return 0;
966 }
febd17d6 967+EXPORT_SYMBOL_GPL(cap_mmap_file);
c2c0f25c
AM
968
969 #ifdef CONFIG_SECURITY
970
7f207e10 971diff --git a/security/device_cgroup.c b/security/device_cgroup.c
febd17d6 972index 03c1652..f88c84b 100644
7f207e10
AM
973--- a/security/device_cgroup.c
974+++ b/security/device_cgroup.c
f6c5ef8b
AM
975@@ -7,6 +7,7 @@
976 #include <linux/device_cgroup.h>
977 #include <linux/cgroup.h>
978 #include <linux/ctype.h>
979+#include <linux/export.h>
980 #include <linux/list.h>
981 #include <linux/uaccess.h>
982 #include <linux/seq_file.h>
076b876e 983@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
984 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
985 access);
7f207e10 986 }
febd17d6 987+EXPORT_SYMBOL_GPL(__devcgroup_inode_permission);
7f207e10
AM
988
989 int devcgroup_inode_mknod(int mode, dev_t dev)
990 {
991diff --git a/security/security.c b/security/security.c
3c1bdaff 992index 3013237..342ce8b 100644
7f207e10
AM
993--- a/security/security.c
994+++ b/security/security.c
3c1bdaff 995@@ -535,6 +535,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry)
7f207e10 996 return 0;
c2c0f25c 997 return call_int_hook(path_rmdir, 0, dir, dentry);
7f207e10 998 }
febd17d6 999+EXPORT_SYMBOL_GPL(security_path_rmdir);
7f207e10 1000
5afbbe0d 1001 int security_path_unlink(const struct path *dir, struct dentry *dentry)
7f207e10 1002 {
3c1bdaff 1003@@ -551,6 +552,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry,
7f207e10 1004 return 0;
c2c0f25c 1005 return call_int_hook(path_symlink, 0, dir, dentry, old_name);
7f207e10 1006 }
febd17d6 1007+EXPORT_SYMBOL_GPL(security_path_symlink);
7f207e10 1008
5afbbe0d 1009 int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
7f207e10 1010 struct dentry *new_dentry)
3c1bdaff 1011@@ -559,6 +561,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
7f207e10 1012 return 0;
c2c0f25c 1013 return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
7f207e10 1014 }
febd17d6 1015+EXPORT_SYMBOL_GPL(security_path_link);
7f207e10 1016
5afbbe0d
AM
1017 int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
1018 const struct path *new_dir, struct dentry *new_dentry,
3c1bdaff 1019@@ -586,6 +589,7 @@ int security_path_truncate(const struct path *path)
7f207e10 1020 return 0;
c2c0f25c 1021 return call_int_hook(path_truncate, 0, path);
7f207e10 1022 }
febd17d6 1023+EXPORT_SYMBOL_GPL(security_path_truncate);
7f207e10 1024
5afbbe0d 1025 int security_path_chmod(const struct path *path, umode_t mode)
7eafdf33 1026 {
3c1bdaff 1027@@ -593,6 +597,7 @@ int security_path_chmod(const struct path *path, umode_t mode)
7f207e10 1028 return 0;
c2c0f25c 1029 return call_int_hook(path_chmod, 0, path, mode);
7f207e10 1030 }
febd17d6 1031+EXPORT_SYMBOL_GPL(security_path_chmod);
7f207e10 1032
5afbbe0d 1033 int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
7f207e10 1034 {
3c1bdaff 1035@@ -600,6 +605,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
7f207e10 1036 return 0;
c2c0f25c 1037 return call_int_hook(path_chown, 0, path, uid, gid);
7f207e10 1038 }
febd17d6 1039+EXPORT_SYMBOL_GPL(security_path_chown);
7f207e10 1040
5afbbe0d 1041 int security_path_chroot(const struct path *path)
7f207e10 1042 {
3c1bdaff 1043@@ -685,6 +691,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10 1044 return 0;
c2c0f25c 1045 return call_int_hook(inode_readlink, 0, dentry);
7f207e10 1046 }
febd17d6 1047+EXPORT_SYMBOL_GPL(security_inode_readlink);
7f207e10 1048
c2c0f25c
AM
1049 int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
1050 bool rcu)
3c1bdaff 1051@@ -700,6 +707,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 1052 return 0;
c2c0f25c 1053 return call_int_hook(inode_permission, 0, inode, mask);
7f207e10 1054 }
febd17d6 1055+EXPORT_SYMBOL_GPL(security_inode_permission);
7f207e10 1056
1e00d052 1057 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 1058 {
3c1bdaff 1059@@ -871,6 +879,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
1060
1061 return fsnotify_perm(file, mask);
1062 }
febd17d6 1063+EXPORT_SYMBOL_GPL(security_file_permission);
7f207e10
AM
1064
1065 int security_file_alloc(struct file *file)
1066 {
3c1bdaff 1067@@ -930,6 +939,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
1068 return ret;
1069 return ima_file_mmap(file, prot);
1070 }
febd17d6 1071+EXPORT_SYMBOL_GPL(security_mmap_file);
7f207e10 1072
0c3ec466
AM
1073 int security_mmap_addr(unsigned long addr)
1074 {
7f207e10
AM
1075diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
1076--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
1c60b727 1077+++ linux/Documentation/ABI/testing/debugfs-aufs 2017-07-29 12:14:25.893041746 +0200
86dc4139 1078@@ -0,0 +1,50 @@
7f207e10
AM
1079+What: /debug/aufs/si_<id>/
1080+Date: March 2009
f6b6e03d 1081+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1082+Description:
1083+ Under /debug/aufs, a directory named si_<id> is created
1084+ per aufs mount, where <id> is a unique id generated
1085+ internally.
1facf9fc 1086+
86dc4139
AM
1087+What: /debug/aufs/si_<id>/plink
1088+Date: Apr 2013
f6b6e03d 1089+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
1090+Description:
1091+ It has three lines and shows the information about the
1092+ pseudo-link. The first line is a single number
1093+ representing a number of buckets. The second line is a
1094+ number of pseudo-links per buckets (separated by a
1095+ blank). The last line is a single number representing a
1096+ total number of psedo-links.
1097+ When the aufs mount option 'noplink' is specified, it
1098+ will show "1\n0\n0\n".
1099+
7f207e10
AM
1100+What: /debug/aufs/si_<id>/xib
1101+Date: March 2009
f6b6e03d 1102+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1103+Description:
1104+ It shows the consumed blocks by xib (External Inode Number
1105+ Bitmap), its block size and file size.
1106+ When the aufs mount option 'noxino' is specified, it
1107+ will be empty. About XINO files, see the aufs manual.
1108+
1109+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
1110+Date: March 2009
f6b6e03d 1111+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1112+Description:
1113+ It shows the consumed blocks by xino (External Inode Number
1114+ Translation Table), its link count, block size and file
1115+ size.
1116+ When the aufs mount option 'noxino' is specified, it
1117+ will be empty. About XINO files, see the aufs manual.
1118+
1119+What: /debug/aufs/si_<id>/xigen
1120+Date: March 2009
f6b6e03d 1121+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1122+Description:
1123+ It shows the consumed blocks by xigen (External Inode
1124+ Generation Table), its block size and file size.
1125+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
1126+ be created.
1127+ When the aufs mount option 'noxino' is specified, it
1128+ will be empty. About XINO files, see the aufs manual.
1129diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
1130--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
1c60b727 1131+++ linux/Documentation/ABI/testing/sysfs-aufs 2017-07-29 12:14:25.893041746 +0200
392086de 1132@@ -0,0 +1,31 @@
7f207e10
AM
1133+What: /sys/fs/aufs/si_<id>/
1134+Date: March 2009
f6b6e03d 1135+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1136+Description:
1137+ Under /sys/fs/aufs, a directory named si_<id> is created
1138+ per aufs mount, where <id> is a unique id generated
1139+ internally.
1140+
1141+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
1142+Date: March 2009
f6b6e03d 1143+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1144+Description:
1145+ It shows the abolute path of a member directory (which
1146+ is called branch) in aufs, and its permission.
1147+
392086de
AM
1148+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
1149+Date: July 2013
f6b6e03d 1150+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
1151+Description:
1152+ It shows the id of a member directory (which is called
1153+ branch) in aufs.
1154+
7f207e10
AM
1155+What: /sys/fs/aufs/si_<id>/xi_path
1156+Date: March 2009
f6b6e03d 1157+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1158+Description:
1159+ It shows the abolute path of XINO (External Inode Number
1160+ Bitmap, Translation Table and Generation Table) file
1161+ even if it is the default path.
1162+ When the aufs mount option 'noxino' is specified, it
1163+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
1164diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
1165--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
3c1bdaff 1166+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2017-09-05 10:42:11.038754821 +0200
1c60b727 1167@@ -0,0 +1,171 @@
53392da6 1168+
a2654f78 1169+# Copyright (C) 2005-2017 Junjiro R. Okajima
53392da6
AM
1170+#
1171+# This program is free software; you can redistribute it and/or modify
1172+# it under the terms of the GNU General Public License as published by
1173+# the Free Software Foundation; either version 2 of the License, or
1174+# (at your option) any later version.
1175+#
1176+# This program is distributed in the hope that it will be useful,
1177+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1178+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1179+# GNU General Public License for more details.
1180+#
1181+# You should have received a copy of the GNU General Public License
523b37e3 1182+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1183+
1184+Introduction
1185+----------------------------------------
1186+
3c1bdaff 1187+aufs [ei ju: ef es] | /ey-yoo-ef-es/ | [a u f s]
53392da6
AM
1188+1. abbrev. for "advanced multi-layered unification filesystem".
1189+2. abbrev. for "another unionfs".
1190+3. abbrev. for "auf das" in German which means "on the" in English.
1191+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
1192+ But "Filesystem aufs Filesystem" is hard to understand.
1c60b727 1193+4. abbrev. for "African Urban Fashion Show".
53392da6
AM
1194+
1195+AUFS is a filesystem with features:
1196+- multi layered stackable unification filesystem, the member directory
1197+ is called as a branch.
1198+- branch permission and attribute, 'readonly', 'real-readonly',
7e9cd9fe 1199+ 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their
53392da6
AM
1200+ combination.
1201+- internal "file copy-on-write".
1202+- logical deletion, whiteout.
1203+- dynamic branch manipulation, adding, deleting and changing permission.
1204+- allow bypassing aufs, user's direct branch access.
1205+- external inode number translation table and bitmap which maintains the
1206+ persistent aufs inode number.
1207+- seekable directory, including NFS readdir.
1208+- file mapping, mmap and sharing pages.
1209+- pseudo-link, hardlink over branches.
1210+- loopback mounted filesystem as a branch.
1211+- several policies to select one among multiple writable branches.
1212+- revert a single systemcall when an error occurs in aufs.
1213+- and more...
1214+
1215+
1216+Multi Layered Stackable Unification Filesystem
1217+----------------------------------------------------------------------
1218+Most people already knows what it is.
1219+It is a filesystem which unifies several directories and provides a
1220+merged single directory. When users access a file, the access will be
1221+passed/re-directed/converted (sorry, I am not sure which English word is
1222+correct) to the real file on the member filesystem. The member
1223+filesystem is called 'lower filesystem' or 'branch' and has a mode
1224+'readonly' and 'readwrite.' And the deletion for a file on the lower
1225+readonly branch is handled by creating 'whiteout' on the upper writable
1226+branch.
1227+
1228+On LKML, there have been discussions about UnionMount (Jan Blunck,
1229+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
1230+different approaches to implement the merged-view.
1231+The former tries putting it into VFS, and the latter implements as a
1232+separate filesystem.
1233+(If I misunderstand about these implementations, please let me know and
1234+I shall correct it. Because it is a long time ago when I read their
1235+source files last time).
1236+
1237+UnionMount's approach will be able to small, but may be hard to share
1238+branches between several UnionMount since the whiteout in it is
1239+implemented in the inode on branch filesystem and always
1240+shared. According to Bharata's post, readdir does not seems to be
1241+finished yet.
1242+There are several missing features known in this implementations such as
1243+- for users, the inode number may change silently. eg. copy-up.
1244+- link(2) may break by copy-up.
1245+- read(2) may get an obsoleted filedata (fstat(2) too).
1246+- fcntl(F_SETLK) may be broken by copy-up.
1247+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
1248+ open(O_RDWR).
1249+
7e9cd9fe
AM
1250+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was
1251+merged into mainline. This is another implementation of UnionMount as a
1252+separated filesystem. All the limitations and known problems which
1253+UnionMount are equally inherited to "overlay" filesystem.
1254+
1255+Unionfs has a longer history. When I started implementing a stackable
1256+filesystem (Aug 2005), it already existed. It has virtual super_block,
1257+inode, dentry and file objects and they have an array pointing lower
1258+same kind objects. After contributing many patches for Unionfs, I
1259+re-started my project AUFS (Jun 2006).
53392da6
AM
1260+
1261+In AUFS, the structure of filesystem resembles to Unionfs, but I
1262+implemented my own ideas, approaches and enhancements and it became
1263+totally different one.
1264+
1265+Comparing DM snapshot and fs based implementation
1266+- the number of bytes to be copied between devices is much smaller.
1267+- the type of filesystem must be one and only.
1268+- the fs must be writable, no readonly fs, even for the lower original
1269+ device. so the compression fs will not be usable. but if we use
1270+ loopback mount, we may address this issue.
1271+ for instance,
1272+ mount /cdrom/squashfs.img /sq
1273+ losetup /sq/ext2.img
1274+ losetup /somewhere/cow
1275+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
1276+- it will be difficult (or needs more operations) to extract the
1277+ difference between the original device and COW.
1278+- DM snapshot-merge may help a lot when users try merging. in the
1279+ fs-layer union, users will use rsync(1).
1280+
7e9cd9fe
AM
1281+You may want to read my old paper "Filesystems in LiveCD"
1282+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf).
53392da6 1283+
7e9cd9fe
AM
1284+
1285+Several characters/aspects/persona of aufs
53392da6
AM
1286+----------------------------------------------------------------------
1287+
7e9cd9fe 1288+Aufs has several characters, aspects or persona.
53392da6
AM
1289+1. a filesystem, callee of VFS helper
1290+2. sub-VFS, caller of VFS helper for branches
1291+3. a virtual filesystem which maintains persistent inode number
1292+4. reader/writer of files on branches such like an application
1293+
1294+1. Callee of VFS Helper
1295+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1296+unlink(2) from an application reaches sys_unlink() kernel function and
1297+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1298+calls filesystem specific unlink operation. Actually aufs implements the
1299+unlink operation but it behaves like a redirector.
1300+
1301+2. Caller of VFS Helper for Branches
1302+aufs_unlink() passes the unlink request to the branch filesystem as if
1303+it were called from VFS. So the called unlink operation of the branch
1304+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1305+every necessary pre/post operation for the branch filesystem.
1306+- acquire the lock for the parent dir on a branch
1307+- lookup in a branch
1308+- revalidate dentry on a branch
1309+- mnt_want_write() for a branch
1310+- vfs_unlink() for a branch
1311+- mnt_drop_write() for a branch
1312+- release the lock on a branch
1313+
1314+3. Persistent Inode Number
1315+One of the most important issue for a filesystem is to maintain inode
1316+numbers. This is particularly important to support exporting a
1317+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1318+backend block device for its own. But some storage is necessary to
7e9cd9fe
AM
1319+keep and maintain the inode numbers. It may be a large space and may not
1320+suit to keep in memory. Aufs rents some space from its first writable
1321+branch filesystem (by default) and creates file(s) on it. These files
1322+are created by aufs internally and removed soon (currently) keeping
1323+opened.
53392da6
AM
1324+Note: Because these files are removed, they are totally gone after
1325+ unmounting aufs. It means the inode numbers are not persistent
1326+ across unmount or reboot. I have a plan to make them really
1327+ persistent which will be important for aufs on NFS server.
1328+
1329+4. Read/Write Files Internally (copy-on-write)
1330+Because a branch can be readonly, when you write a file on it, aufs will
1331+"copy-up" it to the upper writable branch internally. And then write the
1332+originally requested thing to the file. Generally kernel doesn't
1333+open/read/write file actively. In aufs, even a single write may cause a
1334+internal "file copy". This behaviour is very similar to cp(1) command.
1335+
1336+Some people may think it is better to pass such work to user space
1337+helper, instead of doing in kernel space. Actually I am still thinking
1338+about it. But currently I have implemented it in kernel space.
1339diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1340--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 1341+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2017-07-29 12:14:25.893041746 +0200
7e9cd9fe 1342@@ -0,0 +1,258 @@
53392da6 1343+
a2654f78 1344+# Copyright (C) 2005-2017 Junjiro R. Okajima
53392da6
AM
1345+#
1346+# This program is free software; you can redistribute it and/or modify
1347+# it under the terms of the GNU General Public License as published by
1348+# the Free Software Foundation; either version 2 of the License, or
1349+# (at your option) any later version.
1350+#
1351+# This program is distributed in the hope that it will be useful,
1352+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1353+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1354+# GNU General Public License for more details.
1355+#
1356+# You should have received a copy of the GNU General Public License
523b37e3 1357+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1358+
1359+Basic Aufs Internal Structure
1360+
1361+Superblock/Inode/Dentry/File Objects
1362+----------------------------------------------------------------------
1363+As like an ordinary filesystem, aufs has its own
1364+superblock/inode/dentry/file objects. All these objects have a
1365+dynamically allocated array and store the same kind of pointers to the
1366+lower filesystem, branch.
1367+For example, when you build a union with one readwrite branch and one
1368+readonly, mounted /au, /rw and /ro respectively.
1369+- /au = /rw + /ro
1370+- /ro/fileA exists but /rw/fileA
1371+
1372+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1373+pointers are stored in a aufs dentry. The array in aufs dentry will be,
7e9cd9fe 1374+- [0] = NULL (because /rw/fileA doesn't exist)
53392da6
AM
1375+- [1] = /ro/fileA
1376+
1377+This style of an array is essentially same to the aufs
1378+superblock/inode/dentry/file objects.
1379+
1380+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1381+branches dynamically, these objects has its own generation. When
1382+branches are changed, the generation in aufs superblock is
1383+incremented. And a generation in other object are compared when it is
1384+accessed. When a generation in other objects are obsoleted, aufs
1385+refreshes the internal array.
53392da6
AM
1386+
1387+
1388+Superblock
1389+----------------------------------------------------------------------
1390+Additionally aufs superblock has some data for policies to select one
1391+among multiple writable branches, XIB files, pseudo-links and kobject.
1392+See below in detail.
7e9cd9fe
AM
1393+About the policies which supports copy-down a directory, see
1394+wbr_policy.txt too.
53392da6
AM
1395+
1396+
1397+Branch and XINO(External Inode Number Translation Table)
1398+----------------------------------------------------------------------
1399+Every branch has its own xino (external inode number translation table)
1400+file. The xino file is created and unlinked by aufs internally. When two
1401+members of a union exist on the same filesystem, they share the single
1402+xino file.
1403+The struct of a xino file is simple, just a sequence of aufs inode
1404+numbers which is indexed by the lower inode number.
1405+In the above sample, assume the inode number of /ro/fileA is i111 and
1406+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1407+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1408+
1409+When the inode numbers are not contiguous, the xino file will be sparse
1410+which has a hole in it and doesn't consume as much disk space as it
1411+might appear. If your branch filesystem consumes disk space for such
1412+holes, then you should specify 'xino=' option at mounting aufs.
1413+
7e9cd9fe
AM
1414+Aufs has a mount option to free the disk blocks for such holes in XINO
1415+files on tmpfs or ramdisk. But it is not so effective actually. If you
1416+meet a problem of disk shortage due to XINO files, then you should try
1417+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git.
1418+The patch localizes the assignment inumbers per tmpfs-mount and avoid
1419+the holes in XINO files.
1420+
53392da6 1421+Also a writable branch has three kinds of "whiteout bases". All these
7e9cd9fe 1422+are existed when the branch is joined to aufs, and their names are
53392da6
AM
1423+whiteout-ed doubly, so that users will never see their names in aufs
1424+hierarchy.
7e9cd9fe 1425+1. a regular file which will be hardlinked to all whiteouts.
53392da6 1426+2. a directory to store a pseudo-link.
7e9cd9fe 1427+3. a directory to store an "orphan"-ed file temporary.
53392da6
AM
1428+
1429+1. Whiteout Base
1430+ When you remove a file on a readonly branch, aufs handles it as a
1431+ logical deletion and creates a whiteout on the upper writable branch
1432+ as a hardlink of this file in order not to consume inode on the
1433+ writable branch.
1434+2. Pseudo-link Dir
1435+ See below, Pseudo-link.
1436+3. Step-Parent Dir
1437+ When "fileC" exists on the lower readonly branch only and it is
1438+ opened and removed with its parent dir, and then user writes
1439+ something into it, then aufs copies-up fileC to this
1440+ directory. Because there is no other dir to store fileC. After
1441+ creating a file under this dir, the file is unlinked.
1442+
1443+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1444+dynamically, a branch has its own id. When the branch order changes,
1445+aufs finds the new index by searching the branch id.
53392da6
AM
1446+
1447+
1448+Pseudo-link
1449+----------------------------------------------------------------------
1450+Assume "fileA" exists on the lower readonly branch only and it is
1451+hardlinked to "fileB" on the branch. When you write something to fileA,
1452+aufs copies-up it to the upper writable branch. Additionally aufs
1453+creates a hardlink under the Pseudo-link Directory of the writable
1454+branch. The inode of a pseudo-link is kept in aufs super_block as a
1455+simple list. If fileB is read after unlinking fileA, aufs returns
1456+filedata from the pseudo-link instead of the lower readonly
1457+branch. Because the pseudo-link is based upon the inode, to keep the
7e9cd9fe 1458+inode number by xino (see above) is essentially necessary.
53392da6
AM
1459+
1460+All the hardlinks under the Pseudo-link Directory of the writable branch
1461+should be restored in a proper location later. Aufs provides a utility
1462+to do this. The userspace helpers executed at remounting and unmounting
1463+aufs by default.
1464+During this utility is running, it puts aufs into the pseudo-link
1465+maintenance mode. In this mode, only the process which began the
1466+maintenance mode (and its child processes) is allowed to operate in
1467+aufs. Some other processes which are not related to the pseudo-link will
1468+be allowed to run too, but the rest have to return an error or wait
1469+until the maintenance mode ends. If a process already acquires an inode
1470+mutex (in VFS), it has to return an error.
1471+
1472+
1473+XIB(external inode number bitmap)
1474+----------------------------------------------------------------------
1475+Addition to the xino file per a branch, aufs has an external inode number
7e9cd9fe
AM
1476+bitmap in a superblock object. It is also an internal file such like a
1477+xino file.
53392da6
AM
1478+It is a simple bitmap to mark whether the aufs inode number is in-use or
1479+not.
1480+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1481+
7e9cd9fe 1482+As well as XINO files, aufs has a feature to truncate/refresh XIB to
53392da6
AM
1483+reduce the number of consumed disk blocks for these files.
1484+
1485+
1486+Virtual or Vertical Dir, and Readdir in Userspace
1487+----------------------------------------------------------------------
1488+In order to support multiple layers (branches), aufs readdir operation
1489+constructs a virtual dir block on memory. For readdir, aufs calls
1490+vfs_readdir() internally for each dir on branches, merges their entries
1491+with eliminating the whiteout-ed ones, and sets it to file (dir)
1492+object. So the file object has its entry list until it is closed. The
1493+entry list will be updated when the file position is zero and becomes
7e9cd9fe 1494+obsoleted. This decision is made in aufs automatically.
53392da6
AM
1495+
1496+The dynamically allocated memory block for the name of entries has a
1497+unit of 512 bytes (by default) and stores the names contiguously (no
1498+padding). Another block for each entry is handled by kmem_cache too.
1499+During building dir blocks, aufs creates hash list and judging whether
1500+the entry is whiteouted by its upper branch or already listed.
1501+The merged result is cached in the corresponding inode object and
1502+maintained by a customizable life-time option.
1503+
1504+Some people may call it can be a security hole or invite DoS attack
1505+since the opened and once readdir-ed dir (file object) holds its entry
1506+list and becomes a pressure for system memory. But I'd say it is similar
1507+to files under /proc or /sys. The virtual files in them also holds a
1508+memory page (generally) while they are opened. When an idea to reduce
1509+memory for them is introduced, it will be applied to aufs too.
1510+For those who really hate this situation, I've developed readdir(3)
1511+library which operates this merging in userspace. You just need to set
1512+LD_PRELOAD environment variable, and aufs will not consume no memory in
1513+kernel space for readdir(3).
1514+
1515+
1516+Workqueue
1517+----------------------------------------------------------------------
1518+Aufs sometimes requires privilege access to a branch. For instance,
1519+in copy-up/down operation. When a user process is going to make changes
1520+to a file which exists in the lower readonly branch only, and the mode
1521+of one of ancestor directories may not be writable by a user
1522+process. Here aufs copy-up the file with its ancestors and they may
1523+require privilege to set its owner/group/mode/etc.
1524+This is a typical case of a application character of aufs (see
1525+Introduction).
1526+
1527+Aufs uses workqueue synchronously for this case. It creates its own
1528+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1529+passes the request to call mkdir or write (for example), and wait for
1530+its completion. This approach solves a problem of a signal handler
1531+simply.
1532+If aufs didn't adopt the workqueue and changed the privilege of the
7e9cd9fe
AM
1533+process, then the process may receive the unexpected SIGXFSZ or other
1534+signals.
53392da6
AM
1535+
1536+Also aufs uses the system global workqueue ("events" kernel thread) too
1537+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1538+whiteout base and etc. This is unrelated to a privilege.
1539+Most of aufs operation tries acquiring a rw_semaphore for aufs
1540+superblock at the beginning, at the same time waits for the completion
1541+of all queued asynchronous tasks.
1542+
1543+
1544+Whiteout
1545+----------------------------------------------------------------------
1546+The whiteout in aufs is very similar to Unionfs's. That is represented
1547+by its filename. UnionMount takes an approach of a file mode, but I am
1548+afraid several utilities (find(1) or something) will have to support it.
1549+
1550+Basically the whiteout represents "logical deletion" which stops aufs to
1551+lookup further, but also it represents "dir is opaque" which also stop
7e9cd9fe 1552+further lookup.
53392da6
AM
1553+
1554+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1555+In order to make several functions in a single systemcall to be
1556+revertible, aufs adopts an approach to rename a directory to a temporary
1557+unique whiteouted name.
1558+For example, in rename(2) dir where the target dir already existed, aufs
1559+renames the target dir to a temporary unique whiteouted name before the
7e9cd9fe 1560+actual rename on a branch, and then handles other actions (make it opaque,
53392da6
AM
1561+update the attributes, etc). If an error happens in these actions, aufs
1562+simply renames the whiteouted name back and returns an error. If all are
1563+succeeded, aufs registers a function to remove the whiteouted unique
1564+temporary name completely and asynchronously to the system global
1565+workqueue.
1566+
1567+
1568+Copy-up
1569+----------------------------------------------------------------------
1570+It is a well-known feature or concept.
1571+When user modifies a file on a readonly branch, aufs operate "copy-up"
1572+internally and makes change to the new file on the upper writable branch.
1573+When the trigger systemcall does not update the timestamps of the parent
1574+dir, aufs reverts it after copy-up.
c2b27bf2
AM
1575+
1576+
1577+Move-down (aufs3.9 and later)
1578+----------------------------------------------------------------------
1579+"Copy-up" is one of the essential feature in aufs. It copies a file from
1580+the lower readonly branch to the upper writable branch when a user
1581+changes something about the file.
1582+"Move-down" is an opposite action of copy-up. Basically this action is
1583+ran manually instead of automatically and internally.
076b876e
AM
1584+For desgin and implementation, aufs has to consider these issues.
1585+- whiteout for the file may exist on the lower branch.
1586+- ancestor directories may not exist on the lower branch.
1587+- diropq for the ancestor directories may exist on the upper branch.
1588+- free space on the lower branch will reduce.
1589+- another access to the file may happen during moving-down, including
7e9cd9fe 1590+ UDBA (see "Revalidate Dentry and UDBA").
076b876e
AM
1591+- the file should not be hard-linked nor pseudo-linked. they should be
1592+ handled by auplink utility later.
c2b27bf2
AM
1593+
1594+Sometimes users want to move-down a file from the upper writable branch
1595+to the lower readonly or writable branch. For instance,
1596+- the free space of the upper writable branch is going to run out.
1597+- create a new intermediate branch between the upper and lower branch.
1598+- etc.
1599+
1600+For this purpose, use "aumvdown" command in aufs-util.git.
b912730e
AM
1601diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt linux/Documentation/filesystems/aufs/design/03atomic_open.txt
1602--- /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 1603+++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2017-07-29 12:14:25.893041746 +0200
b912730e
AM
1604@@ -0,0 +1,85 @@
1605+
a2654f78 1606+# Copyright (C) 2015-2017 Junjiro R. Okajima
b912730e
AM
1607+#
1608+# This program is free software; you can redistribute it and/or modify
1609+# it under the terms of the GNU General Public License as published by
1610+# the Free Software Foundation; either version 2 of the License, or
1611+# (at your option) any later version.
1612+#
1613+# This program is distributed in the hope that it will be useful,
1614+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1615+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1616+# GNU General Public License for more details.
1617+#
1618+# You should have received a copy of the GNU General Public License
1619+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1620+
1621+Support for a branch who has its ->atomic_open()
1622+----------------------------------------------------------------------
1623+The filesystems who implement its ->atomic_open() are not majority. For
1624+example NFSv4 does, and aufs should call NFSv4 ->atomic_open,
1625+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than
1626+->atomic_open(), NFSv4 returns an error for this open(2). While I am not
1627+sure whether all filesystems who have ->atomic_open() behave like this,
1628+but NFSv4 surely returns the error.
1629+
1630+In order to support ->atomic_open() for aufs, there are a few
1631+approaches.
1632+
1633+A. Introduce aufs_atomic_open()
1634+ - calls one of VFS:do_last(), lookup_open() or atomic_open() for
1635+ branch fs.
1636+B. Introduce aufs_atomic_open() calling create, open and chmod. this is
1637+ an aufs user Pip Cet's approach
1638+ - calls aufs_create(), VFS finish_open() and notify_change().
1639+ - pass fake-mode to finish_open(), and then correct the mode by
1640+ notify_change().
1641+C. Extend aufs_open() to call branch fs's ->atomic_open()
1642+ - no aufs_atomic_open().
1643+ - aufs_lookup() registers the TID to an aufs internal object.
1644+ - aufs_create() does nothing when the matching TID is registered, but
1645+ registers the mode.
1646+ - aufs_open() calls branch fs's ->atomic_open() when the matching
1647+ TID is registered.
1648+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's
1649+ credential
1650+ - no aufs_atomic_open().
1651+ - aufs_create() registers the TID to an internal object. this info
1652+ represents "this process created this file just now."
1653+ - when aufs gets EACCES from branch fs's ->open(), then confirm the
1654+ registered TID and re-try open() with superuser's credential.
1655+
1656+Pros and cons for each approach.
1657+
1658+A.
1659+ - straightforward but highly depends upon VFS internal.
1660+ - the atomic behavaiour is kept.
1661+ - some of parameters such as nameidata are hard to reproduce for
1662+ branch fs.
1663+ - large overhead.
1664+B.
1665+ - easy to implement.
1666+ - the atomic behavaiour is lost.
1667+C.
1668+ - the atomic behavaiour is kept.
1669+ - dirty and tricky.
1670+ - VFS checks whether the file is created correctly after calling
1671+ ->create(), which means this approach doesn't work.
1672+D.
1673+ - easy to implement.
1674+ - the atomic behavaiour is lost.
1675+ - to open a file with superuser's credential and give it to a user
1676+ process is a bad idea, since the file object keeps the credential
1677+ in it. It may affect LSM or something. This approach doesn't work
1678+ either.
1679+
1680+The approach A is ideal, but it hard to implement. So here is a
1681+variation of A, which is to be implemented.
1682+
1683+A-1. Introduce aufs_atomic_open()
1684+ - calls branch fs ->atomic_open() if exists. otherwise calls
1685+ vfs_create() and finish_open().
1686+ - the demerit is that the several checks after branch fs
1687+ ->atomic_open() are lost. in the ordinary case, the checks are
1688+ done by VFS:do_last(), lookup_open() and atomic_open(). some can
1689+ be implemented in aufs, but not all I am afraid.
53392da6
AM
1690diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1691--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 1692+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2017-07-29 12:14:25.893041746 +0200
7e9cd9fe 1693@@ -0,0 +1,113 @@
53392da6 1694+
a2654f78 1695+# Copyright (C) 2005-2017 Junjiro R. Okajima
53392da6
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
523b37e3 1708+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1709+
1710+Lookup in a Branch
1711+----------------------------------------------------------------------
1712+Since aufs has a character of sub-VFS (see Introduction), it operates
7e9cd9fe
AM
1713+lookup for branches as VFS does. It may be a heavy work. But almost all
1714+lookup operation in aufs is the simplest case, ie. lookup only an entry
1715+directly connected to its parent. Digging down the directory hierarchy
1716+is unnecessary. VFS has a function lookup_one_len() for that use, and
1717+aufs calls it.
1718+
1719+When a branch is a remote filesystem, aufs basically relies upon its
53392da6
AM
1720+->d_revalidate(), also aufs forces the hardest revalidate tests for
1721+them.
1722+For d_revalidate, aufs implements three levels of revalidate tests. See
1723+"Revalidate Dentry and UDBA" in detail.
1724+
1725+
076b876e
AM
1726+Test Only the Highest One for the Directory Permission (dirperm1 option)
1727+----------------------------------------------------------------------
1728+Let's try case study.
1729+- aufs has two branches, upper readwrite and lower readonly.
1730+ /au = /rw + /ro
1731+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1732+- user invoked "chmod a+rx /au/dirA"
1733+- the internal copy-up is activated and "/rw/dirA" is created and its
7e9cd9fe 1734+ permission bits are set to world readable.
076b876e
AM
1735+- then "/au/dirA" becomes world readable?
1736+
1737+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1738+or it may be a natively readonly filesystem. If aufs respects the lower
1739+branch, it should not respond readdir request from other users. But user
1740+allowed it by chmod. Should really aufs rejects showing the entries
1741+under /ro/dirA?
1742+
7e9cd9fe
AM
1743+To be honest, I don't have a good solution for this case. So aufs
1744+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to
1745+users.
076b876e
AM
1746+When dirperm1 is specified, aufs checks only the highest one for the
1747+directory permission, and shows the entries. Otherwise, as usual, checks
1748+every dir existing on all branches and rejects the request.
1749+
1750+As a side effect, dirperm1 option improves the performance of aufs
1751+because the number of permission check is reduced when the number of
1752+branch is many.
1753+
1754+
53392da6
AM
1755+Revalidate Dentry and UDBA (User's Direct Branch Access)
1756+----------------------------------------------------------------------
1757+Generally VFS helpers re-validate a dentry as a part of lookup.
1758+0. digging down the directory hierarchy.
1759+1. lock the parent dir by its i_mutex.
1760+2. lookup the final (child) entry.
1761+3. revalidate it.
1762+4. call the actual operation (create, unlink, etc.)
1763+5. unlock the parent dir
1764+
1765+If the filesystem implements its ->d_revalidate() (step 3), then it is
1766+called. Actually aufs implements it and checks the dentry on a branch is
1767+still valid.
1768+But it is not enough. Because aufs has to release the lock for the
1769+parent dir on a branch at the end of ->lookup() (step 2) and
1770+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1771+held by VFS.
1772+If the file on a branch is changed directly, eg. bypassing aufs, after
1773+aufs released the lock, then the subsequent operation may cause
1774+something unpleasant result.
1775+
1776+This situation is a result of VFS architecture, ->lookup() and
1777+->d_revalidate() is separated. But I never say it is wrong. It is a good
1778+design from VFS's point of view. It is just not suitable for sub-VFS
1779+character in aufs.
1780+
1781+Aufs supports such case by three level of revalidation which is
1782+selectable by user.
1783+1. Simple Revalidate
1784+ Addition to the native flow in VFS's, confirm the child-parent
1785+ relationship on the branch just after locking the parent dir on the
1786+ branch in the "actual operation" (step 4). When this validation
1787+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1788+ checks the validation of the dentry on branches.
1789+2. Monitor Changes Internally by Inotify/Fsnotify
1790+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1791+ the dentry on the branch, and returns EBUSY if it finds different
1792+ dentry.
1793+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1794+ during it is in cache. When the event is notified, aufs registers a
1795+ function to kernel 'events' thread by schedule_work(). And the
1796+ function sets some special status to the cached aufs dentry and inode
1797+ private data. If they are not cached, then aufs has nothing to
1798+ do. When the same file is accessed through aufs (step 0-3) later,
1799+ aufs will detect the status and refresh all necessary data.
1800+ In this mode, aufs has to ignore the event which is fired by aufs
1801+ itself.
1802+3. No Extra Validation
1803+ This is the simplest test and doesn't add any additional revalidation
7e9cd9fe 1804+ test, and skip the revalidation in step 4. It is useful and improves
53392da6
AM
1805+ aufs performance when system surely hide the aufs branches from user,
1806+ by over-mounting something (or another method).
1807diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1808--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 1809+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2017-07-29 12:14:25.893041746 +0200
7e9cd9fe 1810@@ -0,0 +1,74 @@
53392da6 1811+
a2654f78 1812+# Copyright (C) 2005-2017 Junjiro R. Okajima
53392da6
AM
1813+#
1814+# This program is free software; you can redistribute it and/or modify
1815+# it under the terms of the GNU General Public License as published by
1816+# the Free Software Foundation; either version 2 of the License, or
1817+# (at your option) any later version.
1818+#
1819+# This program is distributed in the hope that it will be useful,
1820+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1821+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1822+# GNU General Public License for more details.
1823+#
1824+# You should have received a copy of the GNU General Public License
523b37e3 1825+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1826+
1827+Branch Manipulation
1828+
1829+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1830+and changing its permission/attribute, there are a lot of works to do.
1831+
1832+
1833+Add a Branch
1834+----------------------------------------------------------------------
1835+o Confirm the adding dir exists outside of aufs, including loopback
7e9cd9fe 1836+ mount, and its various attributes.
53392da6
AM
1837+o Initialize the xino file and whiteout bases if necessary.
1838+ See struct.txt.
1839+
1840+o Check the owner/group/mode of the directory
1841+ When the owner/group/mode of the adding directory differs from the
1842+ existing branch, aufs issues a warning because it may impose a
1843+ security risk.
1844+ For example, when a upper writable branch has a world writable empty
1845+ top directory, a malicious user can create any files on the writable
1846+ branch directly, like copy-up and modify manually. If something like
1847+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1848+ writable branch, and the writable branch is world-writable, then a
1849+ malicious guy may create /etc/passwd on the writable branch directly
1850+ and the infected file will be valid in aufs.
7e9cd9fe 1851+ I am afraid it can be a security issue, but aufs can do nothing except
53392da6
AM
1852+ producing a warning.
1853+
1854+
1855+Delete a Branch
1856+----------------------------------------------------------------------
1857+o Confirm the deleting branch is not busy
1858+ To be general, there is one merit to adopt "remount" interface to
1859+ manipulate branches. It is to discard caches. At deleting a branch,
1860+ aufs checks the still cached (and connected) dentries and inodes. If
1861+ there are any, then they are all in-use. An inode without its
1862+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1863+
1864+ For the cached one, aufs checks whether the same named entry exists on
1865+ other branches.
1866+ If the cached one is a directory, because aufs provides a merged view
1867+ to users, as long as one dir is left on any branch aufs can show the
1868+ dir to users. In this case, the branch can be removed from aufs.
1869+ Otherwise aufs rejects deleting the branch.
1870+
1871+ If any file on the deleting branch is opened by aufs, then aufs
1872+ rejects deleting.
1873+
1874+
1875+Modify the Permission of a Branch
1876+----------------------------------------------------------------------
1877+o Re-initialize or remove the xino file and whiteout bases if necessary.
1878+ See struct.txt.
1879+
1880+o rw --> ro: Confirm the modifying branch is not busy
1881+ Aufs rejects the request if any of these conditions are true.
1882+ - a file on the branch is mmap-ed.
1883+ - a regular file on the branch is opened for write and there is no
1884+ same named entry on the upper branch.
1885diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1886--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 1887+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2017-07-29 12:14:25.893041746 +0200
523b37e3 1888@@ -0,0 +1,64 @@
53392da6 1889+
a2654f78 1890+# Copyright (C) 2005-2017 Junjiro R. Okajima
53392da6
AM
1891+#
1892+# This program is free software; you can redistribute it and/or modify
1893+# it under the terms of the GNU General Public License as published by
1894+# the Free Software Foundation; either version 2 of the License, or
1895+# (at your option) any later version.
1896+#
1897+# This program is distributed in the hope that it will be useful,
1898+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1899+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1900+# GNU General Public License for more details.
1901+#
1902+# You should have received a copy of the GNU General Public License
523b37e3 1903+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1904+
1905+Policies to Select One among Multiple Writable Branches
1906+----------------------------------------------------------------------
1907+When the number of writable branch is more than one, aufs has to decide
1908+the target branch for file creation or copy-up. By default, the highest
1909+writable branch which has the parent (or ancestor) dir of the target
1910+file is chosen (top-down-parent policy).
1911+By user's request, aufs implements some other policies to select the
7e9cd9fe
AM
1912+writable branch, for file creation several policies, round-robin,
1913+most-free-space, and other policies. For copy-up, top-down-parent,
1914+bottom-up-parent, bottom-up and others.
53392da6
AM
1915+
1916+As expected, the round-robin policy selects the branch in circular. When
1917+you have two writable branches and creates 10 new files, 5 files will be
1918+created for each branch. mkdir(2) systemcall is an exception. When you
1919+create 10 new directories, all will be created on the same branch.
1920+And the most-free-space policy selects the one which has most free
1921+space among the writable branches. The amount of free space will be
1922+checked by aufs internally, and users can specify its time interval.
1923+
1924+The policies for copy-up is more simple,
1925+top-down-parent is equivalent to the same named on in create policy,
1926+bottom-up-parent selects the writable branch where the parent dir
1927+exists and the nearest upper one from the copyup-source,
1928+bottom-up selects the nearest upper writable branch from the
1929+copyup-source, regardless the existence of the parent dir.
1930+
1931+There are some rules or exceptions to apply these policies.
1932+- If there is a readonly branch above the policy-selected branch and
1933+ the parent dir is marked as opaque (a variation of whiteout), or the
1934+ target (creating) file is whiteout-ed on the upper readonly branch,
1935+ then the result of the policy is ignored and the target file will be
1936+ created on the nearest upper writable branch than the readonly branch.
1937+- If there is a writable branch above the policy-selected branch and
1938+ the parent dir is marked as opaque or the target file is whiteouted
1939+ on the branch, then the result of the policy is ignored and the target
1940+ file will be created on the highest one among the upper writable
1941+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1942+ it as usual.
1943+- link(2) and rename(2) systemcalls are exceptions in every policy.
1944+ They try selecting the branch where the source exists as possible
1945+ since copyup a large file will take long time. If it can't be,
1946+ ie. the branch where the source exists is readonly, then they will
1947+ follow the copyup policy.
1948+- There is an exception for rename(2) when the target exists.
1949+ If the rename target exists, aufs compares the index of the branches
1950+ where the source and the target exists and selects the higher
1951+ one. If the selected branch is readonly, then aufs follows the
1952+ copyup policy.
076b876e
AM
1953diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
1954--- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 1955+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2017-07-29 12:14:25.896375188 +0200
076b876e
AM
1956@@ -0,0 +1,120 @@
1957+
a2654f78 1958+# Copyright (C) 2011-2017 Junjiro R. Okajima
076b876e
AM
1959+#
1960+# This program is free software; you can redistribute it and/or modify
1961+# it under the terms of the GNU General Public License as published by
1962+# the Free Software Foundation; either version 2 of the License, or
1963+# (at your option) any later version.
1964+#
1965+# This program is distributed in the hope that it will be useful,
1966+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1967+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1968+# GNU General Public License for more details.
1969+#
1970+# You should have received a copy of the GNU General Public License
1971+# along with this program; if not, write to the Free Software
1972+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1973+
1974+
1975+File-based Hierarchical Storage Management (FHSM)
1976+----------------------------------------------------------------------
1977+Hierarchical Storage Management (or HSM) is a well-known feature in the
1978+storage world. Aufs provides this feature as file-based with multiple
7e9cd9fe 1979+writable branches, based upon the principle of "Colder, the Lower".
076b876e 1980+Here the word "colder" means that the less used files, and "lower" means
7e9cd9fe 1981+that the position in the order of the stacked branches vertically.
076b876e
AM
1982+These multiple writable branches are prioritized, ie. the topmost one
1983+should be the fastest drive and be used heavily.
1984+
1985+o Characters in aufs FHSM story
1986+- aufs itself and a new branch attribute.
1987+- a new ioctl interface to move-down and to establish a connection with
1988+ the daemon ("move-down" is a converse of "copy-up").
1989+- userspace tool and daemon.
1990+
1991+The userspace daemon establishes a connection with aufs and waits for
1992+the notification. The notified information is very similar to struct
1993+statfs containing the number of consumed blocks and inodes.
1994+When the consumed blocks/inodes of a branch exceeds the user-specified
1995+upper watermark, the daemon activates its move-down process until the
1996+consumed blocks/inodes reaches the user-specified lower watermark.
1997+
1998+The actual move-down is done by aufs based upon the request from
1999+user-space since we need to maintain the inode number and the internal
2000+pointer arrays in aufs.
2001+
2002+Currently aufs FHSM handles the regular files only. Additionally they
2003+must not be hard-linked nor pseudo-linked.
2004+
2005+
2006+o Cowork of aufs and the user-space daemon
2007+ During the userspace daemon established the connection, aufs sends a
2008+ small notification to it whenever aufs writes something into the
2009+ writable branch. But it may cost high since aufs issues statfs(2)
2010+ internally. So user can specify a new option to cache the
2011+ info. Actually the notification is controlled by these factors.
2012+ + the specified cache time.
2013+ + classified as "force" by aufs internally.
2014+ Until the specified time expires, aufs doesn't send the info
2015+ except the forced cases. When aufs decide forcing, the info is always
2016+ notified to userspace.
2017+ For example, the number of free inodes is generally large enough and
2018+ the shortage of it happens rarely. So aufs doesn't force the
2019+ notification when creating a new file, directory and others. This is
2020+ the typical case which aufs doesn't force.
2021+ When aufs writes the actual filedata and the files consumes any of new
2022+ blocks, the aufs forces notifying.
2023+
2024+
2025+o Interfaces in aufs
2026+- New branch attribute.
2027+ + fhsm
2028+ Specifies that the branch is managed by FHSM feature. In other word,
2029+ participant in the FHSM.
2030+ When nofhsm is set to the branch, it will not be the source/target
2031+ branch of the move-down operation. This attribute is set
2032+ independently from coo and moo attributes, and if you want full
2033+ FHSM, you should specify them as well.
2034+- New mount option.
2035+ + fhsm_sec
2036+ Specifies a second to suppress many less important info to be
2037+ notified.
2038+- New ioctl.
2039+ + AUFS_CTL_FHSM_FD
2040+ create a new file descriptor which userspace can read the notification
2041+ (a subset of struct statfs) from aufs.
2042+- Module parameter 'brs'
2043+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not
2044+ be set.
2045+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
2046+ When there are two or more branches with fhsm attributes,
2047+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
2048+ terminates it. As a result of remounting and branch-manipulation, the
2049+ number of branches with fhsm attribute can be one. In this case,
2050+ /sbin/mount.aufs will terminate the user-space daemon.
2051+
2052+
2053+Finally the operation is done as these steps in kernel-space.
2054+- make sure that,
2055+ + no one else is using the file.
2056+ + the file is not hard-linked.
2057+ + the file is not pseudo-linked.
2058+ + the file is a regular file.
2059+ + the parent dir is not opaqued.
2060+- find the target writable branch.
2061+- make sure the file is not whiteout-ed by the upper (than the target)
2062+ branch.
2063+- make the parent dir on the target branch.
2064+- mutex lock the inode on the branch.
2065+- unlink the whiteout on the target branch (if exists).
2066+- lookup and create the whiteout-ed temporary name on the target branch.
2067+- copy the file as the whiteout-ed temporary name on the target branch.
2068+- rename the whiteout-ed temporary name to the original name.
2069+- unlink the file on the source branch.
2070+- maintain the internal pointer array and the external inode number
2071+ table (XINO).
2072+- maintain the timestamps and other attributes of the parent dir and the
2073+ file.
2074+
2075+And of course, in every step, an error may happen. So the operation
2076+should restore the original file state after an error happens.
53392da6
AM
2077diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
2078--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 2079+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2017-07-29 12:14:25.896375188 +0200
b912730e 2080@@ -0,0 +1,72 @@
53392da6 2081+
a2654f78 2082+# Copyright (C) 2005-2017 Junjiro R. Okajima
53392da6
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
523b37e3 2095+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2096+
2097+mmap(2) -- File Memory Mapping
2098+----------------------------------------------------------------------
2099+In aufs, the file-mapped pages are handled by a branch fs directly, no
2100+interaction with aufs. It means aufs_mmap() calls the branch fs's
2101+->mmap().
2102+This approach is simple and good, but there is one problem.
7e9cd9fe 2103+Under /proc, several entries show the mmapped files by its path (with
53392da6
AM
2104+device and inode number), and the printed path will be the path on the
2105+branch fs's instead of virtual aufs's.
2106+This is not a problem in most cases, but some utilities lsof(1) (and its
2107+user) may expect the path on aufs.
2108+
2109+To address this issue, aufs adds a new member called vm_prfile in struct
2110+vm_area_struct (and struct vm_region). The original vm_file points to
2111+the file on the branch fs in order to handle everything correctly as
2112+usual. The new vm_prfile points to a virtual file in aufs, and the
2113+show-functions in procfs refers to vm_prfile if it is set.
2114+Also we need to maintain several other places where touching vm_file
2115+such like
2116+- fork()/clone() copies vma and the reference count of vm_file is
2117+ incremented.
2118+- merging vma maintains the ref count too.
2119+
7e9cd9fe 2120+This is not a good approach. It just fakes the printed path. But it
53392da6
AM
2121+leaves all behaviour around f_mapping unchanged. This is surely an
2122+advantage.
2123+Actually aufs had adopted another complicated approach which calls
2124+generic_file_mmap() and handles struct vm_operations_struct. In this
2125+approach, aufs met a hard problem and I could not solve it without
2126+switching the approach.
b912730e
AM
2127+
2128+There may be one more another approach which is
2129+- bind-mount the branch-root onto the aufs-root internally
2130+- grab the new vfsmount (ie. struct mount)
2131+- lazy-umount the branch-root internally
2132+- in open(2) the aufs-file, open the branch-file with the hidden
2133+ vfsmount (instead of the original branch's vfsmount)
2134+- ideally this "bind-mount and lazy-umount" should be done atomically,
2135+ but it may be possible from userspace by the mount helper.
2136+
2137+Adding the internal hidden vfsmount and using it in opening a file, the
2138+file path under /proc will be printed correctly. This approach looks
2139+smarter, but is not possible I am afraid.
2140+- aufs-root may be bind-mount later. when it happens, another hidden
2141+ vfsmount will be required.
2142+- it is hard to get the chance to bind-mount and lazy-umount
2143+ + in kernel-space, FS can have vfsmount in open(2) via
2144+ file->f_path, and aufs can know its vfsmount. But several locks are
2145+ already acquired, and if aufs tries to bind-mount and lazy-umount
2146+ here, then it may cause a deadlock.
2147+ + in user-space, bind-mount doesn't invoke the mount helper.
2148+- since /proc shows dev and ino, aufs has to give vma these info. it
2149+ means a new member vm_prinode will be necessary. this is essentially
2150+ equivalent to vm_prfile described above.
2151+
2152+I have to give up this "looks-smater" approach.
c1595e42
JR
2153diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
2154--- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 2155+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2017-07-29 12:14:25.896375188 +0200
c1595e42
JR
2156@@ -0,0 +1,96 @@
2157+
a2654f78 2158+# Copyright (C) 2014-2017 Junjiro R. Okajima
c1595e42
JR
2159+#
2160+# This program is free software; you can redistribute it and/or modify
2161+# it under the terms of the GNU General Public License as published by
2162+# the Free Software Foundation; either version 2 of the License, or
2163+# (at your option) any later version.
2164+#
2165+# This program is distributed in the hope that it will be useful,
2166+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2167+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2168+# GNU General Public License for more details.
2169+#
2170+# You should have received a copy of the GNU General Public License
2171+# along with this program; if not, write to the Free Software
2172+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2173+
2174+
2175+Listing XATTR/EA and getting the value
2176+----------------------------------------------------------------------
2177+For the inode standard attributes (owner, group, timestamps, etc.), aufs
2178+shows the values from the topmost existing file. This behaviour is good
7e9cd9fe 2179+for the non-dir entries since the bahaviour exactly matches the shown
c1595e42
JR
2180+information. But for the directories, aufs considers all the same named
2181+entries on the lower branches. Which means, if one of the lower entry
2182+rejects readdir call, then aufs returns an error even if the topmost
2183+entry allows it. This behaviour is necessary to respect the branch fs's
2184+security, but can make users confused since the user-visible standard
2185+attributes don't match the behaviour.
2186+To address this issue, aufs has a mount option called dirperm1 which
2187+checks the permission for the topmost entry only, and ignores the lower
2188+entry's permission.
2189+
2190+A similar issue can happen around XATTR.
2191+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
7e9cd9fe
AM
2192+always set. Otherwise these very unpleasant situation would happen.
2193+- listxattr(2) may return the duplicated entries.
c1595e42
JR
2194+- users may not be able to remove or reset the XATTR forever,
2195+
2196+
2197+XATTR/EA support in the internal (copy,move)-(up,down)
2198+----------------------------------------------------------------------
7e9cd9fe 2199+Generally the extended attributes of inode are categorized as these.
c1595e42
JR
2200+- "security" for LSM and capability.
2201+- "system" for posix ACL, 'acl' mount option is required for the branch
2202+ fs generally.
2203+- "trusted" for userspace, CAP_SYS_ADMIN is required.
2204+- "user" for userspace, 'user_xattr' mount option is required for the
2205+ branch fs generally.
2206+
2207+Moreover there are some other categories. Aufs handles these rather
2208+unpopular categories as the ordinary ones, ie. there is no special
2209+condition nor exception.
2210+
2211+In copy-up, the support for XATTR on the dst branch may differ from the
2212+src branch. In this case, the copy-up operation will get an error and
7e9cd9fe
AM
2213+the original user operation which triggered the copy-up will fail. It
2214+can happen that even all copy-up will fail.
c1595e42
JR
2215+When both of src and dst branches support XATTR and if an error occurs
2216+during copying XATTR, then the copy-up should fail obviously. That is a
2217+good reason and aufs should return an error to userspace. But when only
7e9cd9fe 2218+the src branch support that XATTR, aufs should not return an error.
c1595e42
JR
2219+For example, the src branch supports ACL but the dst branch doesn't
2220+because the dst branch may natively un-support it or temporary
2221+un-support it due to "noacl" mount option. Of course, the dst branch fs
2222+may NOT return an error even if the XATTR is not supported. It is
2223+totally up to the branch fs.
2224+
2225+Anyway when the aufs internal copy-up gets an error from the dst branch
2226+fs, then aufs tries removing the just copied entry and returns the error
2227+to the userspace. The worst case of this situation will be all copy-up
2228+will fail.
2229+
2230+For the copy-up operation, there two basic approaches.
2231+- copy the specified XATTR only (by category above), and return the
7e9cd9fe 2232+ error unconditionally if it happens.
c1595e42
JR
2233+- copy all XATTR, and ignore the error on the specified category only.
2234+
2235+In order to support XATTR and to implement the correct behaviour, aufs
7e9cd9fe
AM
2236+chooses the latter approach and introduces some new branch attributes,
2237+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
c1595e42 2238+They correspond to the XATTR namespaces (see above). Additionally, to be
7e9cd9fe
AM
2239+convenient, "icex" is also provided which means all "icex*" attributes
2240+are set (here the word "icex" stands for "ignore copy-error on XATTR").
c1595e42
JR
2241+
2242+The meaning of these attributes is to ignore the error from setting
2243+XATTR on that branch.
2244+Note that aufs tries copying all XATTR unconditionally, and ignores the
2245+error from the dst branch according to the specified attributes.
2246+
2247+Some XATTR may have its default value. The default value may come from
2248+the parent dir or the environment. If the default value is set at the
2249+file creating-time, it will be overwritten by copy-up.
2250+Some contradiction may happen I am afraid.
2251+Do we need another attribute to stop copying XATTR? I am unsure. For
2252+now, aufs implements the branch attributes to ignore the error.
53392da6
AM
2253diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
2254--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 2255+++ linux/Documentation/filesystems/aufs/design/07export.txt 2017-07-29 12:14:25.896375188 +0200
523b37e3 2256@@ -0,0 +1,58 @@
53392da6 2257+
a2654f78 2258+# Copyright (C) 2005-2017 Junjiro R. Okajima
53392da6
AM
2259+#
2260+# This program is free software; you can redistribute it and/or modify
2261+# it under the terms of the GNU General Public License as published by
2262+# the Free Software Foundation; either version 2 of the License, or
2263+# (at your option) any later version.
2264+#
2265+# This program is distributed in the hope that it will be useful,
2266+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2267+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2268+# GNU General Public License for more details.
2269+#
2270+# You should have received a copy of the GNU General Public License
523b37e3 2271+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2272+
2273+Export Aufs via NFS
2274+----------------------------------------------------------------------
2275+Here is an approach.
2276+- like xino/xib, add a new file 'xigen' which stores aufs inode
2277+ generation.
2278+- iget_locked(): initialize aufs inode generation for a new inode, and
2279+ store it in xigen file.
2280+- destroy_inode(): increment aufs inode generation and store it in xigen
2281+ file. it is necessary even if it is not unlinked, because any data of
2282+ inode may be changed by UDBA.
2283+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
2284+ build file handle by
2285+ + branch id (4 bytes)
2286+ + superblock generation (4 bytes)
2287+ + inode number (4 or 8 bytes)
2288+ + parent dir inode number (4 or 8 bytes)
2289+ + inode generation (4 bytes))
2290+ + return value of exportfs_encode_fh() for the parent on a branch (4
2291+ bytes)
2292+ + file handle for a branch (by exportfs_encode_fh())
2293+- fh_to_dentry():
2294+ + find the index of a branch from its id in handle, and check it is
2295+ still exist in aufs.
2296+ + 1st level: get the inode number from handle and search it in cache.
7e9cd9fe
AM
2297+ + 2nd level: if not found in cache, get the parent inode number from
2298+ the handle and search it in cache. and then open the found parent
2299+ dir, find the matching inode number by vfs_readdir() and get its
2300+ name, and call lookup_one_len() for the target dentry.
53392da6
AM
2301+ + 3rd level: if the parent dir is not cached, call
2302+ exportfs_decode_fh() for a branch and get the parent on a branch,
2303+ build a pathname of it, convert it a pathname in aufs, call
2304+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
2305+ the 2nd level.
2306+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
2307+ for every branch, but not itself. to get this, (currently) aufs
2308+ searches in current->nsproxy->mnt_ns list. it may not be a good
2309+ idea, but I didn't get other approach.
2310+ + test the generation of the gotten inode.
2311+- every inode operation: they may get EBUSY due to UDBA. in this case,
2312+ convert it into ESTALE for NFSD.
2313+- readdir(): call lockdep_on/off() because filldir in NFSD calls
2314+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
2315diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
2316--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 2317+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2017-07-29 12:14:25.896375188 +0200
523b37e3 2318@@ -0,0 +1,52 @@
53392da6 2319+
a2654f78 2320+# Copyright (C) 2005-2017 Junjiro R. Okajima
53392da6
AM
2321+#
2322+# This program is free software; you can redistribute it and/or modify
2323+# it under the terms of the GNU General Public License as published by
2324+# the Free Software Foundation; either version 2 of the License, or
2325+# (at your option) any later version.
2326+#
2327+# This program is distributed in the hope that it will be useful,
2328+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2329+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2330+# GNU General Public License for more details.
2331+#
2332+# You should have received a copy of the GNU General Public License
523b37e3 2333+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2334+
2335+Show Whiteout Mode (shwh)
2336+----------------------------------------------------------------------
2337+Generally aufs hides the name of whiteouts. But in some cases, to show
2338+them is very useful for users. For instance, creating a new middle layer
2339+(branch) by merging existing layers.
2340+
2341+(borrowing aufs1 HOW-TO from a user, Michael Towers)
2342+When you have three branches,
2343+- Bottom: 'system', squashfs (underlying base system), read-only
2344+- Middle: 'mods', squashfs, read-only
2345+- Top: 'overlay', ram (tmpfs), read-write
2346+
2347+The top layer is loaded at boot time and saved at shutdown, to preserve
2348+the changes made to the system during the session.
2349+When larger changes have been made, or smaller changes have accumulated,
2350+the size of the saved top layer data grows. At this point, it would be
2351+nice to be able to merge the two overlay branches ('mods' and 'overlay')
2352+and rewrite the 'mods' squashfs, clearing the top layer and thus
2353+restoring save and load speed.
2354+
2355+This merging is simplified by the use of another aufs mount, of just the
2356+two overlay branches using the 'shwh' option.
2357+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
2358+ aufs /livesys/merge_union
2359+
2360+A merged view of these two branches is then available at
2361+/livesys/merge_union, and the new feature is that the whiteouts are
2362+visible!
2363+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
2364+writing to all branches. Also the default mode for all branches is 'ro'.
2365+It is now possible to save the combined contents of the two overlay
2366+branches to a new squashfs, e.g.:
2367+# mksquashfs /livesys/merge_union /path/to/newmods.squash
2368+
2369+This new squashfs archive can be stored on the boot device and the
2370+initramfs will use it to replace the old one at the next boot.
2371diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
2372--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
1c60b727 2373+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2017-07-29 12:14:25.896375188 +0200
7e9cd9fe 2374@@ -0,0 +1,47 @@
53392da6 2375+
a2654f78 2376+# Copyright (C) 2010-2017 Junjiro R. Okajima
53392da6
AM
2377+#
2378+# This program is free software; you can redistribute it and/or modify
2379+# it under the terms of the GNU General Public License as published by
2380+# the Free Software Foundation; either version 2 of the License, or
2381+# (at your option) any later version.
2382+#
2383+# This program is distributed in the hope that it will be useful,
2384+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2385+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2386+# GNU General Public License for more details.
2387+#
2388+# You should have received a copy of the GNU General Public License
523b37e3 2389+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2390+
2391+Dynamically customizable FS operations
2392+----------------------------------------------------------------------
2393+Generally FS operations (struct inode_operations, struct
2394+address_space_operations, struct file_operations, etc.) are defined as
2395+"static const", but it never means that FS have only one set of
2396+operation. Some FS have multiple sets of them. For instance, ext2 has
2397+three sets, one for XIP, for NOBH, and for normal.
2398+Since aufs overrides and redirects these operations, sometimes aufs has
7e9cd9fe 2399+to change its behaviour according to the branch FS type. More importantly
53392da6
AM
2400+VFS acts differently if a function (member in the struct) is set or
2401+not. It means aufs should have several sets of operations and select one
2402+among them according to the branch FS definition.
2403+
7e9cd9fe 2404+In order to solve this problem and not to affect the behaviour of VFS,
53392da6 2405+aufs defines these operations dynamically. For instance, aufs defines
7e9cd9fe
AM
2406+dummy direct_IO function for struct address_space_operations, but it may
2407+not be set to the address_space_operations actually. When the branch FS
2408+doesn't have it, aufs doesn't set it to its address_space_operations
2409+while the function definition itself is still alive. So the behaviour
2410+itself will not change, and it will return an error when direct_IO is
2411+not set.
53392da6
AM
2412+
2413+The lifetime of these dynamically generated operation object is
2414+maintained by aufs branch object. When the branch is removed from aufs,
2415+the reference counter of the object is decremented. When it reaches
2416+zero, the dynamically generated operation object will be freed.
2417+
7e9cd9fe
AM
2418+This approach is designed to support AIO (io_submit), Direct I/O and
2419+XIP (DAX) mainly.
2420+Currently this approach is applied to address_space_operations for
2421+regular files only.
53392da6
AM
2422diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
2423--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
1c60b727 2424+++ linux/Documentation/filesystems/aufs/README 2017-07-29 12:14:25.893041746 +0200
f2c43d5f 2425@@ -0,0 +1,393 @@
53392da6 2426+
5527c038 2427+Aufs4 -- advanced multi layered unification filesystem version 4.x
53392da6
AM
2428+http://aufs.sf.net
2429+Junjiro R. Okajima
2430+
2431+
2432+0. Introduction
2433+----------------------------------------
2434+In the early days, aufs was entirely re-designed and re-implemented
7e9cd9fe 2435+Unionfs Version 1.x series. Adding many original ideas, approaches,
53392da6
AM
2436+improvements and implementations, it becomes totally different from
2437+Unionfs while keeping the basic features.
2438+Recently, Unionfs Version 2.x series begin taking some of the same
2439+approaches to aufs1's.
2440+Unionfs is being developed by Professor Erez Zadok at Stony Brook
2441+University and his team.
2442+
5527c038 2443+Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3.
53392da6
AM
2444+If you want older kernel version support, try aufs2-2.6.git or
2445+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
2446+
2447+Note: it becomes clear that "Aufs was rejected. Let's give it up."
38d290e6
JR
2448+ According to Christoph Hellwig, linux rejects all union-type
2449+ filesystems but UnionMount.
53392da6
AM
2450+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
2451+
38d290e6
JR
2452+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
2453+ UnionMount, and he pointed out an issue around a directory mutex
2454+ lock and aufs addressed it. But it is still unsure whether aufs will
2455+ be merged (or any other union solution).
076b876e 2456+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
38d290e6 2457+
53392da6
AM
2458+
2459+1. Features
2460+----------------------------------------
2461+- unite several directories into a single virtual filesystem. The member
2462+ directory is called as a branch.
2463+- you can specify the permission flags to the branch, which are 'readonly',
2464+ 'readwrite' and 'whiteout-able.'
2465+- by upper writable branch, internal copyup and whiteout, files/dirs on
2466+ readonly branch are modifiable logically.
2467+- dynamic branch manipulation, add, del.
2468+- etc...
2469+
7e9cd9fe
AM
2470+Also there are many enhancements in aufs, such as:
2471+- test only the highest one for the directory permission (dirperm1)
2472+- copyup on open (coo=)
2473+- 'move' policy for copy-up between two writable branches, after
2474+ checking free space.
2475+- xattr, acl
53392da6
AM
2476+- readdir(3) in userspace.
2477+- keep inode number by external inode number table
2478+- keep the timestamps of file/dir in internal copyup operation
2479+- seekable directory, supporting NFS readdir.
2480+- whiteout is hardlinked in order to reduce the consumption of inodes
2481+ on branch
2482+- do not copyup, nor create a whiteout when it is unnecessary
2483+- revert a single systemcall when an error occurs in aufs
2484+- remount interface instead of ioctl
2485+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
2486+- loopback mounted filesystem as a branch
2487+- kernel thread for removing the dir who has a plenty of whiteouts
2488+- support copyup sparse file (a file which has a 'hole' in it)
2489+- default permission flags for branches
2490+- selectable permission flags for ro branch, whether whiteout can
2491+ exist or not
2492+- export via NFS.
2493+- support <sysfs>/fs/aufs and <debugfs>/aufs.
2494+- support multiple writable branches, some policies to select one
2495+ among multiple writable branches.
2496+- a new semantics for link(2) and rename(2) to support multiple
2497+ writable branches.
2498+- no glibc changes are required.
2499+- pseudo hardlink (hardlink over branches)
2500+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
2501+ including NFS or remote filesystem branch.
2502+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
2503+- and more...
2504+
5527c038 2505+Currently these features are dropped temporary from aufs4.
53392da6 2506+See design/08plan.txt in detail.
53392da6
AM
2507+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
2508+ (robr)
2509+- statistics of aufs thread (/sys/fs/aufs/stat)
53392da6
AM
2510+
2511+Features or just an idea in the future (see also design/*.txt),
2512+- reorder the branch index without del/re-add.
2513+- permanent xino files for NFSD
2514+- an option for refreshing the opened files after add/del branches
53392da6
AM
2515+- light version, without branch manipulation. (unnecessary?)
2516+- copyup in userspace
2517+- inotify in userspace
2518+- readv/writev
53392da6
AM
2519+
2520+
2521+2. Download
2522+----------------------------------------
5527c038
JR
2523+There are three GIT trees for aufs4, aufs4-linux.git,
2524+aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in
1e00d052 2525+"aufs-util.git."
5527c038
JR
2526+While the aufs-util is always necessary, you need either of aufs4-linux
2527+or aufs4-standalone.
1e00d052 2528+
5527c038 2529+The aufs4-linux tree includes the whole linux mainline GIT tree,
1e00d052
AM
2530+git://git.kernel.org/.../torvalds/linux.git.
2531+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
5527c038 2532+build aufs4 as an external kernel module.
2000de60 2533+Several extra patches are not included in this tree. Only
be52b249 2534+aufs4-standalone tree contains them. They are described in the later
2000de60 2535+section "Configuration and Compilation."
1e00d052 2536+
5527c038 2537+On the other hand, the aufs4-standalone tree has only aufs source files
53392da6 2538+and necessary patches, and you can select CONFIG_AUFS_FS=m.
2000de60 2539+But you need to apply all aufs patches manually.
53392da6 2540+
5527c038
JR
2541+You will find GIT branches whose name is in form of "aufs4.x" where "x"
2542+represents the linux kernel version, "linux-4.x". For instance,
2543+"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use
2544+"aufs4.x-rcN" branch.
1e00d052 2545+
5527c038 2546+o aufs4-linux tree
1e00d052 2547+$ git clone --reference /your/linux/git/tree \
5527c038 2548+ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git
1e00d052 2549+- if you don't have linux GIT tree, then remove "--reference ..."
5527c038
JR
2550+$ cd aufs4-linux.git
2551+$ git checkout origin/aufs4.0
53392da6 2552+
2000de60
JR
2553+Or You may want to directly git-pull aufs into your linux GIT tree, and
2554+leave the patch-work to GIT.
2555+$ cd /your/linux/git/tree
5527c038
JR
2556+$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git
2557+$ git fetch aufs4
2558+$ git checkout -b my4.0 v4.0
2559+$ (add your local change...)
2560+$ git pull aufs4 aufs4.0
2561+- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch.
2000de60 2562+- you may need to solve some conflicts between your_changes and
5527c038
JR
2563+ aufs4.0. in this case, git-rerere is recommended so that you can
2564+ solve the similar conflicts automatically when you upgrade to 4.1 or
2000de60
JR
2565+ later in the future.
2566+
5527c038
JR
2567+o aufs4-standalone tree
2568+$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git
2569+$ cd aufs4-standalone.git
2570+$ git checkout origin/aufs4.0
53392da6
AM
2571+
2572+o aufs-util tree
5527c038
JR
2573+$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git
2574+- note that the public aufs-util.git is on SourceForge instead of
2575+ GitHUB.
53392da6 2576+$ cd aufs-util.git
5527c038 2577+$ git checkout origin/aufs4.0
53392da6 2578+
5527c038
JR
2579+Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY.
2580+The minor version number, 'x' in '4.x', of aufs may not always
9dbd164d
AM
2581+follow the minor version number of the kernel.
2582+Because changes in the kernel that cause the use of a new
2583+minor version number do not always require changes to aufs-util.
2584+
2585+Since aufs-util has its own minor version number, you may not be
2586+able to find a GIT branch in aufs-util for your kernel's
2587+exact minor version number.
2588+In this case, you should git-checkout the branch for the
53392da6 2589+nearest lower number.
9dbd164d
AM
2590+
2591+For (an unreleased) example:
5527c038
JR
2592+If you are using "linux-4.10" and the "aufs4.10" branch
2593+does not exist in aufs-util repository, then "aufs4.9", "aufs4.8"
9dbd164d
AM
2594+or something numerically smaller is the branch for your kernel.
2595+
53392da6
AM
2596+Also you can view all branches by
2597+ $ git branch -a
2598+
2599+
2600+3. Configuration and Compilation
2601+----------------------------------------
2602+Make sure you have git-checkout'ed the correct branch.
2603+
5527c038 2604+For aufs4-linux tree,
c06a8ce3 2605+- enable CONFIG_AUFS_FS.
1e00d052
AM
2606+- set other aufs configurations if necessary.
2607+
5527c038 2608+For aufs4-standalone tree,
53392da6
AM
2609+There are several ways to build.
2610+
2611+1.
5527c038
JR
2612+- apply ./aufs4-kbuild.patch to your kernel source files.
2613+- apply ./aufs4-base.patch too.
2614+- apply ./aufs4-mmap.patch too.
2615+- apply ./aufs4-standalone.patch too, if you have a plan to set
2616+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch.
537831f9
AM
2617+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2618+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 2619+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
2620+ =m or =y.
2621+- and build your kernel as usual.
2622+- install the built kernel.
c06a8ce3
AM
2623+ Note: Since linux-3.9, every filesystem module requires an alias
2624+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2625+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
2626+- install the header files too by "make headers_install" to the
2627+ directory where you specify. By default, it is $PWD/usr.
b4510431 2628+ "make help" shows a brief note for headers_install.
53392da6
AM
2629+- and reboot your system.
2630+
2631+2.
2632+- module only (CONFIG_AUFS_FS=m).
5527c038
JR
2633+- apply ./aufs4-base.patch to your kernel source files.
2634+- apply ./aufs4-mmap.patch too.
2635+- apply ./aufs4-standalone.patch too.
53392da6
AM
2636+- build your kernel, don't forget "make headers_install", and reboot.
2637+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 2638+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
2639+ every aufs configurations.
2640+- build the module by simple "make".
c06a8ce3
AM
2641+ Note: Since linux-3.9, every filesystem module requires an alias
2642+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2643+ modules.aliases file.
53392da6
AM
2644+- you can specify ${KDIR} make variable which points to your kernel
2645+ source tree.
2646+- install the files
2647+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
2648+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2649+ + run "make install_headers" (instead of headers_install) to install
2650+ the modified aufs header file (you can specify DESTDIR which is
2651+ available in aufs standalone version's Makefile only), or copy
2652+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2653+ you like manually. By default, the target directory is $PWD/usr.
5527c038 2654+- no need to apply aufs4-kbuild.patch, nor copying source files to your
53392da6
AM
2655+ kernel source tree.
2656+
b4510431 2657+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
2658+ as well as "make headers_install" in the kernel source tree.
2659+ headers_install is subject to be forgotten, but it is essentially
2660+ necessary, not only for building aufs-util.
2661+ You may not meet problems without headers_install in some older
2662+ version though.
2663+
2664+And then,
2665+- read README in aufs-util, build and install it
9dbd164d
AM
2666+- note that your distribution may contain an obsoleted version of
2667+ aufs_type.h in /usr/include/linux or something. When you build aufs
2668+ utilities, make sure that your compiler refers the correct aufs header
2669+ file which is built by "make headers_install."
53392da6
AM
2670+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2671+ then run "make install_ulib" too. And refer to the aufs manual in
2672+ detail.
2673+
5527c038 2674+There several other patches in aufs4-standalone.git. They are all
38d290e6 2675+optional. When you meet some problems, they will help you.
5527c038 2676+- aufs4-loopback.patch
38d290e6
JR
2677+ Supports a nested loopback mount in a branch-fs. This patch is
2678+ unnecessary until aufs produces a message like "you may want to try
2679+ another patch for loopback file".
2680+- vfs-ino.patch
2681+ Modifies a system global kernel internal function get_next_ino() in
2682+ order to stop assigning 0 for an inode-number. Not directly related to
2683+ aufs, but recommended generally.
2684+- tmpfs-idr.patch
2685+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
2686+ the size of aufs XINO files for tmpfs branch. Also it prevents the
2687+ duplication of inode number, which is important for backup tools and
2688+ other utilities. When you find aufs XINO files for tmpfs branch
2689+ growing too much, try this patch.
be52b249
AM
2690+- lockdep-debug.patch
2691+ Because aufs is not only an ordinary filesystem (callee of VFS), but
2692+ also a caller of VFS functions for branch filesystems, subclassing of
2693+ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging
2694+ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will
2695+ need to apply this debug patch to expand several constant values.
2696+ If don't know what LOCKDEP, then you don't have apply this patch.
38d290e6 2697+
53392da6
AM
2698+
2699+4. Usage
2700+----------------------------------------
2701+At first, make sure aufs-util are installed, and please read the aufs
2702+manual, aufs.5 in aufs-util.git tree.
2703+$ man -l aufs.5
2704+
2705+And then,
2706+$ mkdir /tmp/rw /tmp/aufs
2707+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2708+
2709+Here is another example. The result is equivalent.
2710+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2711+ Or
2712+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2713+# mount -o remount,append:${HOME} /tmp/aufs
2714+
2715+Then, you can see whole tree of your home dir through /tmp/aufs. If
2716+you modify a file under /tmp/aufs, the one on your home directory is
2717+not affected, instead the same named file will be newly created under
2718+/tmp/rw. And all of your modification to a file will be applied to
2719+the one under /tmp/rw. This is called the file based Copy on Write
2720+(COW) method.
2721+Aufs mount options are described in aufs.5.
2722+If you run chroot or something and make your aufs as a root directory,
2723+then you need to customize the shutdown script. See the aufs manual in
2724+detail.
2725+
2726+Additionally, there are some sample usages of aufs which are a
2727+diskless system with network booting, and LiveCD over NFS.
2728+See sample dir in CVS tree on SourceForge.
2729+
2730+
2731+5. Contact
2732+----------------------------------------
2733+When you have any problems or strange behaviour in aufs, please let me
2734+know with:
2735+- /proc/mounts (instead of the output of mount(8))
2736+- /sys/module/aufs/*
2737+- /sys/fs/aufs/* (if you have them)
2738+- /debug/aufs/* (if you have them)
2739+- linux kernel version
2740+ if your kernel is not plain, for example modified by distributor,
2741+ the url where i can download its source is necessary too.
2742+- aufs version which was printed at loading the module or booting the
2743+ system, instead of the date you downloaded.
2744+- configuration (define/undefine CONFIG_AUFS_xxx)
2745+- kernel configuration or /proc/config.gz (if you have it)
2746+- behaviour which you think to be incorrect
2747+- actual operation, reproducible one is better
2748+- mailto: aufs-users at lists.sourceforge.net
2749+
2750+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2751+and Feature Requests) on SourceForge. Please join and write to
2752+aufs-users ML.
2753+
2754+
2755+6. Acknowledgements
2756+----------------------------------------
2757+Thanks to everyone who have tried and are using aufs, whoever
2758+have reported a bug or any feedback.
2759+
2760+Especially donators:
2761+Tomas Matejicek(slax.org) made a donation (much more than once).
2762+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2763+ scripts) is making "doubling" donations.
2764+ Unfortunately I cannot list all of the donators, but I really
b4510431 2765+ appreciate.
53392da6
AM
2766+ It ends Aug 2010, but the ordinary donation URL is still available.
2767+ <http://sourceforge.net/donate/index.php?group_id=167503>
2768+Dai Itasaka made a donation (2007/8).
2769+Chuck Smith made a donation (2008/4, 10 and 12).
2770+Henk Schoneveld made a donation (2008/9).
2771+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
2772+Francois Dupoux made a donation (2008/11).
2773+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
2774+ aufs2 GIT tree (2009/2).
2775+William Grant made a donation (2009/3).
2776+Patrick Lane made a donation (2009/4).
2777+The Mail Archive (mail-archive.com) made donations (2009/5).
2778+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
2779+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
2780+Pavel Pronskiy made a donation (2011/2).
2781+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
2782+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
2783+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
2784+11).
1e00d052 2785+Sam Liddicott made a donation (2011/9).
86dc4139
AM
2786+Era Scarecrow made a donation (2013/4).
2787+Bor Ratajc made a donation (2013/4).
2788+Alessandro Gorreta made a donation (2013/4).
2789+POIRETTE Marc made a donation (2013/4).
2790+Alessandro Gorreta made a donation (2013/4).
2791+lauri kasvandik made a donation (2013/5).
392086de 2792+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
2793+The Parted Magic Project made a donation (2013/9 and 11).
2794+Pavel Barta made a donation (2013/10).
38d290e6 2795+Nikolay Pertsev made a donation (2014/5).
c2c0f25c 2796+James B made a donation (2014/7 and 2015/7).
076b876e 2797+Stefano Di Biase made a donation (2014/8).
2000de60 2798+Daniel Epellei made a donation (2015/1).
8cdd5066 2799+OmegaPhil made a donation (2016/1).
5afbbe0d 2800+Tomasz Szewczyk made a donation (2016/4).
f2c43d5f 2801+James Burry made a donation (2016/12).
53392da6
AM
2802+
2803+Thank you very much.
2804+Donations are always, including future donations, very important and
2805+helpful for me to keep on developing aufs.
2806+
2807+
2808+7.
2809+----------------------------------------
2810+If you are an experienced user, no explanation is needed. Aufs is
2811+just a linux filesystem.
2812+
2813+
2814+Enjoy!
2815+
2816+# Local variables: ;
2817+# mode: text;
2818+# End: ;
7f207e10
AM
2819diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
2820--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 2821+++ linux/fs/aufs/aufs.h 2017-07-29 12:14:25.896375188 +0200
523b37e3 2822@@ -0,0 +1,59 @@
7f207e10 2823+/*
a2654f78 2824+ * Copyright (C) 2005-2017 Junjiro R. Okajima
7f207e10
AM
2825+ *
2826+ * This program, aufs is free software; you can redistribute it and/or modify
2827+ * it under the terms of the GNU General Public License as published by
2828+ * the Free Software Foundation; either version 2 of the License, or
2829+ * (at your option) any later version.
2830+ *
2831+ * This program is distributed in the hope that it will be useful,
2832+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2833+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2834+ * GNU General Public License for more details.
2835+ *
2836+ * You should have received a copy of the GNU General Public License
523b37e3 2837+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2838+ */
2839+
2840+/*
2841+ * all header files
2842+ */
2843+
2844+#ifndef __AUFS_H__
2845+#define __AUFS_H__
2846+
2847+#ifdef __KERNEL__
2848+
2849+#define AuStub(type, name, body, ...) \
2850+ static inline type name(__VA_ARGS__) { body; }
2851+
2852+#define AuStubVoid(name, ...) \
2853+ AuStub(void, name, , __VA_ARGS__)
2854+#define AuStubInt0(name, ...) \
2855+ AuStub(int, name, return 0, __VA_ARGS__)
2856+
2857+#include "debug.h"
2858+
2859+#include "branch.h"
2860+#include "cpup.h"
2861+#include "dcsub.h"
2862+#include "dbgaufs.h"
2863+#include "dentry.h"
2864+#include "dir.h"
2865+#include "dynop.h"
2866+#include "file.h"
2867+#include "fstype.h"
2868+#include "inode.h"
2869+#include "loop.h"
2870+#include "module.h"
7f207e10
AM
2871+#include "opts.h"
2872+#include "rwsem.h"
2873+#include "spl.h"
2874+#include "super.h"
2875+#include "sysaufs.h"
2876+#include "vfsub.h"
2877+#include "whout.h"
2878+#include "wkq.h"
2879+
2880+#endif /* __KERNEL__ */
2881+#endif /* __AUFS_H__ */
2882diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
2883--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
2884+++ linux/fs/aufs/branch.c 2017-07-29 12:14:25.896375188 +0200
2885@@ -0,0 +1,1422 @@
7f207e10 2886+/*
a2654f78 2887+ * Copyright (C) 2005-2017 Junjiro R. Okajima
7f207e10
AM
2888+ *
2889+ * This program, aufs is free software; you can redistribute it and/or modify
2890+ * it under the terms of the GNU General Public License as published by
2891+ * the Free Software Foundation; either version 2 of the License, or
2892+ * (at your option) any later version.
2893+ *
2894+ * This program is distributed in the hope that it will be useful,
2895+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2896+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2897+ * GNU General Public License for more details.
2898+ *
2899+ * You should have received a copy of the GNU General Public License
523b37e3 2900+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2901+ */
2902+
2903+/*
2904+ * branch management
2905+ */
2906+
027c5e7a 2907+#include <linux/compat.h>
7f207e10
AM
2908+#include <linux/statfs.h>
2909+#include "aufs.h"
2910+
2911+/*
2912+ * free a single branch
1facf9fc 2913+ */
2914+static void au_br_do_free(struct au_branch *br)
2915+{
2916+ int i;
2917+ struct au_wbr *wbr;
4a4d8108 2918+ struct au_dykey **key;
1facf9fc 2919+
027c5e7a
AM
2920+ au_hnotify_fin_br(br);
2921+
1facf9fc 2922+ if (br->br_xino.xi_file)
2923+ fput(br->br_xino.xi_file);
521ced18
JR
2924+ for (i = br->br_xino.xi_nondir.total - 1; i >= 0; i--)
2925+ AuDebugOn(br->br_xino.xi_nondir.array[i]);
1c60b727 2926+ kfree(br->br_xino.xi_nondir.array);
1facf9fc 2927+
5afbbe0d
AM
2928+ AuDebugOn(au_br_count(br));
2929+ au_br_count_fin(br);
1facf9fc 2930+
2931+ wbr = br->br_wbr;
2932+ if (wbr) {
2933+ for (i = 0; i < AuBrWh_Last; i++)
2934+ dput(wbr->wbr_wh[i]);
2935+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 2936+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 2937+ }
2938+
076b876e
AM
2939+ if (br->br_fhsm) {
2940+ au_br_fhsm_fin(br->br_fhsm);
1c60b727 2941+ kfree(br->br_fhsm);
076b876e
AM
2942+ }
2943+
4a4d8108
AM
2944+ key = br->br_dykey;
2945+ for (i = 0; i < AuBrDynOp; i++, key++)
2946+ if (*key)
2947+ au_dy_put(*key);
2948+ else
2949+ break;
2950+
537831f9
AM
2951+ /* recursive lock, s_umount of branch's */
2952+ lockdep_off();
86dc4139 2953+ path_put(&br->br_path);
537831f9 2954+ lockdep_on();
1c60b727
AM
2955+ kfree(wbr);
2956+ kfree(br);
1facf9fc 2957+}
2958+
2959+/*
2960+ * frees all branches
2961+ */
2962+void au_br_free(struct au_sbinfo *sbinfo)
2963+{
2964+ aufs_bindex_t bmax;
2965+ struct au_branch **br;
2966+
dece6358
AM
2967+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2968+
5afbbe0d 2969+ bmax = sbinfo->si_bbot + 1;
1facf9fc 2970+ br = sbinfo->si_branch;
2971+ while (bmax--)
2972+ au_br_do_free(*br++);
2973+}
2974+
2975+/*
2976+ * find the index of a branch which is specified by @br_id.
2977+ */
2978+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2979+{
5afbbe0d 2980+ aufs_bindex_t bindex, bbot;
1facf9fc 2981+
5afbbe0d
AM
2982+ bbot = au_sbbot(sb);
2983+ for (bindex = 0; bindex <= bbot; bindex++)
1facf9fc 2984+ if (au_sbr_id(sb, bindex) == br_id)
2985+ return bindex;
2986+ return -1;
2987+}
2988+
2989+/* ---------------------------------------------------------------------- */
2990+
2991+/*
2992+ * add a branch
2993+ */
2994+
b752ccd1
AM
2995+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2996+ struct dentry *h_root)
1facf9fc 2997+{
b752ccd1
AM
2998+ if (unlikely(h_adding == h_root
2999+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 3000+ return 1;
b752ccd1
AM
3001+ if (h_adding->d_sb != h_root->d_sb)
3002+ return 0;
3003+ return au_test_subdir(h_adding, h_root)
3004+ || au_test_subdir(h_root, h_adding);
1facf9fc 3005+}
3006+
3007+/*
3008+ * returns a newly allocated branch. @new_nbranch is a number of branches
3009+ * after adding a branch.
3010+ */
3011+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
3012+ int perm)
3013+{
3014+ struct au_branch *add_branch;
3015+ struct dentry *root;
5527c038 3016+ struct inode *inode;
4a4d8108 3017+ int err;
1facf9fc 3018+
4a4d8108 3019+ err = -ENOMEM;
be52b249 3020+ add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS);
1facf9fc 3021+ if (unlikely(!add_branch))
3022+ goto out;
521ced18
JR
3023+ add_branch->br_xino.xi_nondir.total = 8; /* initial size */
3024+ add_branch->br_xino.xi_nondir.array
3025+ = kzalloc(sizeof(ino_t) * add_branch->br_xino.xi_nondir.total,
3026+ GFP_NOFS);
3027+ if (unlikely(!add_branch->br_xino.xi_nondir.array))
3028+ goto out_br;
1facf9fc 3029+
027c5e7a
AM
3030+ err = au_hnotify_init_br(add_branch, perm);
3031+ if (unlikely(err))
521ced18 3032+ goto out_xinondir;
027c5e7a 3033+
1facf9fc 3034+ if (au_br_writable(perm)) {
3035+ /* may be freed separately at changing the branch permission */
be52b249 3036+ add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr),
1facf9fc 3037+ GFP_NOFS);
3038+ if (unlikely(!add_branch->br_wbr))
027c5e7a 3039+ goto out_hnotify;
1facf9fc 3040+ }
3041+
076b876e
AM
3042+ if (au_br_fhsm(perm)) {
3043+ err = au_fhsm_br_alloc(add_branch);
3044+ if (unlikely(err))
3045+ goto out_wbr;
3046+ }
3047+
521ced18 3048+ root = sb->s_root;
e2f27e51 3049+ err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0);
4a4d8108 3050+ if (!err)
e2f27e51 3051+ err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0);
5527c038
JR
3052+ if (!err) {
3053+ inode = d_inode(root);
1c60b727
AM
3054+ err = au_hinode_realloc(au_ii(inode), new_nbranch,
3055+ /*may_shrink*/0);
5527c038 3056+ }
4a4d8108
AM
3057+ if (!err)
3058+ return add_branch; /* success */
1facf9fc 3059+
076b876e 3060+out_wbr:
1c60b727 3061+ kfree(add_branch->br_wbr);
027c5e7a
AM
3062+out_hnotify:
3063+ au_hnotify_fin_br(add_branch);
521ced18 3064+out_xinondir:
1c60b727 3065+ kfree(add_branch->br_xino.xi_nondir.array);
4f0767ce 3066+out_br:
1c60b727 3067+ kfree(add_branch);
4f0767ce 3068+out:
4a4d8108 3069+ return ERR_PTR(err);
1facf9fc 3070+}
3071+
3072+/*
3073+ * test if the branch permission is legal or not.
3074+ */
3075+static int test_br(struct inode *inode, int brperm, char *path)
3076+{
3077+ int err;
3078+
4a4d8108
AM
3079+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
3080+ if (!err)
3081+ goto out;
1facf9fc 3082+
4a4d8108
AM
3083+ err = -EINVAL;
3084+ pr_err("write permission for readonly mount or inode, %s\n", path);
3085+
4f0767ce 3086+out:
1facf9fc 3087+ return err;
3088+}
3089+
3090+/*
3091+ * returns:
3092+ * 0: success, the caller will add it
3093+ * plus: success, it is already unified, the caller should ignore it
3094+ * minus: error
3095+ */
3096+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
3097+{
3098+ int err;
5afbbe0d 3099+ aufs_bindex_t bbot, bindex;
5527c038 3100+ struct dentry *root, *h_dentry;
1facf9fc 3101+ struct inode *inode, *h_inode;
3102+
3103+ root = sb->s_root;
5afbbe0d
AM
3104+ bbot = au_sbbot(sb);
3105+ if (unlikely(bbot >= 0
1facf9fc 3106+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
3107+ err = 1;
3108+ if (!remount) {
3109+ err = -EINVAL;
4a4d8108 3110+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 3111+ }
3112+ goto out;
3113+ }
3114+
3115+ err = -ENOSPC; /* -E2BIG; */
3116+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
5afbbe0d 3117+ || AUFS_BRANCH_MAX - 1 <= bbot)) {
4a4d8108 3118+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 3119+ goto out;
3120+ }
3121+
3122+ err = -EDOM;
5afbbe0d 3123+ if (unlikely(add->bindex < 0 || bbot + 1 < add->bindex)) {
4a4d8108 3124+ pr_err("bad index %d\n", add->bindex);
1facf9fc 3125+ goto out;
3126+ }
3127+
5527c038 3128+ inode = d_inode(add->path.dentry);
1facf9fc 3129+ err = -ENOENT;
3130+ if (unlikely(!inode->i_nlink)) {
4a4d8108 3131+ pr_err("no existence %s\n", add->pathname);
1facf9fc 3132+ goto out;
3133+ }
3134+
3135+ err = -EINVAL;
3136+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 3137+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 3138+ goto out;
3139+ }
3140+
3141+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
3142+ pr_err("unsupported filesystem, %s (%s)\n",
3143+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 3144+ goto out;
3145+ }
3146+
c1595e42
JR
3147+ if (unlikely(inode->i_sb->s_stack_depth)) {
3148+ pr_err("already stacked, %s (%s)\n",
3149+ add->pathname, au_sbtype(inode->i_sb));
3150+ goto out;
3151+ }
3152+
5527c038 3153+ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname);
1facf9fc 3154+ if (unlikely(err))
3155+ goto out;
3156+
5afbbe0d 3157+ if (bbot < 0)
1facf9fc 3158+ return 0; /* success */
3159+
3160+ err = -EINVAL;
5afbbe0d 3161+ for (bindex = 0; bindex <= bbot; bindex++)
1facf9fc 3162+ if (unlikely(test_overlap(sb, add->path.dentry,
3163+ au_h_dptr(root, bindex)))) {
4a4d8108 3164+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 3165+ goto out;
3166+ }
3167+
3168+ err = 0;
3169+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
5527c038
JR
3170+ h_dentry = au_h_dptr(root, 0);
3171+ h_inode = d_inode(h_dentry);
1facf9fc 3172+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
3173+ || !uid_eq(h_inode->i_uid, inode->i_uid)
3174+ || !gid_eq(h_inode->i_gid, inode->i_gid))
3175+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
3176+ add->pathname,
3177+ i_uid_read(inode), i_gid_read(inode),
3178+ (inode->i_mode & S_IALLUGO),
3179+ i_uid_read(h_inode), i_gid_read(h_inode),
3180+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 3181+ }
3182+
4f0767ce 3183+out:
1facf9fc 3184+ return err;
3185+}
3186+
3187+/*
3188+ * initialize or clean the whiteouts for an adding branch
3189+ */
3190+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 3191+ int new_perm)
1facf9fc 3192+{
3193+ int err, old_perm;
3194+ aufs_bindex_t bindex;
febd17d6 3195+ struct inode *h_inode;
1facf9fc 3196+ struct au_wbr *wbr;
3197+ struct au_hinode *hdir;
5527c038 3198+ struct dentry *h_dentry;
1facf9fc 3199+
86dc4139
AM
3200+ err = vfsub_mnt_want_write(au_br_mnt(br));
3201+ if (unlikely(err))
3202+ goto out;
3203+
1facf9fc 3204+ wbr = br->br_wbr;
3205+ old_perm = br->br_perm;
3206+ br->br_perm = new_perm;
3207+ hdir = NULL;
febd17d6 3208+ h_inode = NULL;
1facf9fc 3209+ bindex = au_br_index(sb, br->br_id);
3210+ if (0 <= bindex) {
5527c038 3211+ hdir = au_hi(d_inode(sb->s_root), bindex);
5afbbe0d 3212+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 3213+ } else {
5527c038 3214+ h_dentry = au_br_dentry(br);
febd17d6
JR
3215+ h_inode = d_inode(h_dentry);
3216+ inode_lock_nested(h_inode, AuLsc_I_PARENT);
1facf9fc 3217+ }
3218+ if (!wbr)
86dc4139 3219+ err = au_wh_init(br, sb);
1facf9fc 3220+ else {
3221+ wbr_wh_write_lock(wbr);
86dc4139 3222+ err = au_wh_init(br, sb);
1facf9fc 3223+ wbr_wh_write_unlock(wbr);
3224+ }
3225+ if (hdir)
5afbbe0d 3226+ au_hn_inode_unlock(hdir);
1facf9fc 3227+ else
febd17d6 3228+ inode_unlock(h_inode);
86dc4139 3229+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 3230+ br->br_perm = old_perm;
3231+
3232+ if (!err && wbr && !au_br_writable(new_perm)) {
1c60b727 3233+ kfree(wbr);
1facf9fc 3234+ br->br_wbr = NULL;
3235+ }
3236+
86dc4139 3237+out:
1facf9fc 3238+ return err;
3239+}
3240+
3241+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 3242+ int perm)
1facf9fc 3243+{
3244+ int err;
4a4d8108 3245+ struct kstatfs kst;
1facf9fc 3246+ struct au_wbr *wbr;
3247+
3248+ wbr = br->br_wbr;
dece6358 3249+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 3250+ atomic_set(&wbr->wbr_wh_running, 0);
1facf9fc 3251+
4a4d8108
AM
3252+ /*
3253+ * a limit for rmdir/rename a dir
523b37e3 3254+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 3255+ */
86dc4139 3256+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
3257+ if (unlikely(err))
3258+ goto out;
3259+ err = -EINVAL;
3260+ if (kst.f_namelen >= NAME_MAX)
86dc4139 3261+ err = au_br_init_wh(sb, br, perm);
4a4d8108 3262+ else
523b37e3
AM
3263+ pr_err("%pd(%s), unsupported namelen %ld\n",
3264+ au_br_dentry(br),
86dc4139 3265+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 3266+
4f0767ce 3267+out:
1facf9fc 3268+ return err;
3269+}
3270+
c1595e42 3271+/* initialize a new branch */
1facf9fc 3272+static int au_br_init(struct au_branch *br, struct super_block *sb,
3273+ struct au_opt_add *add)
3274+{
3275+ int err;
5527c038 3276+ struct inode *h_inode;
1facf9fc 3277+
3278+ err = 0;
521ced18
JR
3279+ spin_lock_init(&br->br_xino.xi_nondir.spin);
3280+ init_waitqueue_head(&br->br_xino.xi_nondir.wqh);
1facf9fc 3281+ br->br_perm = add->perm;
86dc4139 3282+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108 3283+ spin_lock_init(&br->br_dykey_lock);
5afbbe0d 3284+ au_br_count_init(br);
1facf9fc 3285+ atomic_set(&br->br_xino_running, 0);
3286+ br->br_id = au_new_br_id(sb);
7f207e10 3287+ AuDebugOn(br->br_id < 0);
1facf9fc 3288+
3289+ if (au_br_writable(add->perm)) {
86dc4139 3290+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 3291+ if (unlikely(err))
b752ccd1 3292+ goto out_err;
1facf9fc 3293+ }
3294+
3295+ if (au_opt_test(au_mntflags(sb), XINO)) {
5527c038
JR
3296+ h_inode = d_inode(add->path.dentry);
3297+ err = au_xino_br(sb, br, h_inode->i_ino,
1facf9fc 3298+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
3299+ if (unlikely(err)) {
3300+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 3301+ goto out_err;
1facf9fc 3302+ }
3303+ }
3304+
3305+ sysaufs_br_init(br);
86dc4139 3306+ path_get(&br->br_path);
b752ccd1 3307+ goto out; /* success */
1facf9fc 3308+
4f0767ce 3309+out_err:
86dc4139 3310+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 3311+out:
1facf9fc 3312+ return err;
3313+}
3314+
3315+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
5afbbe0d 3316+ struct au_branch *br, aufs_bindex_t bbot,
1facf9fc 3317+ aufs_bindex_t amount)
3318+{
3319+ struct au_branch **brp;
3320+
dece6358
AM
3321+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3322+
1facf9fc 3323+ brp = sbinfo->si_branch + bindex;
3324+ memmove(brp + 1, brp, sizeof(*brp) * amount);
3325+ *brp = br;
5afbbe0d
AM
3326+ sbinfo->si_bbot++;
3327+ if (unlikely(bbot < 0))
3328+ sbinfo->si_bbot = 0;
1facf9fc 3329+}
3330+
3331+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
5afbbe0d 3332+ aufs_bindex_t bbot, aufs_bindex_t amount)
1facf9fc 3333+{
3334+ struct au_hdentry *hdp;
3335+
1308ab2a 3336+ AuRwMustWriteLock(&dinfo->di_rwsem);
3337+
5afbbe0d 3338+ hdp = au_hdentry(dinfo, bindex);
1facf9fc 3339+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
3340+ au_h_dentry_init(hdp);
5afbbe0d
AM
3341+ dinfo->di_bbot++;
3342+ if (unlikely(bbot < 0))
3343+ dinfo->di_btop = 0;
1facf9fc 3344+}
3345+
3346+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
5afbbe0d 3347+ aufs_bindex_t bbot, aufs_bindex_t amount)
1facf9fc 3348+{
3349+ struct au_hinode *hip;
3350+
1308ab2a 3351+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3352+
5afbbe0d 3353+ hip = au_hinode(iinfo, bindex);
1facf9fc 3354+ memmove(hip + 1, hip, sizeof(*hip) * amount);
5afbbe0d
AM
3355+ au_hinode_init(hip);
3356+ iinfo->ii_bbot++;
3357+ if (unlikely(bbot < 0))
3358+ iinfo->ii_btop = 0;
1facf9fc 3359+}
3360+
86dc4139
AM
3361+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
3362+ aufs_bindex_t bindex)
1facf9fc 3363+{
86dc4139 3364+ struct dentry *root, *h_dentry;
5527c038 3365+ struct inode *root_inode, *h_inode;
5afbbe0d 3366+ aufs_bindex_t bbot, amount;
1facf9fc 3367+
3368+ root = sb->s_root;
5527c038 3369+ root_inode = d_inode(root);
5afbbe0d
AM
3370+ bbot = au_sbbot(sb);
3371+ amount = bbot + 1 - bindex;
86dc4139 3372+ h_dentry = au_br_dentry(br);
53392da6 3373+ au_sbilist_lock();
5afbbe0d
AM
3374+ au_br_do_add_brp(au_sbi(sb), bindex, br, bbot, amount);
3375+ au_br_do_add_hdp(au_di(root), bindex, bbot, amount);
3376+ au_br_do_add_hip(au_ii(root_inode), bindex, bbot, amount);
1facf9fc 3377+ au_set_h_dptr(root, bindex, dget(h_dentry));
5527c038
JR
3378+ h_inode = d_inode(h_dentry);
3379+ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
53392da6 3380+ au_sbilist_unlock();
1facf9fc 3381+}
3382+
3383+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
3384+{
3385+ int err;
5afbbe0d 3386+ aufs_bindex_t bbot, add_bindex;
1facf9fc 3387+ struct dentry *root, *h_dentry;
3388+ struct inode *root_inode;
3389+ struct au_branch *add_branch;
3390+
3391+ root = sb->s_root;
5527c038 3392+ root_inode = d_inode(root);
1facf9fc 3393+ IMustLock(root_inode);
5afbbe0d 3394+ IiMustWriteLock(root_inode);
1facf9fc 3395+ err = test_add(sb, add, remount);
3396+ if (unlikely(err < 0))
3397+ goto out;
3398+ if (err) {
3399+ err = 0;
3400+ goto out; /* success */
3401+ }
3402+
5afbbe0d
AM
3403+ bbot = au_sbbot(sb);
3404+ add_branch = au_br_alloc(sb, bbot + 2, add->perm);
1facf9fc 3405+ err = PTR_ERR(add_branch);
3406+ if (IS_ERR(add_branch))
3407+ goto out;
3408+
3409+ err = au_br_init(add_branch, sb, add);
3410+ if (unlikely(err)) {
3411+ au_br_do_free(add_branch);
3412+ goto out;
3413+ }
3414+
3415+ add_bindex = add->bindex;
1facf9fc 3416+ if (!remount)
86dc4139 3417+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3418+ else {
3419+ sysaufs_brs_del(sb, add_bindex);
86dc4139 3420+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3421+ sysaufs_brs_add(sb, add_bindex);
3422+ }
3423+
86dc4139 3424+ h_dentry = add->path.dentry;
1308ab2a 3425+ if (!add_bindex) {
1facf9fc 3426+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 3427+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
3428+ } else
5527c038 3429+ au_add_nlink(root_inode, d_inode(h_dentry));
1facf9fc 3430+
3431+ /*
4a4d8108 3432+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 3433+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 3434+ * once detached from aufs.
3435+ */
3436+ if (au_xino_brid(sb) < 0
3437+ && au_br_writable(add_branch->br_perm)
3438+ && !au_test_fs_bad_xino(h_dentry->d_sb)
3439+ && add_branch->br_xino.xi_file
2000de60 3440+ && add_branch->br_xino.xi_file->f_path.dentry->d_parent == h_dentry)
1facf9fc 3441+ au_xino_brid_set(sb, add_branch->br_id);
3442+
4f0767ce 3443+out:
1facf9fc 3444+ return err;
3445+}
3446+
3447+/* ---------------------------------------------------------------------- */
3448+
79b8bda9 3449+static unsigned long long au_farray_cb(struct super_block *sb, void *a,
076b876e
AM
3450+ unsigned long long max __maybe_unused,
3451+ void *arg)
3452+{
3453+ unsigned long long n;
3454+ struct file **p, *f;
3455+ struct au_sphlhead *files;
3456+ struct au_finfo *finfo;
076b876e
AM
3457+
3458+ n = 0;
3459+ p = a;
3460+ files = &au_sbi(sb)->si_files;
3461+ spin_lock(&files->spin);
3462+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
3463+ f = finfo->fi_file;
3464+ if (file_count(f)
3465+ && !special_file(file_inode(f)->i_mode)) {
3466+ get_file(f);
3467+ *p++ = f;
3468+ n++;
3469+ AuDebugOn(n > max);
3470+ }
3471+ }
3472+ spin_unlock(&files->spin);
3473+
3474+ return n;
3475+}
3476+
3477+static struct file **au_farray_alloc(struct super_block *sb,
3478+ unsigned long long *max)
3479+{
5afbbe0d 3480+ *max = au_nfiles(sb);
79b8bda9 3481+ return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL);
076b876e
AM
3482+}
3483+
3484+static void au_farray_free(struct file **a, unsigned long long max)
3485+{
3486+ unsigned long long ull;
3487+
3488+ for (ull = 0; ull < max; ull++)
3489+ if (a[ull])
3490+ fput(a[ull]);
be52b249 3491+ kvfree(a);
076b876e
AM
3492+}
3493+
3494+/* ---------------------------------------------------------------------- */
3495+
1facf9fc 3496+/*
3497+ * delete a branch
3498+ */
3499+
3500+/* to show the line number, do not make it inlined function */
4a4d8108 3501+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 3502+ if (do_info) \
4a4d8108 3503+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 3504+} while (0)
3505+
5afbbe0d
AM
3506+static int au_test_ibusy(struct inode *inode, aufs_bindex_t btop,
3507+ aufs_bindex_t bbot)
027c5e7a 3508+{
5afbbe0d 3509+ return (inode && !S_ISDIR(inode->i_mode)) || btop == bbot;
027c5e7a
AM
3510+}
3511+
5afbbe0d
AM
3512+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t btop,
3513+ aufs_bindex_t bbot)
027c5e7a 3514+{
5afbbe0d 3515+ return au_test_ibusy(d_inode(dentry), btop, bbot);
027c5e7a
AM
3516+}
3517+
1facf9fc 3518+/*
3519+ * test if the branch is deletable or not.
3520+ */
3521+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 3522+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3523+{
3524+ int err, i, j, ndentry;
5afbbe0d 3525+ aufs_bindex_t btop, bbot;
1facf9fc 3526+ struct au_dcsub_pages dpages;
3527+ struct au_dpage *dpage;
3528+ struct dentry *d;
1facf9fc 3529+
3530+ err = au_dpages_init(&dpages, GFP_NOFS);
3531+ if (unlikely(err))
3532+ goto out;
3533+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
3534+ if (unlikely(err))
3535+ goto out_dpages;
3536+
1facf9fc 3537+ for (i = 0; !err && i < dpages.ndpage; i++) {
3538+ dpage = dpages.dpages + i;
3539+ ndentry = dpage->ndentry;
3540+ for (j = 0; !err && j < ndentry; j++) {
3541+ d = dpage->dentries[j];
c1595e42 3542+ AuDebugOn(au_dcount(d) <= 0);
027c5e7a 3543+ if (!au_digen_test(d, sigen)) {
1facf9fc 3544+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
3545+ if (unlikely(au_dbrange_test(d))) {
3546+ di_read_unlock(d, AuLock_IR);
3547+ continue;
3548+ }
3549+ } else {
1facf9fc 3550+ di_write_lock_child(d);
027c5e7a
AM
3551+ if (unlikely(au_dbrange_test(d))) {
3552+ di_write_unlock(d);
3553+ continue;
3554+ }
1facf9fc 3555+ err = au_reval_dpath(d, sigen);
3556+ if (!err)
3557+ di_downgrade_lock(d, AuLock_IR);
3558+ else {
3559+ di_write_unlock(d);
3560+ break;
3561+ }
3562+ }
3563+
027c5e7a 3564+ /* AuDbgDentry(d); */
5afbbe0d
AM
3565+ btop = au_dbtop(d);
3566+ bbot = au_dbbot(d);
3567+ if (btop <= bindex
3568+ && bindex <= bbot
1facf9fc 3569+ && au_h_dptr(d, bindex)
5afbbe0d 3570+ && au_test_dbusy(d, btop, bbot)) {
1facf9fc 3571+ err = -EBUSY;
523b37e3 3572+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 3573+ AuDbgDentry(d);
1facf9fc 3574+ }
3575+ di_read_unlock(d, AuLock_IR);
3576+ }
3577+ }
3578+
4f0767ce 3579+out_dpages:
1facf9fc 3580+ au_dpages_free(&dpages);
4f0767ce 3581+out:
1facf9fc 3582+ return err;
3583+}
3584+
3585+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 3586+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3587+{
3588+ int err;
7f207e10
AM
3589+ unsigned long long max, ull;
3590+ struct inode *i, **array;
5afbbe0d 3591+ aufs_bindex_t btop, bbot;
1facf9fc 3592+
7f207e10
AM
3593+ array = au_iarray_alloc(sb, &max);
3594+ err = PTR_ERR(array);
3595+ if (IS_ERR(array))
3596+ goto out;
3597+
1facf9fc 3598+ err = 0;
7f207e10
AM
3599+ AuDbg("b%d\n", bindex);
3600+ for (ull = 0; !err && ull < max; ull++) {
3601+ i = array[ull];
076b876e
AM
3602+ if (unlikely(!i))
3603+ break;
7f207e10 3604+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 3605+ continue;
3606+
7f207e10 3607+ /* AuDbgInode(i); */
537831f9 3608+ if (au_iigen(i, NULL) == sigen)
1facf9fc 3609+ ii_read_lock_child(i);
3610+ else {
3611+ ii_write_lock_child(i);
027c5e7a
AM
3612+ err = au_refresh_hinode_self(i);
3613+ au_iigen_dec(i);
1facf9fc 3614+ if (!err)
3615+ ii_downgrade_lock(i);
3616+ else {
3617+ ii_write_unlock(i);
3618+ break;
3619+ }
3620+ }
3621+
5afbbe0d
AM
3622+ btop = au_ibtop(i);
3623+ bbot = au_ibbot(i);
3624+ if (btop <= bindex
3625+ && bindex <= bbot
1facf9fc 3626+ && au_h_iptr(i, bindex)
5afbbe0d 3627+ && au_test_ibusy(i, btop, bbot)) {
1facf9fc 3628+ err = -EBUSY;
3629+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 3630+ AuDbgInode(i);
1facf9fc 3631+ }
3632+ ii_read_unlock(i);
3633+ }
7f207e10 3634+ au_iarray_free(array, max);
1facf9fc 3635+
7f207e10 3636+out:
1facf9fc 3637+ return err;
3638+}
3639+
b752ccd1
AM
3640+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
3641+ const unsigned int verbose)
1facf9fc 3642+{
3643+ int err;
3644+ unsigned int sigen;
3645+
3646+ sigen = au_sigen(root->d_sb);
3647+ DiMustNoWaiters(root);
5527c038 3648+ IiMustNoWaiters(d_inode(root));
1facf9fc 3649+ di_write_unlock(root);
b752ccd1 3650+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 3651+ if (!err)
b752ccd1 3652+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 3653+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3654+
3655+ return err;
3656+}
3657+
076b876e
AM
3658+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
3659+ struct file **to_free, int *idx)
3660+{
3661+ int err;
c1595e42 3662+ unsigned char matched, root;
5afbbe0d 3663+ aufs_bindex_t bindex, bbot;
076b876e
AM
3664+ struct au_fidir *fidir;
3665+ struct au_hfile *hfile;
3666+
3667+ err = 0;
2000de60 3668+ root = IS_ROOT(file->f_path.dentry);
c1595e42
JR
3669+ if (root) {
3670+ get_file(file);
3671+ to_free[*idx] = file;
3672+ (*idx)++;
3673+ goto out;
3674+ }
3675+
076b876e 3676+ matched = 0;
076b876e
AM
3677+ fidir = au_fi(file)->fi_hdir;
3678+ AuDebugOn(!fidir);
5afbbe0d
AM
3679+ bbot = au_fbbot_dir(file);
3680+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) {
076b876e
AM
3681+ hfile = fidir->fd_hfile + bindex;
3682+ if (!hfile->hf_file)
3683+ continue;
3684+
c1595e42 3685+ if (hfile->hf_br->br_id == br_id) {
076b876e 3686+ matched = 1;
076b876e 3687+ break;
c1595e42 3688+ }
076b876e 3689+ }
c1595e42 3690+ if (matched)
076b876e
AM
3691+ err = -EBUSY;
3692+
3693+out:
3694+ return err;
3695+}
3696+
3697+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
3698+ struct file **to_free, int opened)
3699+{
3700+ int err, idx;
3701+ unsigned long long ull, max;
5afbbe0d 3702+ aufs_bindex_t btop;
076b876e 3703+ struct file *file, **array;
076b876e
AM
3704+ struct dentry *root;
3705+ struct au_hfile *hfile;
3706+
3707+ array = au_farray_alloc(sb, &max);
3708+ err = PTR_ERR(array);
3709+ if (IS_ERR(array))
3710+ goto out;
3711+
3712+ err = 0;
3713+ idx = 0;
3714+ root = sb->s_root;
3715+ di_write_unlock(root);
3716+ for (ull = 0; ull < max; ull++) {
3717+ file = array[ull];
3718+ if (unlikely(!file))
3719+ break;
3720+
3721+ /* AuDbg("%pD\n", file); */
3722+ fi_read_lock(file);
5afbbe0d 3723+ btop = au_fbtop(file);
2000de60 3724+ if (!d_is_dir(file->f_path.dentry)) {
076b876e
AM
3725+ hfile = &au_fi(file)->fi_htop;
3726+ if (hfile->hf_br->br_id == br_id)
3727+ err = -EBUSY;
3728+ } else
3729+ err = test_dir_busy(file, br_id, to_free, &idx);
3730+ fi_read_unlock(file);
3731+ if (unlikely(err))
3732+ break;
3733+ }
3734+ di_write_lock_child(root);
3735+ au_farray_free(array, max);
3736+ AuDebugOn(idx > opened);
3737+
3738+out:
3739+ return err;
3740+}
3741+
3742+static void br_del_file(struct file **to_free, unsigned long long opened,
3743+ aufs_bindex_t br_id)
3744+{
3745+ unsigned long long ull;
5afbbe0d 3746+ aufs_bindex_t bindex, btop, bbot, bfound;
076b876e
AM
3747+ struct file *file;
3748+ struct au_fidir *fidir;
3749+ struct au_hfile *hfile;
3750+
3751+ for (ull = 0; ull < opened; ull++) {
3752+ file = to_free[ull];
3753+ if (unlikely(!file))
3754+ break;
3755+
3756+ /* AuDbg("%pD\n", file); */
2000de60 3757+ AuDebugOn(!d_is_dir(file->f_path.dentry));
076b876e
AM
3758+ bfound = -1;
3759+ fidir = au_fi(file)->fi_hdir;
3760+ AuDebugOn(!fidir);
3761+ fi_write_lock(file);
5afbbe0d
AM
3762+ btop = au_fbtop(file);
3763+ bbot = au_fbbot_dir(file);
3764+ for (bindex = btop; bindex <= bbot; bindex++) {
076b876e
AM
3765+ hfile = fidir->fd_hfile + bindex;
3766+ if (!hfile->hf_file)
3767+ continue;
3768+
3769+ if (hfile->hf_br->br_id == br_id) {
3770+ bfound = bindex;
3771+ break;
3772+ }
3773+ }
3774+ AuDebugOn(bfound < 0);
3775+ au_set_h_fptr(file, bfound, NULL);
5afbbe0d
AM
3776+ if (bfound == btop) {
3777+ for (btop++; btop <= bbot; btop++)
3778+ if (au_hf_dir(file, btop)) {
3779+ au_set_fbtop(file, btop);
076b876e
AM
3780+ break;
3781+ }
3782+ }
3783+ fi_write_unlock(file);
3784+ }
3785+}
3786+
1facf9fc 3787+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
3788+ const aufs_bindex_t bindex,
5afbbe0d 3789+ const aufs_bindex_t bbot)
1facf9fc 3790+{
3791+ struct au_branch **brp, **p;
3792+
dece6358
AM
3793+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3794+
1facf9fc 3795+ brp = sbinfo->si_branch + bindex;
5afbbe0d
AM
3796+ if (bindex < bbot)
3797+ memmove(brp, brp + 1, sizeof(*brp) * (bbot - bindex));
3798+ sbinfo->si_branch[0 + bbot] = NULL;
3799+ sbinfo->si_bbot--;
1facf9fc 3800+
e2f27e51
AM
3801+ p = au_krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST,
3802+ /*may_shrink*/1);
1facf9fc 3803+ if (p)
3804+ sbinfo->si_branch = p;
4a4d8108 3805+ /* harmless error */
1facf9fc 3806+}
3807+
3808+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
5afbbe0d 3809+ const aufs_bindex_t bbot)
1facf9fc 3810+{
3811+ struct au_hdentry *hdp, *p;
3812+
1308ab2a 3813+ AuRwMustWriteLock(&dinfo->di_rwsem);
3814+
5afbbe0d
AM
3815+ hdp = au_hdentry(dinfo, bindex);
3816+ if (bindex < bbot)
3817+ memmove(hdp, hdp + 1, sizeof(*hdp) * (bbot - bindex));
3818+ /* au_h_dentry_init(au_hdentry(dinfo, bbot); */
3819+ dinfo->di_bbot--;
1facf9fc 3820+
e2f27e51
AM
3821+ p = au_krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST,
3822+ /*may_shrink*/1);
1facf9fc 3823+ if (p)
3824+ dinfo->di_hdentry = p;
4a4d8108 3825+ /* harmless error */
1facf9fc 3826+}
3827+
3828+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
5afbbe0d 3829+ const aufs_bindex_t bbot)
1facf9fc 3830+{
3831+ struct au_hinode *hip, *p;
3832+
1308ab2a 3833+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3834+
5afbbe0d
AM
3835+ hip = au_hinode(iinfo, bindex);
3836+ if (bindex < bbot)
3837+ memmove(hip, hip + 1, sizeof(*hip) * (bbot - bindex));
3838+ /* au_hinode_init(au_hinode(iinfo, bbot)); */
3839+ iinfo->ii_bbot--;
1facf9fc 3840+
e2f27e51
AM
3841+ p = au_krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST,
3842+ /*may_shrink*/1);
1facf9fc 3843+ if (p)
3844+ iinfo->ii_hinode = p;
4a4d8108 3845+ /* harmless error */
1facf9fc 3846+}
3847+
3848+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
3849+ struct au_branch *br)
3850+{
5afbbe0d 3851+ aufs_bindex_t bbot;
1facf9fc 3852+ struct au_sbinfo *sbinfo;
53392da6
AM
3853+ struct dentry *root, *h_root;
3854+ struct inode *inode, *h_inode;
3855+ struct au_hinode *hinode;
1facf9fc 3856+
dece6358
AM
3857+ SiMustWriteLock(sb);
3858+
1facf9fc 3859+ root = sb->s_root;
5527c038 3860+ inode = d_inode(root);
1facf9fc 3861+ sbinfo = au_sbi(sb);
5afbbe0d 3862+ bbot = sbinfo->si_bbot;
1facf9fc 3863+
53392da6
AM
3864+ h_root = au_h_dptr(root, bindex);
3865+ hinode = au_hi(inode, bindex);
3866+ h_inode = au_igrab(hinode->hi_inode);
3867+ au_hiput(hinode);
1facf9fc 3868+
53392da6 3869+ au_sbilist_lock();
5afbbe0d
AM
3870+ au_br_do_del_brp(sbinfo, bindex, bbot);
3871+ au_br_do_del_hdp(au_di(root), bindex, bbot);
3872+ au_br_do_del_hip(au_ii(inode), bindex, bbot);
53392da6
AM
3873+ au_sbilist_unlock();
3874+
3875+ dput(h_root);
3876+ iput(h_inode);
3877+ au_br_do_free(br);
1facf9fc 3878+}
3879+
79b8bda9
AM
3880+static unsigned long long empty_cb(struct super_block *sb, void *array,
3881+ unsigned long long max, void *arg)
076b876e
AM
3882+{
3883+ return max;
3884+}
3885+
1facf9fc 3886+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
3887+{
3888+ int err, rerr, i;
076b876e 3889+ unsigned long long opened;
1facf9fc 3890+ unsigned int mnt_flags;
5afbbe0d 3891+ aufs_bindex_t bindex, bbot, br_id;
1facf9fc 3892+ unsigned char do_wh, verbose;
3893+ struct au_branch *br;
3894+ struct au_wbr *wbr;
076b876e
AM
3895+ struct dentry *root;
3896+ struct file **to_free;
1facf9fc 3897+
3898+ err = 0;
076b876e
AM
3899+ opened = 0;
3900+ to_free = NULL;
3901+ root = sb->s_root;
3902+ bindex = au_find_dbindex(root, del->h_path.dentry);
1facf9fc 3903+ if (bindex < 0) {
3904+ if (remount)
3905+ goto out; /* success */
3906+ err = -ENOENT;
4a4d8108 3907+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 3908+ goto out;
3909+ }
3910+ AuDbg("bindex b%d\n", bindex);
3911+
3912+ err = -EBUSY;
3913+ mnt_flags = au_mntflags(sb);
3914+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
5afbbe0d
AM
3915+ bbot = au_sbbot(sb);
3916+ if (unlikely(!bbot)) {
1facf9fc 3917+ AuVerbose(verbose, "no more branches left\n");
3918+ goto out;
3919+ }
3920+ br = au_sbr(sb, bindex);
86dc4139 3921+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
076b876e
AM
3922+
3923+ br_id = br->br_id;
5afbbe0d 3924+ opened = au_br_count(br);
076b876e 3925+ if (unlikely(opened)) {
79b8bda9 3926+ to_free = au_array_alloc(&opened, empty_cb, sb, NULL);
076b876e
AM
3927+ err = PTR_ERR(to_free);
3928+ if (IS_ERR(to_free))
3929+ goto out;
3930+
3931+ err = test_file_busy(sb, br_id, to_free, opened);
3932+ if (unlikely(err)) {
3933+ AuVerbose(verbose, "%llu file(s) opened\n", opened);
3934+ goto out;
3935+ }
1facf9fc 3936+ }
3937+
3938+ wbr = br->br_wbr;
3939+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
3940+ if (do_wh) {
1308ab2a 3941+ /* instead of WbrWhMustWriteLock(wbr) */
3942+ SiMustWriteLock(sb);
1facf9fc 3943+ for (i = 0; i < AuBrWh_Last; i++) {
3944+ dput(wbr->wbr_wh[i]);
3945+ wbr->wbr_wh[i] = NULL;
3946+ }
3947+ }
3948+
076b876e 3949+ err = test_children_busy(root, bindex, verbose);
1facf9fc 3950+ if (unlikely(err)) {
3951+ if (do_wh)
3952+ goto out_wh;
3953+ goto out;
3954+ }
3955+
3956+ err = 0;
076b876e
AM
3957+ if (to_free) {
3958+ /*
3959+ * now we confirmed the branch is deletable.
3960+ * let's free the remaining opened dirs on the branch.
3961+ */
3962+ di_write_unlock(root);
3963+ br_del_file(to_free, opened, br_id);
3964+ di_write_lock_child(root);
3965+ }
3966+
1facf9fc 3967+ if (!remount)
3968+ au_br_do_del(sb, bindex, br);
3969+ else {
3970+ sysaufs_brs_del(sb, bindex);
3971+ au_br_do_del(sb, bindex, br);
3972+ sysaufs_brs_add(sb, bindex);
3973+ }
3974+
1308ab2a 3975+ if (!bindex) {
5527c038 3976+ au_cpup_attr_all(d_inode(root), /*force*/1);
1308ab2a 3977+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
3978+ } else
5527c038 3979+ au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry));
1facf9fc 3980+ if (au_opt_test(mnt_flags, PLINK))
3981+ au_plink_half_refresh(sb, br_id);
3982+
b752ccd1 3983+ if (au_xino_brid(sb) == br_id)
1facf9fc 3984+ au_xino_brid_set(sb, -1);
3985+ goto out; /* success */
3986+
4f0767ce 3987+out_wh:
1facf9fc 3988+ /* revert */
86dc4139 3989+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 3990+ if (rerr)
0c3ec466
AM
3991+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
3992+ del->pathname, rerr);
4f0767ce 3993+out:
076b876e
AM
3994+ if (to_free)
3995+ au_farray_free(to_free, opened);
1facf9fc 3996+ return err;
3997+}
3998+
3999+/* ---------------------------------------------------------------------- */
4000+
027c5e7a
AM
4001+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
4002+{
4003+ int err;
5afbbe0d 4004+ aufs_bindex_t btop, bbot;
027c5e7a
AM
4005+ struct aufs_ibusy ibusy;
4006+ struct inode *inode, *h_inode;
4007+
4008+ err = -EPERM;
4009+ if (unlikely(!capable(CAP_SYS_ADMIN)))
4010+ goto out;
4011+
4012+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
4013+ if (!err)
4014+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
4015+ if (unlikely(err)) {
4016+ err = -EFAULT;
4017+ AuTraceErr(err);
4018+ goto out;
4019+ }
4020+
4021+ err = -EINVAL;
4022+ si_read_lock(sb, AuLock_FLUSH);
5afbbe0d 4023+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbbot(sb)))
027c5e7a
AM
4024+ goto out_unlock;
4025+
4026+ err = 0;
4027+ ibusy.h_ino = 0; /* invalid */
4028+ inode = ilookup(sb, ibusy.ino);
4029+ if (!inode
4030+ || inode->i_ino == AUFS_ROOT_INO
5afbbe0d 4031+ || au_is_bad_inode(inode))
027c5e7a
AM
4032+ goto out_unlock;
4033+
4034+ ii_read_lock_child(inode);
5afbbe0d
AM
4035+ btop = au_ibtop(inode);
4036+ bbot = au_ibbot(inode);
4037+ if (btop <= ibusy.bindex && ibusy.bindex <= bbot) {
027c5e7a 4038+ h_inode = au_h_iptr(inode, ibusy.bindex);
5afbbe0d 4039+ if (h_inode && au_test_ibusy(inode, btop, bbot))
027c5e7a
AM
4040+ ibusy.h_ino = h_inode->i_ino;
4041+ }
4042+ ii_read_unlock(inode);
4043+ iput(inode);
4044+
4045+out_unlock:
4046+ si_read_unlock(sb);
4047+ if (!err) {
4048+ err = __put_user(ibusy.h_ino, &arg->h_ino);
4049+ if (unlikely(err)) {
4050+ err = -EFAULT;
4051+ AuTraceErr(err);
4052+ }
4053+ }
4054+out:
4055+ return err;
4056+}
4057+
4058+long au_ibusy_ioctl(struct file *file, unsigned long arg)
4059+{
2000de60 4060+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg);
027c5e7a
AM
4061+}
4062+
4063+#ifdef CONFIG_COMPAT
4064+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
4065+{
2000de60 4066+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg));
027c5e7a
AM
4067+}
4068+#endif
4069+
4070+/* ---------------------------------------------------------------------- */
4071+
1facf9fc 4072+/*
4073+ * change a branch permission
4074+ */
4075+
dece6358
AM
4076+static void au_warn_ima(void)
4077+{
4078+#ifdef CONFIG_IMA
1308ab2a 4079+ /* since it doesn't support mark_files_ro() */
027c5e7a 4080+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
4081+#endif
4082+}
4083+
1facf9fc 4084+static int do_need_sigen_inc(int a, int b)
4085+{
4086+ return au_br_whable(a) && !au_br_whable(b);
4087+}
4088+
4089+static int need_sigen_inc(int old, int new)
4090+{
4091+ return do_need_sigen_inc(old, new)
4092+ || do_need_sigen_inc(new, old);
4093+}
4094+
4095+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
4096+{
7f207e10 4097+ int err, do_warn;
027c5e7a 4098+ unsigned int mnt_flags;
7f207e10 4099+ unsigned long long ull, max;
e49829fe 4100+ aufs_bindex_t br_id;
38d290e6 4101+ unsigned char verbose, writer;
7f207e10 4102+ struct file *file, *hf, **array;
e49829fe 4103+ struct au_hfile *hfile;
1facf9fc 4104+
027c5e7a
AM
4105+ mnt_flags = au_mntflags(sb);
4106+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
4107+
7f207e10
AM
4108+ array = au_farray_alloc(sb, &max);
4109+ err = PTR_ERR(array);
4110+ if (IS_ERR(array))
1facf9fc 4111+ goto out;
4112+
7f207e10 4113+ do_warn = 0;
e49829fe 4114+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
4115+ for (ull = 0; ull < max; ull++) {
4116+ file = array[ull];
076b876e
AM
4117+ if (unlikely(!file))
4118+ break;
1facf9fc 4119+
523b37e3 4120+ /* AuDbg("%pD\n", file); */
1facf9fc 4121+ fi_read_lock(file);
4122+ if (unlikely(au_test_mmapped(file))) {
4123+ err = -EBUSY;
523b37e3 4124+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 4125+ AuDbgFile(file);
1facf9fc 4126+ FiMustNoWaiters(file);
4127+ fi_read_unlock(file);
7f207e10 4128+ goto out_array;
1facf9fc 4129+ }
4130+
e49829fe
JR
4131+ hfile = &au_fi(file)->fi_htop;
4132+ hf = hfile->hf_file;
7e9cd9fe 4133+ if (!d_is_reg(file->f_path.dentry)
1facf9fc 4134+ || !(file->f_mode & FMODE_WRITE)
e49829fe 4135+ || hfile->hf_br->br_id != br_id
7f207e10
AM
4136+ || !(hf->f_mode & FMODE_WRITE))
4137+ array[ull] = NULL;
4138+ else {
4139+ do_warn = 1;
4140+ get_file(file);
1facf9fc 4141+ }
4142+
1facf9fc 4143+ FiMustNoWaiters(file);
4144+ fi_read_unlock(file);
7f207e10
AM
4145+ fput(file);
4146+ }
1facf9fc 4147+
4148+ err = 0;
7f207e10 4149+ if (do_warn)
dece6358 4150+ au_warn_ima();
7f207e10
AM
4151+
4152+ for (ull = 0; ull < max; ull++) {
4153+ file = array[ull];
4154+ if (!file)
4155+ continue;
4156+
1facf9fc 4157+ /* todo: already flushed? */
523b37e3
AM
4158+ /*
4159+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
4160+ * approach which resets f_mode and calls mnt_drop_write() and
4161+ * file_release_write() for each file, because the branch
4162+ * attribute in aufs world is totally different from the native
4163+ * fs rw/ro mode.
4164+ */
7f207e10
AM
4165+ /* fi_read_lock(file); */
4166+ hfile = &au_fi(file)->fi_htop;
4167+ hf = hfile->hf_file;
4168+ /* fi_read_unlock(file); */
027c5e7a 4169+ spin_lock(&hf->f_lock);
38d290e6
JR
4170+ writer = !!(hf->f_mode & FMODE_WRITER);
4171+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
027c5e7a 4172+ spin_unlock(&hf->f_lock);
38d290e6
JR
4173+ if (writer) {
4174+ put_write_access(file_inode(hf));
c06a8ce3 4175+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 4176+ }
4177+ }
4178+
7f207e10
AM
4179+out_array:
4180+ au_farray_free(array, max);
4f0767ce 4181+out:
7f207e10 4182+ AuTraceErr(err);
1facf9fc 4183+ return err;
4184+}
4185+
4186+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4187+ int *do_refresh)
1facf9fc 4188+{
4189+ int err, rerr;
4190+ aufs_bindex_t bindex;
4191+ struct dentry *root;
4192+ struct au_branch *br;
076b876e 4193+ struct au_br_fhsm *bf;
1facf9fc 4194+
4195+ root = sb->s_root;
1facf9fc 4196+ bindex = au_find_dbindex(root, mod->h_root);
4197+ if (bindex < 0) {
4198+ if (remount)
4199+ return 0; /* success */
4200+ err = -ENOENT;
4a4d8108 4201+ pr_err("%s no such branch\n", mod->path);
1facf9fc 4202+ goto out;
4203+ }
4204+ AuDbg("bindex b%d\n", bindex);
4205+
5527c038 4206+ err = test_br(d_inode(mod->h_root), mod->perm, mod->path);
1facf9fc 4207+ if (unlikely(err))
4208+ goto out;
4209+
4210+ br = au_sbr(sb, bindex);
86dc4139 4211+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 4212+ if (br->br_perm == mod->perm)
4213+ return 0; /* success */
4214+
076b876e
AM
4215+ /* pre-allocate for non-fhsm --> fhsm */
4216+ bf = NULL;
4217+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
4218+ err = au_fhsm_br_alloc(br);
4219+ if (unlikely(err))
4220+ goto out;
4221+ bf = br->br_fhsm;
4222+ br->br_fhsm = NULL;
4223+ }
4224+
1facf9fc 4225+ if (au_br_writable(br->br_perm)) {
4226+ /* remove whiteout base */
86dc4139 4227+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 4228+ if (unlikely(err))
076b876e 4229+ goto out_bf;
1facf9fc 4230+
4231+ if (!au_br_writable(mod->perm)) {
4232+ /* rw --> ro, file might be mmapped */
4233+ DiMustNoWaiters(root);
5527c038 4234+ IiMustNoWaiters(d_inode(root));
1facf9fc 4235+ di_write_unlock(root);
4236+ err = au_br_mod_files_ro(sb, bindex);
4237+ /* aufs_write_lock() calls ..._child() */
4238+ di_write_lock_child(root);
4239+
4240+ if (unlikely(err)) {
4241+ rerr = -ENOMEM;
be52b249 4242+ br->br_wbr = kzalloc(sizeof(*br->br_wbr),
1facf9fc 4243+ GFP_NOFS);
86dc4139
AM
4244+ if (br->br_wbr)
4245+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 4246+ if (unlikely(rerr)) {
4247+ AuIOErr("nested error %d (%d)\n",
4248+ rerr, err);
4249+ br->br_perm = mod->perm;
4250+ }
4251+ }
4252+ }
4253+ } else if (au_br_writable(mod->perm)) {
4254+ /* ro --> rw */
4255+ err = -ENOMEM;
be52b249 4256+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), GFP_NOFS);
1facf9fc 4257+ if (br->br_wbr) {
86dc4139 4258+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 4259+ if (unlikely(err)) {
1c60b727 4260+ kfree(br->br_wbr);
1facf9fc 4261+ br->br_wbr = NULL;
4262+ }
4263+ }
4264+ }
076b876e
AM
4265+ if (unlikely(err))
4266+ goto out_bf;
4267+
4268+ if (au_br_fhsm(br->br_perm)) {
4269+ if (!au_br_fhsm(mod->perm)) {
4270+ /* fhsm --> non-fhsm */
4271+ au_br_fhsm_fin(br->br_fhsm);
1c60b727 4272+ kfree(br->br_fhsm);
076b876e
AM
4273+ br->br_fhsm = NULL;
4274+ }
4275+ } else if (au_br_fhsm(mod->perm))
4276+ /* non-fhsm --> fhsm */
4277+ br->br_fhsm = bf;
4278+
076b876e
AM
4279+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
4280+ br->br_perm = mod->perm;
4281+ goto out; /* success */
1facf9fc 4282+
076b876e 4283+out_bf:
f0c0a007 4284+ if (bf)
1c60b727 4285+ kfree(bf);
076b876e
AM
4286+out:
4287+ AuTraceErr(err);
4288+ return err;
4289+}
4290+
4291+/* ---------------------------------------------------------------------- */
4292+
4293+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
4294+{
4295+ int err;
4296+ struct kstatfs kstfs;
4297+
4298+ err = vfs_statfs(&br->br_path, &kstfs);
1facf9fc 4299+ if (!err) {
076b876e
AM
4300+ stfs->f_blocks = kstfs.f_blocks;
4301+ stfs->f_bavail = kstfs.f_bavail;
4302+ stfs->f_files = kstfs.f_files;
4303+ stfs->f_ffree = kstfs.f_ffree;
1facf9fc 4304+ }
4305+
1facf9fc 4306+ return err;
4307+}
7f207e10
AM
4308diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
4309--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 4310+++ linux/fs/aufs/branch.h 2017-07-29 12:14:25.896375188 +0200
521ced18 4311@@ -0,0 +1,321 @@
1facf9fc 4312+/*
a2654f78 4313+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 4314+ *
4315+ * This program, aufs is free software; you can redistribute it and/or modify
4316+ * it under the terms of the GNU General Public License as published by
4317+ * the Free Software Foundation; either version 2 of the License, or
4318+ * (at your option) any later version.
dece6358
AM
4319+ *
4320+ * This program is distributed in the hope that it will be useful,
4321+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4322+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4323+ * GNU General Public License for more details.
4324+ *
4325+ * You should have received a copy of the GNU General Public License
523b37e3 4326+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4327+ */
4328+
4329+/*
4330+ * branch filesystems and xino for them
4331+ */
4332+
4333+#ifndef __AUFS_BRANCH_H__
4334+#define __AUFS_BRANCH_H__
4335+
4336+#ifdef __KERNEL__
4337+
1facf9fc 4338+#include <linux/mount.h>
4a4d8108 4339+#include "dynop.h"
1facf9fc 4340+#include "rwsem.h"
4341+#include "super.h"
4342+
4343+/* ---------------------------------------------------------------------- */
4344+
4345+/* a xino file */
4346+struct au_xino_file {
4347+ struct file *xi_file;
521ced18
JR
4348+ struct {
4349+ spinlock_t spin;
4350+ ino_t *array;
4351+ int total;
4352+ /* reserved for future use */
4353+ /* unsigned long *bitmap; */
4354+ wait_queue_head_t wqh;
4355+ } xi_nondir;
1facf9fc 4356+
4357+ /* todo: make xino files an array to support huge inode number */
4358+
4359+#ifdef CONFIG_DEBUG_FS
4360+ struct dentry *xi_dbgaufs;
4361+#endif
4362+};
4363+
076b876e
AM
4364+/* File-based Hierarchical Storage Management */
4365+struct au_br_fhsm {
4366+#ifdef CONFIG_AUFS_FHSM
4367+ struct mutex bf_lock;
4368+ unsigned long bf_jiffy;
4369+ struct aufs_stfs bf_stfs;
4370+ int bf_readable;
4371+#endif
4372+};
4373+
1facf9fc 4374+/* members for writable branch only */
4375+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
4376+struct au_wbr {
dece6358 4377+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 4378+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 4379+ atomic_t wbr_wh_running;
1facf9fc 4380+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
4381+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
4382+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
4383+
4384+ /* mfs mode */
4385+ unsigned long long wbr_bytes;
4386+};
4387+
4a4d8108
AM
4388+/* ext2 has 3 types of operations at least, ext3 has 4 */
4389+#define AuBrDynOp (AuDyLast * 4)
4390+
1716fcea
AM
4391+#ifdef CONFIG_AUFS_HFSNOTIFY
4392+/* support for asynchronous destruction */
4393+struct au_br_hfsnotify {
4394+ struct fsnotify_group *hfsn_group;
4395+};
4396+#endif
4397+
392086de
AM
4398+/* sysfs entries */
4399+struct au_brsysfs {
4400+ char name[16];
4401+ struct attribute attr;
4402+};
4403+
4404+enum {
4405+ AuBrSysfs_BR,
4406+ AuBrSysfs_BRID,
4407+ AuBrSysfs_Last
4408+};
4409+
1facf9fc 4410+/* protected by superblock rwsem */
4411+struct au_branch {
4412+ struct au_xino_file br_xino;
4413+
4414+ aufs_bindex_t br_id;
4415+
4416+ int br_perm;
86dc4139 4417+ struct path br_path;
4a4d8108
AM
4418+ spinlock_t br_dykey_lock;
4419+ struct au_dykey *br_dykey[AuBrDynOp];
5afbbe0d 4420+ struct percpu_counter br_count;
1facf9fc 4421+
4422+ struct au_wbr *br_wbr;
076b876e 4423+ struct au_br_fhsm *br_fhsm;
1facf9fc 4424+
4425+ /* xino truncation */
1facf9fc 4426+ atomic_t br_xino_running;
4427+
027c5e7a 4428+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 4429+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
4430+#endif
4431+
1facf9fc 4432+#ifdef CONFIG_SYSFS
392086de
AM
4433+ /* entries under sysfs per mount-point */
4434+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 4435+#endif
4436+};
4437+
4438+/* ---------------------------------------------------------------------- */
4439+
86dc4139
AM
4440+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
4441+{
4442+ return br->br_path.mnt;
4443+}
4444+
4445+static inline struct dentry *au_br_dentry(struct au_branch *br)
4446+{
4447+ return br->br_path.dentry;
4448+}
4449+
4450+static inline struct super_block *au_br_sb(struct au_branch *br)
4451+{
4452+ return au_br_mnt(br)->mnt_sb;
4453+}
4454+
5afbbe0d
AM
4455+static inline void au_br_get(struct au_branch *br)
4456+{
4457+ percpu_counter_inc(&br->br_count);
4458+}
4459+
4460+static inline void au_br_put(struct au_branch *br)
4461+{
4462+ percpu_counter_dec(&br->br_count);
4463+}
4464+
4465+static inline s64 au_br_count(struct au_branch *br)
4466+{
4467+ return percpu_counter_sum(&br->br_count);
4468+}
4469+
4470+static inline void au_br_count_init(struct au_branch *br)
4471+{
4472+ percpu_counter_init(&br->br_count, 0, GFP_NOFS);
4473+}
4474+
4475+static inline void au_br_count_fin(struct au_branch *br)
4476+{
4477+ percpu_counter_destroy(&br->br_count);
4478+}
4479+
1facf9fc 4480+static inline int au_br_rdonly(struct au_branch *br)
4481+{
86dc4139 4482+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 4483+ || !au_br_writable(br->br_perm))
4484+ ? -EROFS : 0;
4485+}
4486+
4a4d8108 4487+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 4488+{
4a4d8108 4489+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 4490+ return !(brperm & AuBrPerm_RR);
1facf9fc 4491+#else
4492+ return 0;
4493+#endif
4494+}
4495+
b912730e
AM
4496+static inline int au_br_test_oflag(int oflag, struct au_branch *br)
4497+{
4498+ int err, exec_flag;
4499+
4500+ err = 0;
4501+ exec_flag = oflag & __FMODE_EXEC;
79b8bda9 4502+ if (unlikely(exec_flag && path_noexec(&br->br_path)))
b912730e
AM
4503+ err = -EACCES;
4504+
4505+ return err;
4506+}
4507+
1facf9fc 4508+/* ---------------------------------------------------------------------- */
4509+
4510+/* branch.c */
4511+struct au_sbinfo;
4512+void au_br_free(struct au_sbinfo *sinfo);
4513+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
4514+struct au_opt_add;
4515+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
4516+struct au_opt_del;
4517+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
4518+long au_ibusy_ioctl(struct file *file, unsigned long arg);
4519+#ifdef CONFIG_COMPAT
4520+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
4521+#endif
1facf9fc 4522+struct au_opt_mod;
4523+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4524+ int *do_refresh);
076b876e
AM
4525+struct aufs_stfs;
4526+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
1facf9fc 4527+
4528+/* xino.c */
4529+static const loff_t au_loff_max = LLONG_MAX;
4530+
4531+int au_xib_trunc(struct super_block *sb);
5527c038 4532+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size,
1facf9fc 4533+ loff_t *pos);
5527c038
JR
4534+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
4535+ size_t size, loff_t *pos);
1facf9fc 4536+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
4537+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
4538+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 4539+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 4540+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4541+ ino_t ino);
4542+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4543+ ino_t *ino);
4544+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
4545+ struct file *base_file, int do_test);
4546+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
4547+
4548+struct au_opt_xino;
4549+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
4550+void au_xino_clr(struct super_block *sb);
4551+struct file *au_xino_def(struct super_block *sb);
4552+int au_xino_path(struct seq_file *seq, struct file *file);
4553+
521ced18
JR
4554+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
4555+ ino_t h_ino, int idx);
4556+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4557+ int *idx);
4558+
1facf9fc 4559+/* ---------------------------------------------------------------------- */
4560+
4561+/* Superblock to branch */
4562+static inline
4563+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
4564+{
4565+ return au_sbr(sb, bindex)->br_id;
4566+}
4567+
4568+static inline
4569+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
4570+{
86dc4139 4571+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 4572+}
4573+
4574+static inline
4575+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
4576+{
86dc4139 4577+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 4578+}
4579+
5afbbe0d
AM
4580+static inline void au_sbr_get(struct super_block *sb, aufs_bindex_t bindex)
4581+{
4582+ au_br_get(au_sbr(sb, bindex));
4583+}
4584+
1facf9fc 4585+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
4586+{
5afbbe0d 4587+ au_br_put(au_sbr(sb, bindex));
1facf9fc 4588+}
4589+
4590+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
4591+{
4592+ return au_sbr(sb, bindex)->br_perm;
4593+}
4594+
4595+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
4596+{
4597+ return au_br_whable(au_sbr_perm(sb, bindex));
4598+}
4599+
4600+/* ---------------------------------------------------------------------- */
4601+
4602+/*
4603+ * wbr_wh_read_lock, wbr_wh_write_lock
4604+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
4605+ */
4606+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
4607+
dece6358
AM
4608+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
4609+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
4610+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
4611+
076b876e
AM
4612+/* ---------------------------------------------------------------------- */
4613+
4614+#ifdef CONFIG_AUFS_FHSM
4615+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
4616+{
4617+ mutex_init(&brfhsm->bf_lock);
4618+ brfhsm->bf_jiffy = 0;
4619+ brfhsm->bf_readable = 0;
4620+}
4621+
4622+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
4623+{
4624+ mutex_destroy(&brfhsm->bf_lock);
4625+}
4626+#else
4627+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
4628+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
4629+#endif
4630+
1facf9fc 4631+#endif /* __KERNEL__ */
4632+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
4633diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
4634--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
1c60b727 4635+++ linux/fs/aufs/conf.mk 2017-07-29 12:14:25.899708630 +0200
c1595e42 4636@@ -0,0 +1,38 @@
4a4d8108
AM
4637+
4638+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
4639+
4640+define AuConf
4641+ifdef ${1}
4642+AuConfStr += ${1}=${${1}}
4643+endif
4644+endef
4645+
b752ccd1 4646+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 4647+ SBILIST \
7f207e10 4648+ HNOTIFY HFSNOTIFY \
4a4d8108 4649+ EXPORT INO_T_64 \
c1595e42 4650+ XATTR \
076b876e 4651+ FHSM \
4a4d8108 4652+ RDU \
4a4d8108
AM
4653+ SHWH \
4654+ BR_RAMFS \
4655+ BR_FUSE POLL \
4656+ BR_HFSPLUS \
4657+ BDEV_LOOP \
b752ccd1
AM
4658+ DEBUG MAGIC_SYSRQ
4659+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
4660+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
4661+
4662+AuConfName = ${obj}/conf.str
4663+${AuConfName}.tmp: FORCE
4664+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
4665+${AuConfName}: ${AuConfName}.tmp
4666+ @diff -q $< $@ > /dev/null 2>&1 || { \
4667+ echo ' GEN ' $@; \
4668+ cp -p $< $@; \
4669+ }
4670+FORCE:
4671+clean-files += ${AuConfName} ${AuConfName}.tmp
4672+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
4673+
4674+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
4675diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
4676--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
3c1bdaff 4677+++ linux/fs/aufs/cpup.c 2017-09-05 10:42:11.055421928 +0200
1c60b727 4678@@ -0,0 +1,1442 @@
1facf9fc 4679+/*
a2654f78 4680+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 4681+ *
4682+ * This program, aufs is free software; you can redistribute it and/or modify
4683+ * it under the terms of the GNU General Public License as published by
4684+ * the Free Software Foundation; either version 2 of the License, or
4685+ * (at your option) any later version.
dece6358
AM
4686+ *
4687+ * This program is distributed in the hope that it will be useful,
4688+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4689+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4690+ * GNU General Public License for more details.
4691+ *
4692+ * You should have received a copy of the GNU General Public License
523b37e3 4693+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4694+ */
4695+
4696+/*
4697+ * copy-up functions, see wbr_policy.c for copy-down
4698+ */
4699+
4700+#include <linux/fs_stack.h>
dece6358 4701+#include <linux/mm.h>
8cdd5066 4702+#include <linux/task_work.h>
1facf9fc 4703+#include "aufs.h"
4704+
86dc4139 4705+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 4706+{
4707+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 4708+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 4709+
86dc4139
AM
4710+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
4711+
4712+ dst->i_flags |= iflags & ~mask;
1facf9fc 4713+ if (au_test_fs_notime(dst->i_sb))
4714+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
4715+}
4716+
4717+void au_cpup_attr_timesizes(struct inode *inode)
4718+{
4719+ struct inode *h_inode;
4720+
5afbbe0d 4721+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 4722+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 4723+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 4724+}
4725+
4726+void au_cpup_attr_nlink(struct inode *inode, int force)
4727+{
4728+ struct inode *h_inode;
4729+ struct super_block *sb;
5afbbe0d 4730+ aufs_bindex_t bindex, bbot;
1facf9fc 4731+
4732+ sb = inode->i_sb;
5afbbe0d 4733+ bindex = au_ibtop(inode);
1facf9fc 4734+ h_inode = au_h_iptr(inode, bindex);
4735+ if (!force
4736+ && !S_ISDIR(h_inode->i_mode)
4737+ && au_opt_test(au_mntflags(sb), PLINK)
4738+ && au_plink_test(inode))
4739+ return;
4740+
7eafdf33
AM
4741+ /*
4742+ * 0 can happen in revalidating.
38d290e6
JR
4743+ * h_inode->i_mutex may not be held here, but it is harmless since once
4744+ * i_nlink reaches 0, it will never become positive except O_TMPFILE
4745+ * case.
4746+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
4747+ * the incorrect link count.
7eafdf33 4748+ */
92d182d2 4749+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 4750+
4751+ /*
4752+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
4753+ * it may includes whplink directory.
4754+ */
4755+ if (S_ISDIR(h_inode->i_mode)) {
5afbbe0d
AM
4756+ bbot = au_ibbot(inode);
4757+ for (bindex++; bindex <= bbot; bindex++) {
1facf9fc 4758+ h_inode = au_h_iptr(inode, bindex);
4759+ if (h_inode)
4760+ au_add_nlink(inode, h_inode);
4761+ }
4762+ }
4763+}
4764+
4765+void au_cpup_attr_changeable(struct inode *inode)
4766+{
4767+ struct inode *h_inode;
4768+
5afbbe0d 4769+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 4770+ inode->i_mode = h_inode->i_mode;
4771+ inode->i_uid = h_inode->i_uid;
4772+ inode->i_gid = h_inode->i_gid;
4773+ au_cpup_attr_timesizes(inode);
86dc4139 4774+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 4775+}
4776+
4777+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
4778+{
4779+ struct au_iinfo *iinfo = au_ii(inode);
4780+
1308ab2a 4781+ IiMustWriteLock(inode);
4782+
1facf9fc 4783+ iinfo->ii_higen = h_inode->i_generation;
4784+ iinfo->ii_hsb1 = h_inode->i_sb;
4785+}
4786+
4787+void au_cpup_attr_all(struct inode *inode, int force)
4788+{
4789+ struct inode *h_inode;
4790+
5afbbe0d 4791+ h_inode = au_h_iptr(inode, au_ibtop(inode));
1facf9fc 4792+ au_cpup_attr_changeable(inode);
4793+ if (inode->i_nlink > 0)
4794+ au_cpup_attr_nlink(inode, force);
4795+ inode->i_rdev = h_inode->i_rdev;
4796+ inode->i_blkbits = h_inode->i_blkbits;
4797+ au_cpup_igen(inode, h_inode);
4798+}
4799+
4800+/* ---------------------------------------------------------------------- */
4801+
4802+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
4803+
4804+/* keep the timestamps of the parent dir when cpup */
4805+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4806+ struct path *h_path)
4807+{
4808+ struct inode *h_inode;
4809+
4810+ dt->dt_dentry = dentry;
4811+ dt->dt_h_path = *h_path;
5527c038 4812+ h_inode = d_inode(h_path->dentry);
1facf9fc 4813+ dt->dt_atime = h_inode->i_atime;
4814+ dt->dt_mtime = h_inode->i_mtime;
4815+ /* smp_mb(); */
4816+}
4817+
4818+void au_dtime_revert(struct au_dtime *dt)
4819+{
4820+ struct iattr attr;
4821+ int err;
4822+
4823+ attr.ia_atime = dt->dt_atime;
4824+ attr.ia_mtime = dt->dt_mtime;
4825+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
4826+ | ATTR_ATIME | ATTR_ATIME_SET;
4827+
523b37e3
AM
4828+ /* no delegation since this is a directory */
4829+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 4830+ if (unlikely(err))
0c3ec466 4831+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 4832+}
4833+
4834+/* ---------------------------------------------------------------------- */
4835+
86dc4139
AM
4836+/* internal use only */
4837+struct au_cpup_reg_attr {
4838+ int valid;
4839+ struct kstat st;
4840+ unsigned int iflags; /* inode->i_flags */
4841+};
4842+
1facf9fc 4843+static noinline_for_stack
86dc4139
AM
4844+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
4845+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4846+{
c1595e42 4847+ int err, sbits, icex;
7e9cd9fe
AM
4848+ unsigned int mnt_flags;
4849+ unsigned char verbose;
1facf9fc 4850+ struct iattr ia;
4851+ struct path h_path;
1308ab2a 4852+ struct inode *h_isrc, *h_idst;
86dc4139 4853+ struct kstat *h_st;
c1595e42 4854+ struct au_branch *br;
1facf9fc 4855+
4856+ h_path.dentry = au_h_dptr(dst, bindex);
5527c038 4857+ h_idst = d_inode(h_path.dentry);
c1595e42
JR
4858+ br = au_sbr(dst->d_sb, bindex);
4859+ h_path.mnt = au_br_mnt(br);
5527c038 4860+ h_isrc = d_inode(h_src);
1308ab2a 4861+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 4862+ | ATTR_ATIME | ATTR_MTIME
4863+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
4864+ if (h_src_attr && h_src_attr->valid) {
4865+ h_st = &h_src_attr->st;
4866+ ia.ia_uid = h_st->uid;
4867+ ia.ia_gid = h_st->gid;
4868+ ia.ia_atime = h_st->atime;
4869+ ia.ia_mtime = h_st->mtime;
4870+ if (h_idst->i_mode != h_st->mode
4871+ && !S_ISLNK(h_idst->i_mode)) {
4872+ ia.ia_valid |= ATTR_MODE;
4873+ ia.ia_mode = h_st->mode;
4874+ }
4875+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
4876+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
4877+ } else {
4878+ ia.ia_uid = h_isrc->i_uid;
4879+ ia.ia_gid = h_isrc->i_gid;
4880+ ia.ia_atime = h_isrc->i_atime;
4881+ ia.ia_mtime = h_isrc->i_mtime;
4882+ if (h_idst->i_mode != h_isrc->i_mode
4883+ && !S_ISLNK(h_idst->i_mode)) {
4884+ ia.ia_valid |= ATTR_MODE;
4885+ ia.ia_mode = h_isrc->i_mode;
4886+ }
4887+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
4888+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 4889+ }
523b37e3
AM
4890+ /* no delegation since it is just created */
4891+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4892+
4893+ /* is this nfs only? */
4894+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
4895+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
4896+ ia.ia_mode = h_isrc->i_mode;
523b37e3 4897+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4898+ }
4899+
c1595e42 4900+ icex = br->br_perm & AuBrAttr_ICEX;
7e9cd9fe
AM
4901+ if (!err) {
4902+ mnt_flags = au_mntflags(dst->d_sb);
4903+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
4904+ err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose);
4905+ }
c1595e42 4906+
1facf9fc 4907+ return err;
4908+}
4909+
4910+/* ---------------------------------------------------------------------- */
4911+
4912+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
4913+ char *buf, unsigned long blksize)
4914+{
4915+ int err;
4916+ size_t sz, rbytes, wbytes;
4917+ unsigned char all_zero;
4918+ char *p, *zp;
febd17d6 4919+ struct inode *h_inode;
1facf9fc 4920+ /* reduce stack usage */
4921+ struct iattr *ia;
4922+
4923+ zp = page_address(ZERO_PAGE(0));
4924+ if (unlikely(!zp))
4925+ return -ENOMEM; /* possible? */
4926+
4927+ err = 0;
4928+ all_zero = 0;
4929+ while (len) {
4930+ AuDbg("len %lld\n", len);
4931+ sz = blksize;
4932+ if (len < blksize)
4933+ sz = len;
4934+
4935+ rbytes = 0;
4936+ /* todo: signal_pending? */
4937+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
4938+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
4939+ err = rbytes;
4940+ }
4941+ if (unlikely(err < 0))
4942+ break;
4943+
4944+ all_zero = 0;
4945+ if (len >= rbytes && rbytes == blksize)
4946+ all_zero = !memcmp(buf, zp, rbytes);
4947+ if (!all_zero) {
4948+ wbytes = rbytes;
4949+ p = buf;
4950+ while (wbytes) {
4951+ size_t b;
4952+
4953+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
4954+ err = b;
4955+ /* todo: signal_pending? */
4956+ if (unlikely(err == -EAGAIN || err == -EINTR))
4957+ continue;
4958+ if (unlikely(err < 0))
4959+ break;
4960+ wbytes -= b;
4961+ p += b;
4962+ }
392086de
AM
4963+ if (unlikely(err < 0))
4964+ break;
1facf9fc 4965+ } else {
4966+ loff_t res;
4967+
4968+ AuLabel(hole);
4969+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
4970+ err = res;
4971+ if (unlikely(res < 0))
4972+ break;
4973+ }
4974+ len -= rbytes;
4975+ err = 0;
4976+ }
4977+
4978+ /* the last block may be a hole */
4979+ if (!err && all_zero) {
4980+ AuLabel(last hole);
4981+
4982+ err = 1;
2000de60 4983+ if (au_test_nfs(dst->f_path.dentry->d_sb)) {
1facf9fc 4984+ /* nfs requires this step to make last hole */
4985+ /* is this only nfs? */
4986+ do {
4987+ /* todo: signal_pending? */
4988+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
4989+ } while (err == -EAGAIN || err == -EINTR);
4990+ if (err == 1)
4991+ dst->f_pos--;
4992+ }
4993+
4994+ if (err == 1) {
4995+ ia = (void *)buf;
4996+ ia->ia_size = dst->f_pos;
4997+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
4998+ ia->ia_file = dst;
febd17d6
JR
4999+ h_inode = file_inode(dst);
5000+ inode_lock_nested(h_inode, AuLsc_I_CHILD2);
523b37e3
AM
5001+ /* no delegation since it is just created */
5002+ err = vfsub_notify_change(&dst->f_path, ia,
5003+ /*delegated*/NULL);
febd17d6 5004+ inode_unlock(h_inode);
1facf9fc 5005+ }
5006+ }
5007+
5008+ return err;
5009+}
5010+
5011+int au_copy_file(struct file *dst, struct file *src, loff_t len)
5012+{
5013+ int err;
5014+ unsigned long blksize;
5015+ unsigned char do_kfree;
5016+ char *buf;
5017+
5018+ err = -ENOMEM;
2000de60 5019+ blksize = dst->f_path.dentry->d_sb->s_blocksize;
1facf9fc 5020+ if (!blksize || PAGE_SIZE < blksize)
5021+ blksize = PAGE_SIZE;
5022+ AuDbg("blksize %lu\n", blksize);
5023+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
5024+ if (do_kfree)
5025+ buf = kmalloc(blksize, GFP_NOFS);
5026+ else
5027+ buf = (void *)__get_free_page(GFP_NOFS);
5028+ if (unlikely(!buf))
5029+ goto out;
5030+
5031+ if (len > (1 << 22))
5032+ AuDbg("copying a large file %lld\n", (long long)len);
5033+
5034+ src->f_pos = 0;
5035+ dst->f_pos = 0;
5036+ err = au_do_copy_file(dst, src, len, buf, blksize);
5037+ if (do_kfree)
1c60b727 5038+ kfree(buf);
1facf9fc 5039+ else
1c60b727 5040+ free_page((unsigned long)buf);
1facf9fc 5041+
4f0767ce 5042+out:
1facf9fc 5043+ return err;
5044+}
5045+
1c60b727
AM
5046+static int au_do_copy(struct file *dst, struct file *src, loff_t len)
5047+{
5048+ int err;
5049+ struct super_block *h_src_sb;
5050+ struct inode *h_src_inode;
5051+
5052+ h_src_inode = file_inode(src);
5053+ h_src_sb = h_src_inode->i_sb;
5054+
5055+ /* XFS acquires inode_lock */
5056+ if (!au_test_xfs(h_src_sb))
5057+ err = au_copy_file(dst, src, len);
5058+ else {
3c1bdaff 5059+ inode_unlock_shared(h_src_inode);
1c60b727 5060+ err = au_copy_file(dst, src, len);
3c1bdaff 5061+ vfsub_inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
1c60b727
AM
5062+ }
5063+
5064+ return err;
5065+}
5066+
5067+static int au_clone_or_copy(struct file *dst, struct file *src, loff_t len)
5068+{
5069+ int err;
5070+ struct super_block *h_src_sb;
5071+ struct inode *h_src_inode;
5072+
5073+ h_src_inode = file_inode(src);
5074+ h_src_sb = h_src_inode->i_sb;
5075+ if (h_src_sb != file_inode(dst)->i_sb
5076+ || !dst->f_op->clone_file_range) {
5077+ err = au_do_copy(dst, src, len);
5078+ goto out;
5079+ }
5080+
5081+ if (!au_test_nfs(h_src_sb)) {
3c1bdaff 5082+ inode_unlock_shared(h_src_inode);
1c60b727 5083+ err = vfsub_clone_file_range(src, dst, len);
3c1bdaff 5084+ vfsub_inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
1c60b727
AM
5085+ } else
5086+ err = vfsub_clone_file_range(src, dst, len);
5087+ /* older XFS has a condition in cloning */
5088+ if (unlikely(err != -EOPNOTSUPP))
5089+ goto out;
5090+
5091+ /* the backend fs on NFS may not support cloning */
5092+ err = au_do_copy(dst, src, len);
5093+
5094+out:
5095+ AuTraceErr(err);
5096+ return err;
5097+}
5098+
1facf9fc 5099+/*
5100+ * to support a sparse file which is opened with O_APPEND,
5101+ * we need to close the file.
5102+ */
c2b27bf2 5103+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 5104+{
5105+ int err, i;
5106+ enum { SRC, DST };
5107+ struct {
5108+ aufs_bindex_t bindex;
5109+ unsigned int flags;
5110+ struct dentry *dentry;
392086de 5111+ int force_wr;
1facf9fc 5112+ struct file *file;
523b37e3 5113+ void *label;
1facf9fc 5114+ } *f, file[] = {
5115+ {
c2b27bf2 5116+ .bindex = cpg->bsrc,
1facf9fc 5117+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
523b37e3 5118+ .label = &&out
1facf9fc 5119+ },
5120+ {
c2b27bf2 5121+ .bindex = cpg->bdst,
1facf9fc 5122+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 5123+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
523b37e3 5124+ .label = &&out_src
1facf9fc 5125+ }
5126+ };
521ced18 5127+ struct super_block *sb, *h_src_sb;
e2f27e51 5128+ struct inode *h_src_inode;
8cdd5066 5129+ struct task_struct *tsk = current;
1facf9fc 5130+
5131+ /* bsrc branch can be ro/rw. */
c2b27bf2 5132+ sb = cpg->dentry->d_sb;
1facf9fc 5133+ f = file;
5134+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
5135+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
5136+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 5137+ /*file*/NULL, f->force_wr);
1facf9fc 5138+ err = PTR_ERR(f->file);
5139+ if (IS_ERR(f->file))
5140+ goto *f->label;
1facf9fc 5141+ }
5142+
5143+ /* try stopping to update while we copyup */
e2f27e51 5144+ h_src_inode = d_inode(file[SRC].dentry);
521ced18
JR
5145+ h_src_sb = h_src_inode->i_sb;
5146+ if (!au_test_nfs(h_src_sb))
e2f27e51 5147+ IMustLock(h_src_inode);
1c60b727 5148+ err = au_clone_or_copy(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 5149+
8cdd5066
JR
5150+ /* i wonder if we had O_NO_DELAY_FPUT flag */
5151+ if (tsk->flags & PF_KTHREAD)
5152+ __fput_sync(file[DST].file);
5153+ else {
5154+ WARN(1, "%pD\nPlease report this warning to aufs-users ML",
5155+ file[DST].file);
5156+ fput(file[DST].file);
5157+ /*
5158+ * too bad.
5159+ * we have to call both since we don't know which place the file
5160+ * was added to.
5161+ */
5162+ task_work_run();
5163+ flush_delayed_fput();
5164+ }
1facf9fc 5165+ au_sbr_put(sb, file[DST].bindex);
523b37e3 5166+
4f0767ce 5167+out_src:
1facf9fc 5168+ fput(file[SRC].file);
5169+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 5170+out:
1facf9fc 5171+ return err;
5172+}
5173+
c2b27bf2 5174+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 5175+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5176+{
5177+ int err, rerr;
5178+ loff_t l;
86dc4139 5179+ struct path h_path;
38d290e6 5180+ struct inode *h_src_inode, *h_dst_inode;
1facf9fc 5181+
5182+ err = 0;
5527c038 5183+ h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc);
86dc4139 5184+ l = i_size_read(h_src_inode);
c2b27bf2
AM
5185+ if (cpg->len == -1 || l < cpg->len)
5186+ cpg->len = l;
5187+ if (cpg->len) {
86dc4139 5188+ /* try stopping to update while we are referencing */
3c1bdaff 5189+ vfsub_inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
c2b27bf2 5190+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 5191+
c2b27bf2
AM
5192+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5193+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139 5194+ h_src_attr->iflags = h_src_inode->i_flags;
5527c038 5195+ if (!au_test_nfs(h_src_inode->i_sb))
521ced18 5196+ err = vfsub_getattr(&h_path, &h_src_attr->st);
5527c038 5197+ else {
3c1bdaff 5198+ inode_unlock_shared(h_src_inode);
521ced18 5199+ err = vfsub_getattr(&h_path, &h_src_attr->st);
3c1bdaff 5200+ vfsub_inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD);
5527c038 5201+ }
86dc4139 5202+ if (unlikely(err)) {
3c1bdaff 5203+ inode_unlock_shared(h_src_inode);
86dc4139
AM
5204+ goto out;
5205+ }
5206+ h_src_attr->valid = 1;
e2f27e51
AM
5207+ if (!au_test_nfs(h_src_inode->i_sb)) {
5208+ err = au_cp_regular(cpg);
3c1bdaff 5209+ inode_unlock_shared(h_src_inode);
e2f27e51 5210+ } else {
3c1bdaff 5211+ inode_unlock_shared(h_src_inode);
e2f27e51
AM
5212+ err = au_cp_regular(cpg);
5213+ }
c2b27bf2 5214+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
5215+ if (!err && rerr)
5216+ err = rerr;
1facf9fc 5217+ }
38d290e6
JR
5218+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
5219+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
5527c038 5220+ h_dst_inode = d_inode(h_path.dentry);
38d290e6
JR
5221+ spin_lock(&h_dst_inode->i_lock);
5222+ h_dst_inode->i_state |= I_LINKABLE;
5223+ spin_unlock(&h_dst_inode->i_lock);
5224+ }
1facf9fc 5225+
4f0767ce 5226+out:
1facf9fc 5227+ return err;
5228+}
5229+
5230+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
5231+ struct inode *h_dir)
5232+{
5233+ int err, symlen;
5234+ mm_segment_t old_fs;
b752ccd1
AM
5235+ union {
5236+ char *k;
5237+ char __user *u;
5238+ } sym;
1facf9fc 5239+
5240+ err = -ENOMEM;
537831f9 5241+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 5242+ if (unlikely(!sym.k))
1facf9fc 5243+ goto out;
5244+
9dbd164d 5245+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 5246+ old_fs = get_fs();
5247+ set_fs(KERNEL_DS);
a2654f78 5248+ symlen = vfs_readlink(h_src, sym.u, PATH_MAX);
1facf9fc 5249+ err = symlen;
5250+ set_fs(old_fs);
5251+
5252+ if (symlen > 0) {
b752ccd1
AM
5253+ sym.k[symlen] = 0;
5254+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 5255+ }
1c60b727 5256+ free_page((unsigned long)sym.k);
1facf9fc 5257+
4f0767ce 5258+out:
1facf9fc 5259+ return err;
5260+}
5261+
8cdd5066
JR
5262+/*
5263+ * regardless 'acl' option, reset all ACL.
5264+ * All ACL will be copied up later from the original entry on the lower branch.
5265+ */
5266+static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode)
5267+{
5268+ int err;
5269+ struct dentry *h_dentry;
5270+ struct inode *h_inode;
5271+
5272+ h_dentry = h_path->dentry;
5273+ h_inode = d_inode(h_dentry);
5274+ /* forget_all_cached_acls(h_inode)); */
5275+ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS);
5276+ AuTraceErr(err);
5277+ if (err == -EOPNOTSUPP)
5278+ err = 0;
5279+ if (!err)
5280+ err = vfsub_acl_chmod(h_inode, mode);
5281+
5282+ AuTraceErr(err);
5283+ return err;
5284+}
5285+
5286+static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent,
5287+ struct inode *h_dir, struct path *h_path)
5288+{
5289+ int err;
5290+ struct inode *dir, *inode;
5291+
5292+ err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT);
5293+ AuTraceErr(err);
5294+ if (err == -EOPNOTSUPP)
5295+ err = 0;
5296+ if (unlikely(err))
5297+ goto out;
5298+
5299+ /*
5300+ * strange behaviour from the users view,
5301+ * particularry setattr case
5302+ */
5303+ dir = d_inode(dst_parent);
5afbbe0d 5304+ if (au_ibtop(dir) == cpg->bdst)
8cdd5066
JR
5305+ au_cpup_attr_nlink(dir, /*force*/1);
5306+ inode = d_inode(cpg->dentry);
5307+ au_cpup_attr_nlink(inode, /*force*/1);
5308+
5309+out:
5310+ return err;
5311+}
5312+
1facf9fc 5313+static noinline_for_stack
c2b27bf2 5314+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 5315+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5316+{
5317+ int err;
5318+ umode_t mode;
5319+ unsigned int mnt_flags;
076b876e 5320+ unsigned char isdir, isreg, force;
c2b27bf2 5321+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5322+ struct au_dtime dt;
5323+ struct path h_path;
5324+ struct dentry *h_src, *h_dst, *h_parent;
8cdd5066 5325+ struct inode *h_inode, *h_dir;
1facf9fc 5326+ struct super_block *sb;
5327+
5328+ /* bsrc branch can be ro/rw. */
c2b27bf2 5329+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038
JR
5330+ h_inode = d_inode(h_src);
5331+ AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc));
1facf9fc 5332+
5333+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
5334+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
5335+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
5336+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
5337+ AUFS_WH_PFX_LEN));
1facf9fc 5338+ h_parent = h_dst->d_parent; /* dir inode is locked */
5527c038 5339+ h_dir = d_inode(h_parent);
1facf9fc 5340+ IMustLock(h_dir);
5341+ AuDebugOn(h_parent != h_dst->d_parent);
5342+
c2b27bf2
AM
5343+ sb = cpg->dentry->d_sb;
5344+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 5345+ if (do_dt) {
5346+ h_path.dentry = h_parent;
5347+ au_dtime_store(&dt, dst_parent, &h_path);
5348+ }
5349+ h_path.dentry = h_dst;
5350+
076b876e 5351+ isreg = 0;
1facf9fc 5352+ isdir = 0;
5353+ mode = h_inode->i_mode;
5354+ switch (mode & S_IFMT) {
5355+ case S_IFREG:
076b876e 5356+ isreg = 1;
8cdd5066 5357+ err = vfsub_create(h_dir, &h_path, S_IRUSR | S_IWUSR,
b4510431 5358+ /*want_excl*/true);
1facf9fc 5359+ if (!err)
c2b27bf2 5360+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 5361+ break;
5362+ case S_IFDIR:
5363+ isdir = 1;
5364+ err = vfsub_mkdir(h_dir, &h_path, mode);
8cdd5066
JR
5365+ if (!err)
5366+ err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path);
1facf9fc 5367+ break;
5368+ case S_IFLNK:
5369+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
5370+ break;
5371+ case S_IFCHR:
5372+ case S_IFBLK:
5373+ AuDebugOn(!capable(CAP_MKNOD));
5374+ /*FALLTHROUGH*/
5375+ case S_IFIFO:
5376+ case S_IFSOCK:
5377+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
5378+ break;
5379+ default:
5380+ AuIOErr("Unknown inode type 0%o\n", mode);
5381+ err = -EIO;
5382+ }
8cdd5066
JR
5383+ if (!err)
5384+ err = au_reset_acl(h_dir, &h_path, mode);
1facf9fc 5385+
5386+ mnt_flags = au_mntflags(sb);
5387+ if (!au_opt_test(mnt_flags, UDBA_NONE)
5388+ && !isdir
5389+ && au_opt_test(mnt_flags, XINO)
38d290e6
JR
5390+ && (h_inode->i_nlink == 1
5391+ || (h_inode->i_state & I_LINKABLE))
1facf9fc 5392+ /* todo: unnecessary? */
5527c038 5393+ /* && d_inode(cpg->dentry)->i_nlink == 1 */
c2b27bf2
AM
5394+ && cpg->bdst < cpg->bsrc
5395+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
5396+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 5397+ /* ignore this error */
5398+
076b876e
AM
5399+ if (!err) {
5400+ force = 0;
5401+ if (isreg) {
5402+ force = !!cpg->len;
5403+ if (cpg->len == -1)
5404+ force = !!i_size_read(h_inode);
5405+ }
5406+ au_fhsm_wrote(sb, cpg->bdst, force);
5407+ }
5408+
1facf9fc 5409+ if (do_dt)
5410+ au_dtime_revert(&dt);
5411+ return err;
5412+}
5413+
392086de 5414+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
5415+{
5416+ int err;
392086de 5417+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 5418+ struct inode *h_dir;
392086de 5419+ aufs_bindex_t bdst;
86dc4139 5420+
392086de
AM
5421+ dentry = cpg->dentry;
5422+ bdst = cpg->bdst;
5423+ h_dentry = au_h_dptr(dentry, bdst);
5424+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
5425+ dget(h_dentry);
5426+ au_set_h_dptr(dentry, bdst, NULL);
5427+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
5428+ if (!err)
5429+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 5430+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
5431+ } else {
5432+ err = 0;
5433+ parent = dget_parent(dentry);
5434+ h_parent = au_h_dptr(parent, bdst);
5435+ dput(parent);
5436+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
5437+ if (IS_ERR(h_path->dentry))
5438+ err = PTR_ERR(h_path->dentry);
86dc4139 5439+ }
392086de
AM
5440+ if (unlikely(err))
5441+ goto out;
86dc4139 5442+
86dc4139 5443+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5527c038 5444+ h_dir = d_inode(h_parent);
86dc4139 5445+ IMustLock(h_dir);
523b37e3
AM
5446+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
5447+ /* no delegation since it is just created */
f2c43d5f
AM
5448+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL,
5449+ /*flags*/0);
86dc4139
AM
5450+ dput(h_path->dentry);
5451+
5452+out:
5453+ return err;
5454+}
5455+
1facf9fc 5456+/*
5457+ * copyup the @dentry from @bsrc to @bdst.
5458+ * the caller must set the both of lower dentries.
5459+ * @len is for truncating when it is -1 copyup the entire file.
5460+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 5461+ * basic->bsrc can be larger than basic->bdst.
f2c43d5f
AM
5462+ * aufs doesn't touch the credential so
5463+ * security_inode_copy_up{,_xattr}() are unnecrssary.
1facf9fc 5464+ */
c2b27bf2 5465+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5466+{
5467+ int err, rerr;
5afbbe0d 5468+ aufs_bindex_t old_ibtop;
1facf9fc 5469+ unsigned char isdir, plink;
1facf9fc 5470+ struct dentry *h_src, *h_dst, *h_parent;
5527c038 5471+ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode;
1facf9fc 5472+ struct super_block *sb;
86dc4139 5473+ struct au_branch *br;
c2b27bf2
AM
5474+ /* to reuduce stack size */
5475+ struct {
5476+ struct au_dtime dt;
5477+ struct path h_path;
5478+ struct au_cpup_reg_attr h_src_attr;
5479+ } *a;
1facf9fc 5480+
c2b27bf2
AM
5481+ err = -ENOMEM;
5482+ a = kmalloc(sizeof(*a), GFP_NOFS);
5483+ if (unlikely(!a))
5484+ goto out;
5485+ a->h_src_attr.valid = 0;
1facf9fc 5486+
c2b27bf2
AM
5487+ sb = cpg->dentry->d_sb;
5488+ br = au_sbr(sb, cpg->bdst);
5489+ a->h_path.mnt = au_br_mnt(br);
5490+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 5491+ h_parent = h_dst->d_parent; /* dir inode is locked */
5527c038 5492+ h_dir = d_inode(h_parent);
1facf9fc 5493+ IMustLock(h_dir);
5494+
c2b27bf2 5495+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038 5496+ inode = d_inode(cpg->dentry);
1facf9fc 5497+
5498+ if (!dst_parent)
c2b27bf2 5499+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 5500+ else
5501+ dget(dst_parent);
5502+
5503+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 5504+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 5505+ if (dst_inode) {
5506+ if (unlikely(!plink)) {
5507+ err = -EIO;
027c5e7a
AM
5508+ AuIOErr("hi%lu(i%lu) exists on b%d "
5509+ "but plink is disabled\n",
c2b27bf2
AM
5510+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
5511+ goto out_parent;
1facf9fc 5512+ }
5513+
5514+ if (dst_inode->i_nlink) {
c2b27bf2 5515+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5516+
c2b27bf2 5517+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 5518+ err = PTR_ERR(h_src);
5519+ if (IS_ERR(h_src))
c2b27bf2 5520+ goto out_parent;
5527c038 5521+ if (unlikely(d_is_negative(h_src))) {
1facf9fc 5522+ err = -EIO;
79b8bda9 5523+ AuIOErr("i%lu exists on b%d "
027c5e7a 5524+ "but not pseudo-linked\n",
79b8bda9 5525+ inode->i_ino, cpg->bdst);
1facf9fc 5526+ dput(h_src);
c2b27bf2 5527+ goto out_parent;
1facf9fc 5528+ }
5529+
5530+ if (do_dt) {
c2b27bf2
AM
5531+ a->h_path.dentry = h_parent;
5532+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 5533+ }
86dc4139 5534+
c2b27bf2 5535+ a->h_path.dentry = h_dst;
523b37e3
AM
5536+ delegated = NULL;
5537+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 5538+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 5539+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 5540+ if (do_dt)
c2b27bf2 5541+ au_dtime_revert(&a->dt);
523b37e3
AM
5542+ if (unlikely(err == -EWOULDBLOCK)) {
5543+ pr_warn("cannot retry for NFSv4 delegation"
5544+ " for an internal link\n");
5545+ iput(delegated);
5546+ }
1facf9fc 5547+ dput(h_src);
c2b27bf2 5548+ goto out_parent;
1facf9fc 5549+ } else
5550+ /* todo: cpup_wh_file? */
5551+ /* udba work */
4a4d8108 5552+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 5553+ }
5554+
86dc4139 5555+ isdir = S_ISDIR(inode->i_mode);
5afbbe0d 5556+ old_ibtop = au_ibtop(inode);
c2b27bf2 5557+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 5558+ if (unlikely(err))
86dc4139 5559+ goto out_rev;
5527c038 5560+ dst_inode = d_inode(h_dst);
febd17d6 5561+ inode_lock_nested(dst_inode, AuLsc_I_CHILD2);
86dc4139 5562+ /* todo: necessary? */
c2b27bf2 5563+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 5564+
c2b27bf2 5565+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
5566+ if (unlikely(err)) {
5567+ /* todo: necessary? */
c2b27bf2 5568+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
febd17d6 5569+ inode_unlock(dst_inode);
86dc4139
AM
5570+ goto out_rev;
5571+ }
5572+
5afbbe0d 5573+ if (cpg->bdst < old_ibtop) {
86dc4139 5574+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 5575+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 5576+ if (unlikely(err)) {
c2b27bf2
AM
5577+ /* ignore an error */
5578+ /* au_pin_hdir_relock(cpg->pin); */
febd17d6 5579+ inode_unlock(dst_inode);
86dc4139 5580+ goto out_rev;
4a4d8108 5581+ }
4a4d8108 5582+ }
5afbbe0d 5583+ au_set_ibtop(inode, cpg->bdst);
c2b27bf2 5584+ } else
5afbbe0d 5585+ au_set_ibbot(inode, cpg->bdst);
c2b27bf2 5586+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
5587+ au_hi_flags(inode, isdir));
5588+
5589+ /* todo: necessary? */
c2b27bf2 5590+ /* err = au_pin_hdir_relock(cpg->pin); */
febd17d6 5591+ inode_unlock(dst_inode);
86dc4139
AM
5592+ if (unlikely(err))
5593+ goto out_rev;
5594+
5527c038 5595+ src_inode = d_inode(h_src);
86dc4139 5596+ if (!isdir
5527c038
JR
5597+ && (src_inode->i_nlink > 1
5598+ || src_inode->i_state & I_LINKABLE)
86dc4139 5599+ && plink)
c2b27bf2 5600+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 5601+
c2b27bf2
AM
5602+ if (au_ftest_cpup(cpg->flags, RENAME)) {
5603+ a->h_path.dentry = h_dst;
392086de 5604+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
5605+ }
5606+ if (!err)
c2b27bf2 5607+ goto out_parent; /* success */
1facf9fc 5608+
5609+ /* revert */
4a4d8108 5610+out_rev:
c2b27bf2
AM
5611+ a->h_path.dentry = h_parent;
5612+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5613+ a->h_path.dentry = h_dst;
86dc4139 5614+ rerr = 0;
5527c038 5615+ if (d_is_positive(h_dst)) {
523b37e3
AM
5616+ if (!isdir) {
5617+ /* no delegation since it is just created */
5618+ rerr = vfsub_unlink(h_dir, &a->h_path,
5619+ /*delegated*/NULL, /*force*/0);
5620+ } else
c2b27bf2 5621+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 5622+ }
c2b27bf2 5623+ au_dtime_revert(&a->dt);
1facf9fc 5624+ if (rerr) {
5625+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
5626+ err = -EIO;
5627+ }
c2b27bf2 5628+out_parent:
1facf9fc 5629+ dput(dst_parent);
1c60b727 5630+ kfree(a);
c2b27bf2 5631+out:
1facf9fc 5632+ return err;
5633+}
5634+
7e9cd9fe 5635+#if 0 /* reserved */
1facf9fc 5636+struct au_cpup_single_args {
5637+ int *errp;
c2b27bf2 5638+ struct au_cp_generic *cpg;
1facf9fc 5639+ struct dentry *dst_parent;
5640+};
5641+
5642+static void au_call_cpup_single(void *args)
5643+{
5644+ struct au_cpup_single_args *a = args;
86dc4139 5645+
c2b27bf2
AM
5646+ au_pin_hdir_acquire_nest(a->cpg->pin);
5647+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
5648+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5649+}
c2b27bf2 5650+#endif
1facf9fc 5651+
53392da6
AM
5652+/*
5653+ * prevent SIGXFSZ in copy-up.
5654+ * testing CAP_MKNOD is for generic fs,
5655+ * but CAP_FSETID is for xfs only, currently.
5656+ */
86dc4139 5657+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
5658+{
5659+ int do_sio;
86dc4139
AM
5660+ struct super_block *sb;
5661+ struct inode *h_dir;
53392da6
AM
5662+
5663+ do_sio = 0;
86dc4139 5664+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
5665+ if (!au_wkq_test()
5666+ && (!au_sbi(sb)->si_plink_maint_pid
5667+ || au_plink_maint(sb, AuLock_NOPLM))) {
5668+ switch (mode & S_IFMT) {
5669+ case S_IFREG:
5670+ /* no condition about RLIMIT_FSIZE and the file size */
5671+ do_sio = 1;
5672+ break;
5673+ case S_IFCHR:
5674+ case S_IFBLK:
5675+ do_sio = !capable(CAP_MKNOD);
5676+ break;
5677+ }
5678+ if (!do_sio)
5679+ do_sio = ((mode & (S_ISUID | S_ISGID))
5680+ && !capable(CAP_FSETID));
86dc4139
AM
5681+ /* this workaround may be removed in the future */
5682+ if (!do_sio) {
5683+ h_dir = au_pinned_h_dir(pin);
5684+ do_sio = h_dir->i_mode & S_ISVTX;
5685+ }
53392da6
AM
5686+ }
5687+
5688+ return do_sio;
5689+}
5690+
7e9cd9fe 5691+#if 0 /* reserved */
c2b27bf2 5692+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5693+{
5694+ int err, wkq_err;
1facf9fc 5695+ struct dentry *h_dentry;
5696+
c2b27bf2 5697+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038 5698+ if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode))
c2b27bf2 5699+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 5700+ else {
5701+ struct au_cpup_single_args args = {
5702+ .errp = &err,
c2b27bf2
AM
5703+ .cpg = cpg,
5704+ .dst_parent = dst_parent
1facf9fc 5705+ };
5706+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
5707+ if (unlikely(wkq_err))
5708+ err = wkq_err;
5709+ }
5710+
5711+ return err;
5712+}
c2b27bf2 5713+#endif
1facf9fc 5714+
5715+/*
5716+ * copyup the @dentry from the first active lower branch to @bdst,
5717+ * using au_cpup_single().
5718+ */
c2b27bf2 5719+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5720+{
5721+ int err;
c2b27bf2
AM
5722+ unsigned int flags_orig;
5723+ struct dentry *dentry;
5724+
5725+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 5726+
c2b27bf2 5727+ dentry = cpg->dentry;
86dc4139 5728+ DiMustWriteLock(dentry);
1facf9fc 5729+
c2b27bf2 5730+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 5731+ if (!err) {
c2b27bf2
AM
5732+ flags_orig = cpg->flags;
5733+ au_fset_cpup(cpg->flags, RENAME);
5734+ err = au_cpup_single(cpg, NULL);
5735+ cpg->flags = flags_orig;
1facf9fc 5736+ if (!err)
5737+ return 0; /* success */
5738+
5739+ /* revert */
c2b27bf2 5740+ au_set_h_dptr(dentry, cpg->bdst, NULL);
5afbbe0d 5741+ au_set_dbtop(dentry, cpg->bsrc);
1facf9fc 5742+ }
5743+
5744+ return err;
5745+}
5746+
5747+struct au_cpup_simple_args {
5748+ int *errp;
c2b27bf2 5749+ struct au_cp_generic *cpg;
1facf9fc 5750+};
5751+
5752+static void au_call_cpup_simple(void *args)
5753+{
5754+ struct au_cpup_simple_args *a = args;
86dc4139 5755+
c2b27bf2
AM
5756+ au_pin_hdir_acquire_nest(a->cpg->pin);
5757+ *a->errp = au_cpup_simple(a->cpg);
5758+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5759+}
5760+
c2b27bf2 5761+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5762+{
5763+ int err, wkq_err;
c2b27bf2
AM
5764+ struct dentry *dentry, *parent;
5765+ struct file *h_file;
1facf9fc 5766+ struct inode *h_dir;
5767+
c2b27bf2
AM
5768+ dentry = cpg->dentry;
5769+ h_file = NULL;
5770+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
5771+ AuDebugOn(cpg->bsrc < 0);
392086de 5772+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
5773+ err = PTR_ERR(h_file);
5774+ if (IS_ERR(h_file))
5775+ goto out;
5776+ }
5777+
1facf9fc 5778+ parent = dget_parent(dentry);
5527c038 5779+ h_dir = au_h_iptr(d_inode(parent), cpg->bdst);
53392da6 5780+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
5527c038 5781+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
c2b27bf2 5782+ err = au_cpup_simple(cpg);
1facf9fc 5783+ else {
5784+ struct au_cpup_simple_args args = {
5785+ .errp = &err,
c2b27bf2 5786+ .cpg = cpg
1facf9fc 5787+ };
5788+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
5789+ if (unlikely(wkq_err))
5790+ err = wkq_err;
5791+ }
5792+
5793+ dput(parent);
c2b27bf2
AM
5794+ if (h_file)
5795+ au_h_open_post(dentry, cpg->bsrc, h_file);
5796+
5797+out:
1facf9fc 5798+ return err;
5799+}
5800+
c2b27bf2 5801+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 5802+{
5afbbe0d 5803+ aufs_bindex_t bsrc, bbot;
c2b27bf2 5804+ struct dentry *dentry, *h_dentry;
367653fa 5805+
c2b27bf2
AM
5806+ if (cpg->bsrc < 0) {
5807+ dentry = cpg->dentry;
5afbbe0d
AM
5808+ bbot = au_dbbot(dentry);
5809+ for (bsrc = cpg->bdst + 1; bsrc <= bbot; bsrc++) {
c2b27bf2
AM
5810+ h_dentry = au_h_dptr(dentry, bsrc);
5811+ if (h_dentry) {
5527c038 5812+ AuDebugOn(d_is_negative(h_dentry));
c2b27bf2
AM
5813+ break;
5814+ }
5815+ }
5afbbe0d 5816+ AuDebugOn(bsrc > bbot);
c2b27bf2 5817+ cpg->bsrc = bsrc;
367653fa 5818+ }
c2b27bf2
AM
5819+ AuDebugOn(cpg->bsrc <= cpg->bdst);
5820+ return au_do_sio_cpup_simple(cpg);
5821+}
367653fa 5822+
c2b27bf2
AM
5823+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
5824+{
5825+ AuDebugOn(cpg->bdst <= cpg->bsrc);
5826+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
5827+}
5828+
1facf9fc 5829+/* ---------------------------------------------------------------------- */
5830+
5831+/*
5832+ * copyup the deleted file for writing.
5833+ */
c2b27bf2
AM
5834+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
5835+ struct file *file)
1facf9fc 5836+{
5837+ int err;
c2b27bf2
AM
5838+ unsigned int flags_orig;
5839+ aufs_bindex_t bsrc_orig;
c2b27bf2 5840+ struct au_dinfo *dinfo;
5afbbe0d
AM
5841+ struct {
5842+ struct au_hdentry *hd;
5843+ struct dentry *h_dentry;
5844+ } hdst, hsrc;
1facf9fc 5845+
c2b27bf2 5846+ dinfo = au_di(cpg->dentry);
1308ab2a 5847+ AuRwMustWriteLock(&dinfo->di_rwsem);
5848+
c2b27bf2 5849+ bsrc_orig = cpg->bsrc;
5afbbe0d
AM
5850+ cpg->bsrc = dinfo->di_btop;
5851+ hdst.hd = au_hdentry(dinfo, cpg->bdst);
5852+ hdst.h_dentry = hdst.hd->hd_dentry;
5853+ hdst.hd->hd_dentry = wh_dentry;
5854+ dinfo->di_btop = cpg->bdst;
5855+
5856+ hsrc.h_dentry = NULL;
027c5e7a 5857+ if (file) {
5afbbe0d
AM
5858+ hsrc.hd = au_hdentry(dinfo, cpg->bsrc);
5859+ hsrc.h_dentry = hsrc.hd->hd_dentry;
5860+ hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry;
027c5e7a 5861+ }
c2b27bf2
AM
5862+ flags_orig = cpg->flags;
5863+ cpg->flags = !AuCpup_DTIME;
5864+ err = au_cpup_single(cpg, /*h_parent*/NULL);
5865+ cpg->flags = flags_orig;
027c5e7a
AM
5866+ if (file) {
5867+ if (!err)
5868+ err = au_reopen_nondir(file);
5afbbe0d 5869+ hsrc.hd->hd_dentry = hsrc.h_dentry;
1facf9fc 5870+ }
5afbbe0d
AM
5871+ hdst.hd->hd_dentry = hdst.h_dentry;
5872+ dinfo->di_btop = cpg->bsrc;
c2b27bf2 5873+ cpg->bsrc = bsrc_orig;
1facf9fc 5874+
5875+ return err;
5876+}
5877+
c2b27bf2 5878+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5879+{
5880+ int err;
c2b27bf2 5881+ aufs_bindex_t bdst;
1facf9fc 5882+ struct au_dtime dt;
c2b27bf2 5883+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 5884+ struct au_branch *br;
5885+ struct path h_path;
5886+
c2b27bf2
AM
5887+ dentry = cpg->dentry;
5888+ bdst = cpg->bdst;
1facf9fc 5889+ br = au_sbr(dentry->d_sb, bdst);
5890+ parent = dget_parent(dentry);
5891+ h_parent = au_h_dptr(parent, bdst);
5892+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
5893+ err = PTR_ERR(wh_dentry);
5894+ if (IS_ERR(wh_dentry))
5895+ goto out;
5896+
5897+ h_path.dentry = h_parent;
86dc4139 5898+ h_path.mnt = au_br_mnt(br);
1facf9fc 5899+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 5900+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 5901+ if (unlikely(err))
5902+ goto out_wh;
5903+
5904+ dget(wh_dentry);
5905+ h_path.dentry = wh_dentry;
2000de60 5906+ if (!d_is_dir(wh_dentry)) {
523b37e3 5907+ /* no delegation since it is just created */
5527c038 5908+ err = vfsub_unlink(d_inode(h_parent), &h_path,
523b37e3
AM
5909+ /*delegated*/NULL, /*force*/0);
5910+ } else
5527c038 5911+ err = vfsub_rmdir(d_inode(h_parent), &h_path);
1facf9fc 5912+ if (unlikely(err)) {
523b37e3
AM
5913+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
5914+ wh_dentry, err);
1facf9fc 5915+ err = -EIO;
5916+ }
5917+ au_dtime_revert(&dt);
5527c038 5918+ au_set_hi_wh(d_inode(dentry), bdst, wh_dentry);
1facf9fc 5919+
4f0767ce 5920+out_wh:
1facf9fc 5921+ dput(wh_dentry);
4f0767ce 5922+out:
1facf9fc 5923+ dput(parent);
5924+ return err;
5925+}
5926+
5927+struct au_cpup_wh_args {
5928+ int *errp;
c2b27bf2 5929+ struct au_cp_generic *cpg;
1facf9fc 5930+ struct file *file;
5931+};
5932+
5933+static void au_call_cpup_wh(void *args)
5934+{
5935+ struct au_cpup_wh_args *a = args;
86dc4139 5936+
c2b27bf2
AM
5937+ au_pin_hdir_acquire_nest(a->cpg->pin);
5938+ *a->errp = au_cpup_wh(a->cpg, a->file);
5939+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5940+}
5941+
c2b27bf2 5942+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5943+{
5944+ int err, wkq_err;
c2b27bf2 5945+ aufs_bindex_t bdst;
c1595e42 5946+ struct dentry *dentry, *parent, *h_orph, *h_parent;
86dc4139 5947+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 5948+ struct au_wbr *wbr;
c2b27bf2 5949+ struct au_pin wh_pin, *pin_orig;
1facf9fc 5950+
c2b27bf2
AM
5951+ dentry = cpg->dentry;
5952+ bdst = cpg->bdst;
1facf9fc 5953+ parent = dget_parent(dentry);
5527c038 5954+ dir = d_inode(parent);
1facf9fc 5955+ h_orph = NULL;
5956+ h_parent = NULL;
5957+ h_dir = au_igrab(au_h_iptr(dir, bdst));
5958+ h_tmpdir = h_dir;
c2b27bf2 5959+ pin_orig = NULL;
1facf9fc 5960+ if (!h_dir->i_nlink) {
5961+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
5962+ h_orph = wbr->wbr_orph;
5963+
5964+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 5965+ au_set_h_dptr(parent, bdst, dget(h_orph));
5527c038 5966+ h_tmpdir = d_inode(h_orph);
1facf9fc 5967+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
5968+
febd17d6 5969+ inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3);
4a4d8108 5970+ /* todo: au_h_open_pre()? */
86dc4139 5971+
c2b27bf2 5972+ pin_orig = cpg->pin;
86dc4139 5973+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
5974+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
5975+ cpg->pin = &wh_pin;
1facf9fc 5976+ }
5977+
53392da6 5978+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
5527c038 5979+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
c2b27bf2 5980+ err = au_cpup_wh(cpg, file);
1facf9fc 5981+ else {
5982+ struct au_cpup_wh_args args = {
5983+ .errp = &err,
c2b27bf2
AM
5984+ .cpg = cpg,
5985+ .file = file
1facf9fc 5986+ };
5987+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
5988+ if (unlikely(wkq_err))
5989+ err = wkq_err;
5990+ }
5991+
5992+ if (h_orph) {
febd17d6 5993+ inode_unlock(h_tmpdir);
4a4d8108 5994+ /* todo: au_h_open_post()? */
1facf9fc 5995+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 5996+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
5997+ AuDebugOn(!pin_orig);
5998+ cpg->pin = pin_orig;
1facf9fc 5999+ }
6000+ iput(h_dir);
6001+ dput(parent);
6002+
6003+ return err;
6004+}
6005+
6006+/* ---------------------------------------------------------------------- */
6007+
6008+/*
6009+ * generic routine for both of copy-up and copy-down.
6010+ */
6011+/* cf. revalidate function in file.c */
6012+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
6013+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6014+ struct au_pin *pin,
1facf9fc 6015+ struct dentry *h_parent, void *arg),
6016+ void *arg)
6017+{
6018+ int err;
6019+ struct au_pin pin;
5527c038 6020+ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry;
1facf9fc 6021+
6022+ err = 0;
6023+ parent = dget_parent(dentry);
6024+ if (IS_ROOT(parent))
6025+ goto out;
6026+
6027+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
6028+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
6029+
6030+ /* do not use au_dpage */
6031+ real_parent = parent;
6032+ while (1) {
6033+ dput(parent);
6034+ parent = dget_parent(dentry);
6035+ h_parent = au_h_dptr(parent, bdst);
6036+ if (h_parent)
6037+ goto out; /* success */
6038+
6039+ /* find top dir which is necessary to cpup */
6040+ do {
6041+ d = parent;
6042+ dput(parent);
6043+ parent = dget_parent(d);
6044+ di_read_lock_parent3(parent, !AuLock_IR);
6045+ h_parent = au_h_dptr(parent, bdst);
6046+ di_read_unlock(parent, !AuLock_IR);
6047+ } while (!h_parent);
6048+
6049+ if (d != real_parent)
6050+ di_write_lock_child3(d);
6051+
6052+ /* somebody else might create while we were sleeping */
5527c038
JR
6053+ h_dentry = au_h_dptr(d, bdst);
6054+ if (!h_dentry || d_is_negative(h_dentry)) {
6055+ if (h_dentry)
5afbbe0d 6056+ au_update_dbtop(d);
1facf9fc 6057+
6058+ au_pin_set_dentry(&pin, d);
6059+ err = au_do_pin(&pin);
6060+ if (!err) {
86dc4139 6061+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 6062+ au_unpin(&pin);
6063+ }
6064+ }
6065+
6066+ if (d != real_parent)
6067+ di_write_unlock(d);
6068+ if (unlikely(err))
6069+ break;
6070+ }
6071+
4f0767ce 6072+out:
1facf9fc 6073+ dput(parent);
6074+ return err;
6075+}
6076+
6077+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6078+ struct au_pin *pin,
2000de60 6079+ struct dentry *h_parent __maybe_unused,
1facf9fc 6080+ void *arg __maybe_unused)
6081+{
c2b27bf2
AM
6082+ struct au_cp_generic cpg = {
6083+ .dentry = dentry,
6084+ .bdst = bdst,
6085+ .bsrc = -1,
6086+ .len = 0,
6087+ .pin = pin,
6088+ .flags = AuCpup_DTIME
6089+ };
6090+ return au_sio_cpup_simple(&cpg);
1facf9fc 6091+}
6092+
6093+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
6094+{
6095+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
6096+}
6097+
6098+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
6099+{
6100+ int err;
6101+ struct dentry *parent;
6102+ struct inode *dir;
6103+
6104+ parent = dget_parent(dentry);
5527c038 6105+ dir = d_inode(parent);
1facf9fc 6106+ err = 0;
6107+ if (au_h_iptr(dir, bdst))
6108+ goto out;
6109+
6110+ di_read_unlock(parent, AuLock_IR);
6111+ di_write_lock_parent(parent);
6112+ /* someone else might change our inode while we were sleeping */
6113+ if (!au_h_iptr(dir, bdst))
6114+ err = au_cpup_dirs(dentry, bdst);
6115+ di_downgrade_lock(parent, AuLock_IR);
6116+
4f0767ce 6117+out:
1facf9fc 6118+ dput(parent);
6119+ return err;
6120+}
7f207e10
AM
6121diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
6122--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 6123+++ linux/fs/aufs/cpup.h 2017-07-29 12:14:25.899708630 +0200
523b37e3 6124@@ -0,0 +1,94 @@
1facf9fc 6125+/*
a2654f78 6126+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 6127+ *
6128+ * This program, aufs is free software; you can redistribute it and/or modify
6129+ * it under the terms of the GNU General Public License as published by
6130+ * the Free Software Foundation; either version 2 of the License, or
6131+ * (at your option) any later version.
dece6358
AM
6132+ *
6133+ * This program is distributed in the hope that it will be useful,
6134+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6135+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6136+ * GNU General Public License for more details.
6137+ *
6138+ * You should have received a copy of the GNU General Public License
523b37e3 6139+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6140+ */
6141+
6142+/*
6143+ * copy-up/down functions
6144+ */
6145+
6146+#ifndef __AUFS_CPUP_H__
6147+#define __AUFS_CPUP_H__
6148+
6149+#ifdef __KERNEL__
6150+
dece6358 6151+#include <linux/path.h>
1facf9fc 6152+
dece6358
AM
6153+struct inode;
6154+struct file;
86dc4139 6155+struct au_pin;
dece6358 6156+
86dc4139 6157+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 6158+void au_cpup_attr_timesizes(struct inode *inode);
6159+void au_cpup_attr_nlink(struct inode *inode, int force);
6160+void au_cpup_attr_changeable(struct inode *inode);
6161+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
6162+void au_cpup_attr_all(struct inode *inode, int force);
6163+
6164+/* ---------------------------------------------------------------------- */
6165+
c2b27bf2
AM
6166+struct au_cp_generic {
6167+ struct dentry *dentry;
6168+ aufs_bindex_t bdst, bsrc;
6169+ loff_t len;
6170+ struct au_pin *pin;
6171+ unsigned int flags;
6172+};
6173+
1facf9fc 6174+/* cpup flags */
392086de
AM
6175+#define AuCpup_DTIME 1 /* do dtime_store/revert */
6176+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
6177+ for link(2) */
6178+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
6179+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
6180+ cpup */
6181+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
6182+ existing entry */
6183+#define AuCpup_RWDST (1 << 5) /* force write target even if
6184+ the branch is marked as RO */
c2b27bf2 6185+
1facf9fc 6186+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
6187+#define au_fset_cpup(flags, name) \
6188+ do { (flags) |= AuCpup_##name; } while (0)
6189+#define au_fclr_cpup(flags, name) \
6190+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 6191+
6192+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
6193+int au_sio_cpup_simple(struct au_cp_generic *cpg);
6194+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
6195+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 6196+
6197+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
6198+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 6199+ struct au_pin *pin,
1facf9fc 6200+ struct dentry *h_parent, void *arg),
6201+ void *arg);
6202+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
6203+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
6204+
6205+/* ---------------------------------------------------------------------- */
6206+
6207+/* keep timestamps when copyup */
6208+struct au_dtime {
6209+ struct dentry *dt_dentry;
6210+ struct path dt_h_path;
6211+ struct timespec dt_atime, dt_mtime;
6212+};
6213+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
6214+ struct path *h_path);
6215+void au_dtime_revert(struct au_dtime *dt);
6216+
6217+#endif /* __KERNEL__ */
6218+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
6219diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
6220--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 6221+++ linux/fs/aufs/dbgaufs.c 2017-07-29 12:14:25.899708630 +0200
e2f27e51 6222@@ -0,0 +1,438 @@
1facf9fc 6223+/*
a2654f78 6224+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 6225+ *
6226+ * This program, aufs is free software; you can redistribute it and/or modify
6227+ * it under the terms of the GNU General Public License as published by
6228+ * the Free Software Foundation; either version 2 of the License, or
6229+ * (at your option) any later version.
dece6358
AM
6230+ *
6231+ * This program is distributed in the hope that it will be useful,
6232+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6233+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6234+ * GNU General Public License for more details.
6235+ *
6236+ * You should have received a copy of the GNU General Public License
523b37e3 6237+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6238+ */
6239+
6240+/*
6241+ * debugfs interface
6242+ */
6243+
6244+#include <linux/debugfs.h>
6245+#include "aufs.h"
6246+
6247+#ifndef CONFIG_SYSFS
6248+#error DEBUG_FS depends upon SYSFS
6249+#endif
6250+
6251+static struct dentry *dbgaufs;
6252+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
6253+
6254+/* 20 is max digits length of ulong 64 */
6255+struct dbgaufs_arg {
6256+ int n;
6257+ char a[20 * 4];
6258+};
6259+
6260+/*
6261+ * common function for all XINO files
6262+ */
6263+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
6264+ struct file *file)
6265+{
1c60b727 6266+ kfree(file->private_data);
1facf9fc 6267+ return 0;
6268+}
6269+
6270+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
6271+{
6272+ int err;
6273+ struct kstat st;
6274+ struct dbgaufs_arg *p;
6275+
6276+ err = -ENOMEM;
6277+ p = kmalloc(sizeof(*p), GFP_NOFS);
6278+ if (unlikely(!p))
6279+ goto out;
6280+
6281+ err = 0;
6282+ p->n = 0;
6283+ file->private_data = p;
6284+ if (!xf)
6285+ goto out;
6286+
521ced18 6287+ err = vfsub_getattr(&xf->f_path, &st);
1facf9fc 6288+ if (!err) {
6289+ if (do_fcnt)
6290+ p->n = snprintf
521ced18 6291+ (p->a, sizeof(p->a), "%ld, %llux%u %lld\n",
1facf9fc 6292+ (long)file_count(xf), st.blocks, st.blksize,
6293+ (long long)st.size);
6294+ else
521ced18 6295+ p->n = snprintf(p->a, sizeof(p->a), "%llux%u %lld\n",
1facf9fc 6296+ st.blocks, st.blksize,
6297+ (long long)st.size);
6298+ AuDebugOn(p->n >= sizeof(p->a));
6299+ } else {
6300+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
6301+ err = 0;
6302+ }
6303+
4f0767ce 6304+out:
1facf9fc 6305+ return err;
6306+
6307+}
6308+
6309+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
6310+ size_t count, loff_t *ppos)
6311+{
6312+ struct dbgaufs_arg *p;
6313+
6314+ p = file->private_data;
6315+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6316+}
6317+
6318+/* ---------------------------------------------------------------------- */
6319+
86dc4139
AM
6320+struct dbgaufs_plink_arg {
6321+ int n;
6322+ char a[];
6323+};
6324+
6325+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
6326+ struct file *file)
6327+{
1c60b727 6328+ free_page((unsigned long)file->private_data);
86dc4139
AM
6329+ return 0;
6330+}
6331+
6332+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
6333+{
6334+ int err, i, limit;
6335+ unsigned long n, sum;
6336+ struct dbgaufs_plink_arg *p;
6337+ struct au_sbinfo *sbinfo;
6338+ struct super_block *sb;
6339+ struct au_sphlhead *sphl;
6340+
6341+ err = -ENOMEM;
6342+ p = (void *)get_zeroed_page(GFP_NOFS);
6343+ if (unlikely(!p))
6344+ goto out;
6345+
6346+ err = -EFBIG;
6347+ sbinfo = inode->i_private;
6348+ sb = sbinfo->si_sb;
6349+ si_noflush_read_lock(sb);
6350+ if (au_opt_test(au_mntflags(sb), PLINK)) {
6351+ limit = PAGE_SIZE - sizeof(p->n);
6352+
6353+ /* the number of buckets */
6354+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
6355+ p->n += n;
6356+ limit -= n;
6357+
6358+ sum = 0;
6359+ for (i = 0, sphl = sbinfo->si_plink;
6360+ i < AuPlink_NHASH;
6361+ i++, sphl++) {
6362+ n = au_sphl_count(sphl);
6363+ sum += n;
6364+
6365+ n = snprintf(p->a + p->n, limit, "%lu ", n);
6366+ p->n += n;
6367+ limit -= n;
6368+ if (unlikely(limit <= 0))
6369+ goto out_free;
6370+ }
6371+ p->a[p->n - 1] = '\n';
6372+
6373+ /* the sum of plinks */
6374+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
6375+ p->n += n;
6376+ limit -= n;
6377+ if (unlikely(limit <= 0))
6378+ goto out_free;
6379+ } else {
6380+#define str "1\n0\n0\n"
6381+ p->n = sizeof(str) - 1;
6382+ strcpy(p->a, str);
6383+#undef str
6384+ }
6385+ si_read_unlock(sb);
6386+
6387+ err = 0;
6388+ file->private_data = p;
6389+ goto out; /* success */
6390+
6391+out_free:
1c60b727 6392+ free_page((unsigned long)p);
86dc4139
AM
6393+out:
6394+ return err;
6395+}
6396+
6397+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
6398+ size_t count, loff_t *ppos)
6399+{
6400+ struct dbgaufs_plink_arg *p;
6401+
6402+ p = file->private_data;
6403+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6404+}
6405+
6406+static const struct file_operations dbgaufs_plink_fop = {
6407+ .owner = THIS_MODULE,
6408+ .open = dbgaufs_plink_open,
6409+ .release = dbgaufs_plink_release,
6410+ .read = dbgaufs_plink_read
6411+};
6412+
6413+/* ---------------------------------------------------------------------- */
6414+
1facf9fc 6415+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
6416+{
6417+ int err;
6418+ struct au_sbinfo *sbinfo;
6419+ struct super_block *sb;
6420+
6421+ sbinfo = inode->i_private;
6422+ sb = sbinfo->si_sb;
6423+ si_noflush_read_lock(sb);
6424+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
6425+ si_read_unlock(sb);
6426+ return err;
6427+}
6428+
6429+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 6430+ .owner = THIS_MODULE,
1facf9fc 6431+ .open = dbgaufs_xib_open,
6432+ .release = dbgaufs_xi_release,
6433+ .read = dbgaufs_xi_read
6434+};
6435+
6436+/* ---------------------------------------------------------------------- */
6437+
6438+#define DbgaufsXi_PREFIX "xi"
6439+
6440+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
6441+{
6442+ int err;
6443+ long l;
6444+ struct au_sbinfo *sbinfo;
6445+ struct super_block *sb;
6446+ struct file *xf;
6447+ struct qstr *name;
6448+
6449+ err = -ENOENT;
6450+ xf = NULL;
2000de60 6451+ name = &file->f_path.dentry->d_name;
1facf9fc 6452+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
6453+ || memcmp(name->name, DbgaufsXi_PREFIX,
6454+ sizeof(DbgaufsXi_PREFIX) - 1)))
6455+ goto out;
9dbd164d 6456+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 6457+ if (unlikely(err))
6458+ goto out;
6459+
6460+ sbinfo = inode->i_private;
6461+ sb = sbinfo->si_sb;
6462+ si_noflush_read_lock(sb);
5afbbe0d 6463+ if (l <= au_sbbot(sb)) {
1facf9fc 6464+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
6465+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
6466+ } else
6467+ err = -ENOENT;
6468+ si_read_unlock(sb);
6469+
4f0767ce 6470+out:
1facf9fc 6471+ return err;
6472+}
6473+
6474+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 6475+ .owner = THIS_MODULE,
1facf9fc 6476+ .open = dbgaufs_xino_open,
6477+ .release = dbgaufs_xi_release,
6478+ .read = dbgaufs_xi_read
6479+};
6480+
6481+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
6482+{
5afbbe0d 6483+ aufs_bindex_t bbot;
1facf9fc 6484+ struct au_branch *br;
6485+ struct au_xino_file *xi;
6486+
6487+ if (!au_sbi(sb)->si_dbgaufs)
6488+ return;
6489+
5afbbe0d
AM
6490+ bbot = au_sbbot(sb);
6491+ for (; bindex <= bbot; bindex++) {
1facf9fc 6492+ br = au_sbr(sb, bindex);
6493+ xi = &br->br_xino;
e2f27e51
AM
6494+ /* debugfs acquires the parent i_mutex */
6495+ lockdep_off();
c06a8ce3 6496+ debugfs_remove(xi->xi_dbgaufs);
e2f27e51 6497+ lockdep_on();
c06a8ce3 6498+ xi->xi_dbgaufs = NULL;
1facf9fc 6499+ }
6500+}
6501+
6502+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
6503+{
6504+ struct au_sbinfo *sbinfo;
6505+ struct dentry *parent;
6506+ struct au_branch *br;
6507+ struct au_xino_file *xi;
5afbbe0d 6508+ aufs_bindex_t bbot;
1facf9fc 6509+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
6510+
6511+ sbinfo = au_sbi(sb);
6512+ parent = sbinfo->si_dbgaufs;
6513+ if (!parent)
6514+ return;
6515+
5afbbe0d
AM
6516+ bbot = au_sbbot(sb);
6517+ for (; bindex <= bbot; bindex++) {
1facf9fc 6518+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
6519+ br = au_sbr(sb, bindex);
6520+ xi = &br->br_xino;
6521+ AuDebugOn(xi->xi_dbgaufs);
f0c0a007
AM
6522+ /* debugfs acquires the parent i_mutex */
6523+ lockdep_off();
1facf9fc 6524+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
6525+ sbinfo, &dbgaufs_xino_fop);
f0c0a007 6526+ lockdep_on();
1facf9fc 6527+ /* ignore an error */
6528+ if (unlikely(!xi->xi_dbgaufs))
6529+ AuWarn1("failed %s under debugfs\n", name);
6530+ }
6531+}
6532+
6533+/* ---------------------------------------------------------------------- */
6534+
6535+#ifdef CONFIG_AUFS_EXPORT
6536+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
6537+{
6538+ int err;
6539+ struct au_sbinfo *sbinfo;
6540+ struct super_block *sb;
6541+
6542+ sbinfo = inode->i_private;
6543+ sb = sbinfo->si_sb;
6544+ si_noflush_read_lock(sb);
6545+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
6546+ si_read_unlock(sb);
6547+ return err;
6548+}
6549+
6550+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 6551+ .owner = THIS_MODULE,
1facf9fc 6552+ .open = dbgaufs_xigen_open,
6553+ .release = dbgaufs_xi_release,
6554+ .read = dbgaufs_xi_read
6555+};
6556+
6557+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6558+{
6559+ int err;
6560+
dece6358 6561+ /*
c1595e42 6562+ * This function is a dynamic '__init' function actually,
dece6358
AM
6563+ * so the tiny check for si_rwsem is unnecessary.
6564+ */
6565+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6566+
1facf9fc 6567+ err = -EIO;
6568+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
6569+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6570+ &dbgaufs_xigen_fop);
6571+ if (sbinfo->si_dbgaufs_xigen)
6572+ err = 0;
6573+
6574+ return err;
6575+}
6576+#else
6577+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6578+{
6579+ return 0;
6580+}
6581+#endif /* CONFIG_AUFS_EXPORT */
6582+
6583+/* ---------------------------------------------------------------------- */
6584+
6585+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
6586+{
dece6358 6587+ /*
7e9cd9fe 6588+ * This function is a dynamic '__fin' function actually,
dece6358
AM
6589+ * so the tiny check for si_rwsem is unnecessary.
6590+ */
6591+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6592+
1facf9fc 6593+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
6594+ sbinfo->si_dbgaufs = NULL;
6595+ kobject_put(&sbinfo->si_kobj);
6596+}
6597+
6598+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
6599+{
6600+ int err;
6601+ char name[SysaufsSiNameLen];
6602+
dece6358 6603+ /*
c1595e42 6604+ * This function is a dynamic '__init' function actually,
dece6358
AM
6605+ * so the tiny check for si_rwsem is unnecessary.
6606+ */
6607+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6608+
1facf9fc 6609+ err = -ENOENT;
6610+ if (!dbgaufs) {
6611+ AuErr1("/debug/aufs is uninitialized\n");
6612+ goto out;
6613+ }
6614+
6615+ err = -EIO;
6616+ sysaufs_name(sbinfo, name);
6617+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
6618+ if (unlikely(!sbinfo->si_dbgaufs))
6619+ goto out;
6620+ kobject_get(&sbinfo->si_kobj);
6621+
6622+ sbinfo->si_dbgaufs_xib = debugfs_create_file
6623+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6624+ &dbgaufs_xib_fop);
6625+ if (unlikely(!sbinfo->si_dbgaufs_xib))
6626+ goto out_dir;
6627+
86dc4139
AM
6628+ sbinfo->si_dbgaufs_plink = debugfs_create_file
6629+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6630+ &dbgaufs_plink_fop);
6631+ if (unlikely(!sbinfo->si_dbgaufs_plink))
6632+ goto out_dir;
6633+
1facf9fc 6634+ err = dbgaufs_xigen_init(sbinfo);
6635+ if (!err)
6636+ goto out; /* success */
6637+
4f0767ce 6638+out_dir:
1facf9fc 6639+ dbgaufs_si_fin(sbinfo);
4f0767ce 6640+out:
1facf9fc 6641+ return err;
6642+}
6643+
6644+/* ---------------------------------------------------------------------- */
6645+
6646+void dbgaufs_fin(void)
6647+{
6648+ debugfs_remove(dbgaufs);
6649+}
6650+
6651+int __init dbgaufs_init(void)
6652+{
6653+ int err;
6654+
6655+ err = -EIO;
6656+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
6657+ if (dbgaufs)
6658+ err = 0;
6659+ return err;
6660+}
7f207e10
AM
6661diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
6662--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 6663+++ linux/fs/aufs/dbgaufs.h 2017-07-29 12:14:25.899708630 +0200
523b37e3 6664@@ -0,0 +1,48 @@
1facf9fc 6665+/*
a2654f78 6666+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 6667+ *
6668+ * This program, aufs is free software; you can redistribute it and/or modify
6669+ * it under the terms of the GNU General Public License as published by
6670+ * the Free Software Foundation; either version 2 of the License, or
6671+ * (at your option) any later version.
dece6358
AM
6672+ *
6673+ * This program is distributed in the hope that it will be useful,
6674+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6675+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6676+ * GNU General Public License for more details.
6677+ *
6678+ * You should have received a copy of the GNU General Public License
523b37e3 6679+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6680+ */
6681+
6682+/*
6683+ * debugfs interface
6684+ */
6685+
6686+#ifndef __DBGAUFS_H__
6687+#define __DBGAUFS_H__
6688+
6689+#ifdef __KERNEL__
6690+
dece6358 6691+struct super_block;
1facf9fc 6692+struct au_sbinfo;
dece6358 6693+
1facf9fc 6694+#ifdef CONFIG_DEBUG_FS
6695+/* dbgaufs.c */
6696+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
6697+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
6698+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
6699+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
6700+void dbgaufs_fin(void);
6701+int __init dbgaufs_init(void);
1facf9fc 6702+#else
4a4d8108
AM
6703+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
6704+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
6705+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
6706+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
6707+AuStubVoid(dbgaufs_fin, void)
6708+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 6709+#endif /* CONFIG_DEBUG_FS */
6710+
6711+#endif /* __KERNEL__ */
6712+#endif /* __DBGAUFS_H__ */
7f207e10
AM
6713diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
6714--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 6715+++ linux/fs/aufs/dcsub.c 2017-07-29 12:14:25.899708630 +0200
e2f27e51 6716@@ -0,0 +1,225 @@
1facf9fc 6717+/*
a2654f78 6718+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 6719+ *
6720+ * This program, aufs is free software; you can redistribute it and/or modify
6721+ * it under the terms of the GNU General Public License as published by
6722+ * the Free Software Foundation; either version 2 of the License, or
6723+ * (at your option) any later version.
dece6358
AM
6724+ *
6725+ * This program is distributed in the hope that it will be useful,
6726+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6727+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6728+ * GNU General Public License for more details.
6729+ *
6730+ * You should have received a copy of the GNU General Public License
523b37e3 6731+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6732+ */
6733+
6734+/*
6735+ * sub-routines for dentry cache
6736+ */
6737+
6738+#include "aufs.h"
6739+
6740+static void au_dpage_free(struct au_dpage *dpage)
6741+{
6742+ int i;
6743+ struct dentry **p;
6744+
6745+ p = dpage->dentries;
6746+ for (i = 0; i < dpage->ndentry; i++)
6747+ dput(*p++);
1c60b727 6748+ free_page((unsigned long)dpage->dentries);
1facf9fc 6749+}
6750+
6751+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
6752+{
6753+ int err;
6754+ void *p;
6755+
6756+ err = -ENOMEM;
6757+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
6758+ if (unlikely(!dpages->dpages))
6759+ goto out;
6760+
6761+ p = (void *)__get_free_page(gfp);
6762+ if (unlikely(!p))
6763+ goto out_dpages;
6764+
6765+ dpages->dpages[0].ndentry = 0;
6766+ dpages->dpages[0].dentries = p;
6767+ dpages->ndpage = 1;
6768+ return 0; /* success */
6769+
4f0767ce 6770+out_dpages:
1c60b727 6771+ kfree(dpages->dpages);
4f0767ce 6772+out:
1facf9fc 6773+ return err;
6774+}
6775+
6776+void au_dpages_free(struct au_dcsub_pages *dpages)
6777+{
6778+ int i;
6779+ struct au_dpage *p;
6780+
6781+ p = dpages->dpages;
6782+ for (i = 0; i < dpages->ndpage; i++)
6783+ au_dpage_free(p++);
1c60b727 6784+ kfree(dpages->dpages);
1facf9fc 6785+}
6786+
6787+static int au_dpages_append(struct au_dcsub_pages *dpages,
6788+ struct dentry *dentry, gfp_t gfp)
6789+{
6790+ int err, sz;
6791+ struct au_dpage *dpage;
6792+ void *p;
6793+
6794+ dpage = dpages->dpages + dpages->ndpage - 1;
6795+ sz = PAGE_SIZE / sizeof(dentry);
6796+ if (unlikely(dpage->ndentry >= sz)) {
6797+ AuLabel(new dpage);
6798+ err = -ENOMEM;
6799+ sz = dpages->ndpage * sizeof(*dpages->dpages);
6800+ p = au_kzrealloc(dpages->dpages, sz,
e2f27e51
AM
6801+ sz + sizeof(*dpages->dpages), gfp,
6802+ /*may_shrink*/0);
1facf9fc 6803+ if (unlikely(!p))
6804+ goto out;
6805+
6806+ dpages->dpages = p;
6807+ dpage = dpages->dpages + dpages->ndpage;
6808+ p = (void *)__get_free_page(gfp);
6809+ if (unlikely(!p))
6810+ goto out;
6811+
6812+ dpage->ndentry = 0;
6813+ dpage->dentries = p;
6814+ dpages->ndpage++;
6815+ }
6816+
c1595e42 6817+ AuDebugOn(au_dcount(dentry) <= 0);
027c5e7a 6818+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 6819+ return 0; /* success */
6820+
4f0767ce 6821+out:
1facf9fc 6822+ return err;
6823+}
6824+
c1595e42
JR
6825+/* todo: BAD approach */
6826+/* copied from linux/fs/dcache.c */
6827+enum d_walk_ret {
6828+ D_WALK_CONTINUE,
6829+ D_WALK_QUIT,
6830+ D_WALK_NORETRY,
6831+ D_WALK_SKIP,
6832+};
6833+
6834+extern void d_walk(struct dentry *parent, void *data,
6835+ enum d_walk_ret (*enter)(void *, struct dentry *),
6836+ void (*finish)(void *));
6837+
6838+struct ac_dpages_arg {
1facf9fc 6839+ int err;
c1595e42
JR
6840+ struct au_dcsub_pages *dpages;
6841+ struct super_block *sb;
6842+ au_dpages_test test;
6843+ void *arg;
6844+};
1facf9fc 6845+
c1595e42
JR
6846+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry)
6847+{
6848+ enum d_walk_ret ret;
6849+ struct ac_dpages_arg *arg = _arg;
1facf9fc 6850+
c1595e42
JR
6851+ ret = D_WALK_CONTINUE;
6852+ if (dentry->d_sb == arg->sb
6853+ && !IS_ROOT(dentry)
6854+ && au_dcount(dentry) > 0
6855+ && au_di(dentry)
6856+ && (!arg->test || arg->test(dentry, arg->arg))) {
6857+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC);
6858+ if (unlikely(arg->err))
6859+ ret = D_WALK_QUIT;
1facf9fc 6860+ }
6861+
c1595e42
JR
6862+ return ret;
6863+}
027c5e7a 6864+
c1595e42
JR
6865+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6866+ au_dpages_test test, void *arg)
6867+{
6868+ struct ac_dpages_arg args = {
6869+ .err = 0,
6870+ .dpages = dpages,
6871+ .sb = root->d_sb,
6872+ .test = test,
6873+ .arg = arg
6874+ };
027c5e7a 6875+
c1595e42
JR
6876+ d_walk(root, &args, au_call_dpages_append, NULL);
6877+
6878+ return args.err;
1facf9fc 6879+}
6880+
6881+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6882+ int do_include, au_dpages_test test, void *arg)
6883+{
6884+ int err;
6885+
6886+ err = 0;
027c5e7a
AM
6887+ write_seqlock(&rename_lock);
6888+ spin_lock(&dentry->d_lock);
6889+ if (do_include
c1595e42 6890+ && au_dcount(dentry) > 0
027c5e7a 6891+ && (!test || test(dentry, arg)))
1facf9fc 6892+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6893+ spin_unlock(&dentry->d_lock);
6894+ if (unlikely(err))
6895+ goto out;
6896+
6897+ /*
523b37e3 6898+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
6899+ * mount
6900+ */
1facf9fc 6901+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
6902+ dentry = dentry->d_parent; /* rename_lock is locked */
6903+ spin_lock(&dentry->d_lock);
c1595e42 6904+ if (au_dcount(dentry) > 0
027c5e7a 6905+ && (!test || test(dentry, arg)))
1facf9fc 6906+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6907+ spin_unlock(&dentry->d_lock);
6908+ if (unlikely(err))
6909+ break;
1facf9fc 6910+ }
6911+
4f0767ce 6912+out:
027c5e7a 6913+ write_sequnlock(&rename_lock);
1facf9fc 6914+ return err;
6915+}
6916+
027c5e7a
AM
6917+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
6918+{
6919+ return au_di(dentry) && dentry->d_sb == arg;
6920+}
6921+
6922+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6923+ struct dentry *dentry, int do_include)
6924+{
6925+ return au_dcsub_pages_rev(dpages, dentry, do_include,
6926+ au_dcsub_dpages_aufs, dentry->d_sb);
6927+}
6928+
4a4d8108 6929+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 6930+{
4a4d8108
AM
6931+ struct path path[2] = {
6932+ {
6933+ .dentry = d1
6934+ },
6935+ {
6936+ .dentry = d2
6937+ }
6938+ };
1facf9fc 6939+
4a4d8108 6940+ return path_is_under(path + 0, path + 1);
1facf9fc 6941+}
7f207e10
AM
6942diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
6943--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 6944+++ linux/fs/aufs/dcsub.h 2017-07-29 12:14:25.899708630 +0200
5527c038 6945@@ -0,0 +1,136 @@
1facf9fc 6946+/*
a2654f78 6947+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 6948+ *
6949+ * This program, aufs is free software; you can redistribute it and/or modify
6950+ * it under the terms of the GNU General Public License as published by
6951+ * the Free Software Foundation; either version 2 of the License, or
6952+ * (at your option) any later version.
dece6358
AM
6953+ *
6954+ * This program is distributed in the hope that it will be useful,
6955+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6956+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6957+ * GNU General Public License for more details.
6958+ *
6959+ * You should have received a copy of the GNU General Public License
523b37e3 6960+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6961+ */
6962+
6963+/*
6964+ * sub-routines for dentry cache
6965+ */
6966+
6967+#ifndef __AUFS_DCSUB_H__
6968+#define __AUFS_DCSUB_H__
6969+
6970+#ifdef __KERNEL__
6971+
7f207e10 6972+#include <linux/dcache.h>
027c5e7a 6973+#include <linux/fs.h>
dece6358 6974+
1facf9fc 6975+struct au_dpage {
6976+ int ndentry;
6977+ struct dentry **dentries;
6978+};
6979+
6980+struct au_dcsub_pages {
6981+ int ndpage;
6982+ struct au_dpage *dpages;
6983+};
6984+
6985+/* ---------------------------------------------------------------------- */
6986+
7f207e10 6987+/* dcsub.c */
1facf9fc 6988+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
6989+void au_dpages_free(struct au_dcsub_pages *dpages);
6990+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
6991+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6992+ au_dpages_test test, void *arg);
6993+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6994+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
6995+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6996+ struct dentry *dentry, int do_include);
4a4d8108 6997+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 6998+
7f207e10
AM
6999+/* ---------------------------------------------------------------------- */
7000+
523b37e3
AM
7001+/*
7002+ * todo: in linux-3.13, several similar (but faster) helpers are added to
7003+ * include/linux/dcache.h. Try them (in the future).
7004+ */
7005+
027c5e7a
AM
7006+static inline int au_d_hashed_positive(struct dentry *d)
7007+{
7008+ int err;
5527c038 7009+ struct inode *inode = d_inode(d);
076b876e 7010+
027c5e7a 7011+ err = 0;
5527c038
JR
7012+ if (unlikely(d_unhashed(d)
7013+ || d_is_negative(d)
7014+ || !inode->i_nlink))
027c5e7a
AM
7015+ err = -ENOENT;
7016+ return err;
7017+}
7018+
38d290e6
JR
7019+static inline int au_d_linkable(struct dentry *d)
7020+{
7021+ int err;
5527c038 7022+ struct inode *inode = d_inode(d);
076b876e 7023+
38d290e6
JR
7024+ err = au_d_hashed_positive(d);
7025+ if (err
5527c038 7026+ && d_is_positive(d)
38d290e6
JR
7027+ && (inode->i_state & I_LINKABLE))
7028+ err = 0;
7029+ return err;
7030+}
7031+
027c5e7a
AM
7032+static inline int au_d_alive(struct dentry *d)
7033+{
7034+ int err;
7035+ struct inode *inode;
076b876e 7036+
027c5e7a
AM
7037+ err = 0;
7038+ if (!IS_ROOT(d))
7039+ err = au_d_hashed_positive(d);
7040+ else {
5527c038
JR
7041+ inode = d_inode(d);
7042+ if (unlikely(d_unlinked(d)
7043+ || d_is_negative(d)
7044+ || !inode->i_nlink))
027c5e7a
AM
7045+ err = -ENOENT;
7046+ }
7047+ return err;
7048+}
7049+
7050+static inline int au_alive_dir(struct dentry *d)
7f207e10 7051+{
027c5e7a 7052+ int err;
076b876e 7053+
027c5e7a 7054+ err = au_d_alive(d);
5527c038 7055+ if (unlikely(err || IS_DEADDIR(d_inode(d))))
027c5e7a
AM
7056+ err = -ENOENT;
7057+ return err;
7f207e10
AM
7058+}
7059+
38d290e6
JR
7060+static inline int au_qstreq(struct qstr *a, struct qstr *b)
7061+{
7062+ return a->len == b->len
7063+ && !memcmp(a->name, b->name, a->len);
7064+}
7065+
7e9cd9fe
AM
7066+/*
7067+ * by the commit
7068+ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without
7069+ * taking d_lock
7070+ * the type of d_lockref.count became int, but the inlined function d_count()
7071+ * still returns unsigned int.
7072+ * I don't know why. Maybe it is for every d_count() users?
7073+ * Anyway au_dcount() lives on.
7074+ */
c1595e42
JR
7075+static inline int au_dcount(struct dentry *d)
7076+{
7077+ return (int)d_count(d);
7078+}
7079+
1facf9fc 7080+#endif /* __KERNEL__ */
7081+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
7082diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
7083--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 7084+++ linux/fs/aufs/debug.c 2017-07-29 12:14:25.899708630 +0200
f0c0a007 7085@@ -0,0 +1,440 @@
1facf9fc 7086+/*
a2654f78 7087+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 7088+ *
7089+ * This program, aufs is free software; you can redistribute it and/or modify
7090+ * it under the terms of the GNU General Public License as published by
7091+ * the Free Software Foundation; either version 2 of the License, or
7092+ * (at your option) any later version.
dece6358
AM
7093+ *
7094+ * This program is distributed in the hope that it will be useful,
7095+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7096+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7097+ * GNU General Public License for more details.
7098+ *
7099+ * You should have received a copy of the GNU General Public License
523b37e3 7100+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7101+ */
7102+
7103+/*
7104+ * debug print functions
7105+ */
7106+
7107+#include "aufs.h"
7108+
392086de
AM
7109+/* Returns 0, or -errno. arg is in kp->arg. */
7110+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
7111+{
7112+ int err, n;
7113+
7114+ err = kstrtoint(val, 0, &n);
7115+ if (!err) {
7116+ if (n > 0)
7117+ au_debug_on();
7118+ else
7119+ au_debug_off();
7120+ }
7121+ return err;
7122+}
7123+
7124+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
7125+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
7126+{
7127+ atomic_t *a;
7128+
7129+ a = kp->arg;
7130+ return sprintf(buffer, "%d", atomic_read(a));
7131+}
7132+
7133+static struct kernel_param_ops param_ops_atomic_t = {
7134+ .set = param_atomic_t_set,
7135+ .get = param_atomic_t_get
7136+ /* void (*free)(void *arg) */
7137+};
7138+
7139+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 7140+MODULE_PARM_DESC(debug, "debug print");
392086de 7141+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
1facf9fc 7142+
c1595e42 7143+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */
1facf9fc 7144+char *au_plevel = KERN_DEBUG;
e49829fe
JR
7145+#define dpri(fmt, ...) do { \
7146+ if ((au_plevel \
7147+ && strcmp(au_plevel, KERN_DEBUG)) \
7148+ || au_debug_test()) \
7149+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 7150+} while (0)
7151+
7152+/* ---------------------------------------------------------------------- */
7153+
7154+void au_dpri_whlist(struct au_nhash *whlist)
7155+{
7156+ unsigned long ul, n;
7157+ struct hlist_head *head;
c06a8ce3 7158+ struct au_vdir_wh *pos;
1facf9fc 7159+
7160+ n = whlist->nh_num;
7161+ head = whlist->nh_head;
7162+ for (ul = 0; ul < n; ul++) {
c06a8ce3 7163+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 7164+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
7165+ pos->wh_bindex,
7166+ pos->wh_str.len, pos->wh_str.name,
7167+ pos->wh_str.len);
1facf9fc 7168+ head++;
7169+ }
7170+}
7171+
7172+void au_dpri_vdir(struct au_vdir *vdir)
7173+{
7174+ unsigned long ul;
7175+ union au_vdir_deblk_p p;
7176+ unsigned char *o;
7177+
7178+ if (!vdir || IS_ERR(vdir)) {
7179+ dpri("err %ld\n", PTR_ERR(vdir));
7180+ return;
7181+ }
7182+
7183+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
7184+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
7185+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
7186+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
7187+ p.deblk = vdir->vd_deblk[ul];
7188+ o = p.deblk;
7189+ dpri("[%lu]: %p\n", ul, o);
7190+ }
7191+}
7192+
53392da6 7193+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 7194+ struct dentry *wh)
7195+{
7196+ char *n = NULL;
7197+ int l = 0;
7198+
7199+ if (!inode || IS_ERR(inode)) {
7200+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
7201+ return -1;
7202+ }
7203+
c2b27bf2 7204+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 7205+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
7206+ && sizeof(inode->i_blocks) != sizeof(u64));
7207+ if (wh) {
7208+ n = (void *)wh->d_name.name;
7209+ l = wh->d_name.len;
7210+ }
7211+
53392da6
AM
7212+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
7213+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
7214+ bindex, inode,
1facf9fc 7215+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
7216+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
7217+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 7218+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 7219+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
7220+ inode->i_state, inode->i_flags, inode->i_version,
7221+ inode->i_generation,
1facf9fc 7222+ l ? ", wh " : "", l, n);
7223+ return 0;
7224+}
7225+
7226+void au_dpri_inode(struct inode *inode)
7227+{
7228+ struct au_iinfo *iinfo;
5afbbe0d 7229+ struct au_hinode *hi;
1facf9fc 7230+ aufs_bindex_t bindex;
53392da6 7231+ int err, hn;
1facf9fc 7232+
53392da6 7233+ err = do_pri_inode(-1, inode, -1, NULL);
5afbbe0d 7234+ if (err || !au_test_aufs(inode->i_sb) || au_is_bad_inode(inode))
1facf9fc 7235+ return;
7236+
7237+ iinfo = au_ii(inode);
5afbbe0d
AM
7238+ dpri("i-1: btop %d, bbot %d, gen %d\n",
7239+ iinfo->ii_btop, iinfo->ii_bbot, au_iigen(inode, NULL));
7240+ if (iinfo->ii_btop < 0)
1facf9fc 7241+ return;
53392da6 7242+ hn = 0;
5afbbe0d
AM
7243+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; bindex++) {
7244+ hi = au_hinode(iinfo, bindex);
7245+ hn = !!au_hn(hi);
7246+ do_pri_inode(bindex, hi->hi_inode, hn, hi->hi_whdentry);
53392da6 7247+ }
1facf9fc 7248+}
7249+
2cbb1c4b
JR
7250+void au_dpri_dalias(struct inode *inode)
7251+{
7252+ struct dentry *d;
7253+
7254+ spin_lock(&inode->i_lock);
c1595e42 7255+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias)
2cbb1c4b
JR
7256+ au_dpri_dentry(d);
7257+ spin_unlock(&inode->i_lock);
7258+}
7259+
1facf9fc 7260+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
7261+{
7262+ struct dentry *wh = NULL;
53392da6 7263+ int hn;
5afbbe0d 7264+ struct inode *inode;
076b876e 7265+ struct au_iinfo *iinfo;
5afbbe0d 7266+ struct au_hinode *hi;
1facf9fc 7267+
7268+ if (!dentry || IS_ERR(dentry)) {
7269+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
7270+ return -1;
7271+ }
7272+ /* do not call dget_parent() here */
027c5e7a 7273+ /* note: access d_xxx without d_lock */
523b37e3
AM
7274+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
7275+ bindex, dentry, dentry,
1facf9fc 7276+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
c1595e42 7277+ au_dcount(dentry), dentry->d_flags,
523b37e3 7278+ d_unhashed(dentry) ? "un" : "");
53392da6 7279+ hn = -1;
5afbbe0d
AM
7280+ inode = NULL;
7281+ if (d_is_positive(dentry))
7282+ inode = d_inode(dentry);
7283+ if (inode
7284+ && au_test_aufs(dentry->d_sb)
7285+ && bindex >= 0
7286+ && !au_is_bad_inode(inode)) {
7287+ iinfo = au_ii(inode);
7288+ hi = au_hinode(iinfo, bindex);
7289+ hn = !!au_hn(hi);
7290+ wh = hi->hi_whdentry;
7291+ }
7292+ do_pri_inode(bindex, inode, hn, wh);
1facf9fc 7293+ return 0;
7294+}
7295+
7296+void au_dpri_dentry(struct dentry *dentry)
7297+{
7298+ struct au_dinfo *dinfo;
7299+ aufs_bindex_t bindex;
7300+ int err;
7301+
7302+ err = do_pri_dentry(-1, dentry);
7303+ if (err || !au_test_aufs(dentry->d_sb))
7304+ return;
7305+
7306+ dinfo = au_di(dentry);
7307+ if (!dinfo)
7308+ return;
5afbbe0d
AM
7309+ dpri("d-1: btop %d, bbot %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
7310+ dinfo->di_btop, dinfo->di_bbot,
38d290e6
JR
7311+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
7312+ dinfo->di_tmpfile);
5afbbe0d 7313+ if (dinfo->di_btop < 0)
1facf9fc 7314+ return;
5afbbe0d
AM
7315+ for (bindex = dinfo->di_btop; bindex <= dinfo->di_bbot; bindex++)
7316+ do_pri_dentry(bindex, au_hdentry(dinfo, bindex)->hd_dentry);
1facf9fc 7317+}
7318+
7319+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
7320+{
7321+ char a[32];
7322+
7323+ if (!file || IS_ERR(file)) {
7324+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
7325+ return -1;
7326+ }
7327+ a[0] = 0;
7328+ if (bindex < 0
b912730e 7329+ && !IS_ERR_OR_NULL(file->f_path.dentry)
2000de60 7330+ && au_test_aufs(file->f_path.dentry->d_sb)
1facf9fc 7331+ && au_fi(file))
e49829fe 7332+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 7333+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 7334+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 7335+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 7336+ file->f_version, file->f_pos, a);
b912730e 7337+ if (!IS_ERR_OR_NULL(file->f_path.dentry))
2000de60 7338+ do_pri_dentry(bindex, file->f_path.dentry);
1facf9fc 7339+ return 0;
7340+}
7341+
7342+void au_dpri_file(struct file *file)
7343+{
7344+ struct au_finfo *finfo;
4a4d8108
AM
7345+ struct au_fidir *fidir;
7346+ struct au_hfile *hfile;
1facf9fc 7347+ aufs_bindex_t bindex;
7348+ int err;
7349+
7350+ err = do_pri_file(-1, file);
2000de60 7351+ if (err
b912730e 7352+ || IS_ERR_OR_NULL(file->f_path.dentry)
2000de60 7353+ || !au_test_aufs(file->f_path.dentry->d_sb))
1facf9fc 7354+ return;
7355+
7356+ finfo = au_fi(file);
7357+ if (!finfo)
7358+ return;
4a4d8108 7359+ if (finfo->fi_btop < 0)
1facf9fc 7360+ return;
4a4d8108
AM
7361+ fidir = finfo->fi_hdir;
7362+ if (!fidir)
7363+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
7364+ else
e49829fe
JR
7365+ for (bindex = finfo->fi_btop;
7366+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
7367+ bindex++) {
7368+ hfile = fidir->fd_hfile + bindex;
7369+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
7370+ }
1facf9fc 7371+}
7372+
7373+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
7374+{
7375+ struct vfsmount *mnt;
7376+ struct super_block *sb;
7377+
7378+ if (!br || IS_ERR(br))
7379+ goto out;
86dc4139 7380+ mnt = au_br_mnt(br);
1facf9fc 7381+ if (!mnt || IS_ERR(mnt))
7382+ goto out;
7383+ sb = mnt->mnt_sb;
7384+ if (!sb || IS_ERR(sb))
7385+ goto out;
7386+
5afbbe0d 7387+ dpri("s%d: {perm 0x%x, id %d, cnt %lld, wbr %p}, "
b752ccd1 7388+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 7389+ "xino %d\n",
5afbbe0d 7390+ bindex, br->br_perm, br->br_id, au_br_count(br),
1e00d052 7391+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 7392+ sb->s_flags, sb->s_count,
1facf9fc 7393+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
7394+ return 0;
7395+
4f0767ce 7396+out:
1facf9fc 7397+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
7398+ return -1;
7399+}
7400+
7401+void au_dpri_sb(struct super_block *sb)
7402+{
7403+ struct au_sbinfo *sbinfo;
7404+ aufs_bindex_t bindex;
7405+ int err;
7406+ /* to reuduce stack size */
7407+ struct {
7408+ struct vfsmount mnt;
7409+ struct au_branch fake;
7410+ } *a;
7411+
7412+ /* this function can be called from magic sysrq */
7413+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
7414+ if (unlikely(!a)) {
7415+ dpri("no memory\n");
7416+ return;
7417+ }
7418+
7419+ a->mnt.mnt_sb = sb;
86dc4139 7420+ a->fake.br_path.mnt = &a->mnt;
5afbbe0d 7421+ au_br_count_init(&a->fake);
1facf9fc 7422+ err = do_pri_br(-1, &a->fake);
5afbbe0d 7423+ au_br_count_fin(&a->fake);
1c60b727 7424+ kfree(a);
1facf9fc 7425+ dpri("dev 0x%x\n", sb->s_dev);
7426+ if (err || !au_test_aufs(sb))
7427+ return;
7428+
7429+ sbinfo = au_sbi(sb);
7430+ if (!sbinfo)
7431+ return;
f0c0a007
AM
7432+ dpri("nw %d, gen %u, kobj %d\n",
7433+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
521ced18 7434+ kref_read(&sbinfo->si_kobj.kref));
5afbbe0d 7435+ for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++)
1facf9fc 7436+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
7437+}
7438+
7439+/* ---------------------------------------------------------------------- */
7440+
027c5e7a
AM
7441+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
7442+{
5527c038 7443+ struct inode *h_inode, *inode = d_inode(dentry);
027c5e7a 7444+ struct dentry *h_dentry;
5afbbe0d 7445+ aufs_bindex_t bindex, bbot, bi;
027c5e7a
AM
7446+
7447+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
7448+ return;
7449+
5afbbe0d
AM
7450+ bbot = au_dbbot(dentry);
7451+ bi = au_ibbot(inode);
7452+ if (bi < bbot)
7453+ bbot = bi;
7454+ bindex = au_dbtop(dentry);
7455+ bi = au_ibtop(inode);
027c5e7a
AM
7456+ if (bi > bindex)
7457+ bindex = bi;
7458+
5afbbe0d 7459+ for (; bindex <= bbot; bindex++) {
027c5e7a
AM
7460+ h_dentry = au_h_dptr(dentry, bindex);
7461+ if (!h_dentry)
7462+ continue;
7463+ h_inode = au_h_iptr(inode, bindex);
5527c038 7464+ if (unlikely(h_inode != d_inode(h_dentry))) {
392086de 7465+ au_debug_on();
027c5e7a
AM
7466+ AuDbg("b%d, %s:%d\n", bindex, func, line);
7467+ AuDbgDentry(dentry);
7468+ AuDbgInode(inode);
392086de 7469+ au_debug_off();
027c5e7a
AM
7470+ BUG();
7471+ }
7472+ }
7473+}
7474+
1facf9fc 7475+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
7476+{
7477+ int err, i, j;
7478+ struct au_dcsub_pages dpages;
7479+ struct au_dpage *dpage;
7480+ struct dentry **dentries;
7481+
7482+ err = au_dpages_init(&dpages, GFP_NOFS);
7483+ AuDebugOn(err);
027c5e7a 7484+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 7485+ AuDebugOn(err);
7486+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
7487+ dpage = dpages.dpages + i;
7488+ dentries = dpage->dentries;
7489+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 7490+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 7491+ }
7492+ au_dpages_free(&dpages);
7493+}
7494+
1facf9fc 7495+void au_dbg_verify_kthread(void)
7496+{
53392da6 7497+ if (au_wkq_test()) {
1facf9fc 7498+ au_dbg_blocked();
1e00d052
AM
7499+ /*
7500+ * It may be recursive, but udba=notify between two aufs mounts,
7501+ * where a single ro branch is shared, is not a problem.
7502+ */
7503+ /* WARN_ON(1); */
1facf9fc 7504+ }
7505+}
7506+
7507+/* ---------------------------------------------------------------------- */
7508+
1facf9fc 7509+int __init au_debug_init(void)
7510+{
7511+ aufs_bindex_t bindex;
7512+ struct au_vdir_destr destr;
7513+
7514+ bindex = -1;
7515+ AuDebugOn(bindex >= 0);
7516+
7517+ destr.len = -1;
7518+ AuDebugOn(destr.len < NAME_MAX);
7519+
7520+#ifdef CONFIG_4KSTACKS
0c3ec466 7521+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 7522+#endif
7523+
1facf9fc 7524+ return 0;
7525+}
7f207e10
AM
7526diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
7527--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 7528+++ linux/fs/aufs/debug.h 2017-07-29 12:14:25.899708630 +0200
5527c038 7529@@ -0,0 +1,225 @@
1facf9fc 7530+/*
a2654f78 7531+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 7532+ *
7533+ * This program, aufs is free software; you can redistribute it and/or modify
7534+ * it under the terms of the GNU General Public License as published by
7535+ * the Free Software Foundation; either version 2 of the License, or
7536+ * (at your option) any later version.
dece6358
AM
7537+ *
7538+ * This program is distributed in the hope that it will be useful,
7539+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7540+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7541+ * GNU General Public License for more details.
7542+ *
7543+ * You should have received a copy of the GNU General Public License
523b37e3 7544+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7545+ */
7546+
7547+/*
7548+ * debug print functions
7549+ */
7550+
7551+#ifndef __AUFS_DEBUG_H__
7552+#define __AUFS_DEBUG_H__
7553+
7554+#ifdef __KERNEL__
7555+
392086de 7556+#include <linux/atomic.h>
4a4d8108
AM
7557+#include <linux/module.h>
7558+#include <linux/kallsyms.h>
1facf9fc 7559+#include <linux/sysrq.h>
4a4d8108 7560+
1facf9fc 7561+#ifdef CONFIG_AUFS_DEBUG
7562+#define AuDebugOn(a) BUG_ON(a)
7563+
7564+/* module parameter */
392086de
AM
7565+extern atomic_t aufs_debug;
7566+static inline void au_debug_on(void)
1facf9fc 7567+{
392086de
AM
7568+ atomic_inc(&aufs_debug);
7569+}
7570+static inline void au_debug_off(void)
7571+{
7572+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 7573+}
7574+
7575+static inline int au_debug_test(void)
7576+{
392086de 7577+ return atomic_read(&aufs_debug) > 0;
1facf9fc 7578+}
7579+#else
7580+#define AuDebugOn(a) do {} while (0)
392086de
AM
7581+AuStubVoid(au_debug_on, void)
7582+AuStubVoid(au_debug_off, void)
4a4d8108 7583+AuStubInt0(au_debug_test, void)
1facf9fc 7584+#endif /* CONFIG_AUFS_DEBUG */
7585+
392086de
AM
7586+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
7587+
1facf9fc 7588+/* ---------------------------------------------------------------------- */
7589+
7590+/* debug print */
7591+
4a4d8108 7592+#define AuDbg(fmt, ...) do { \
1facf9fc 7593+ if (au_debug_test()) \
4a4d8108 7594+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 7595+} while (0)
4a4d8108
AM
7596+#define AuLabel(l) AuDbg(#l "\n")
7597+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
7598+#define AuWarn1(fmt, ...) do { \
1facf9fc 7599+ static unsigned char _c; \
7600+ if (!_c++) \
0c3ec466 7601+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 7602+} while (0)
7603+
4a4d8108 7604+#define AuErr1(fmt, ...) do { \
1facf9fc 7605+ static unsigned char _c; \
7606+ if (!_c++) \
4a4d8108 7607+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 7608+} while (0)
7609+
4a4d8108 7610+#define AuIOErr1(fmt, ...) do { \
1facf9fc 7611+ static unsigned char _c; \
7612+ if (!_c++) \
4a4d8108 7613+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 7614+} while (0)
7615+
7616+#define AuUnsupportMsg "This operation is not supported." \
7617+ " Please report this application to aufs-users ML."
4a4d8108
AM
7618+#define AuUnsupport(fmt, ...) do { \
7619+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 7620+ dump_stack(); \
7621+} while (0)
7622+
7623+#define AuTraceErr(e) do { \
7624+ if (unlikely((e) < 0)) \
7625+ AuDbg("err %d\n", (int)(e)); \
7626+} while (0)
7627+
7628+#define AuTraceErrPtr(p) do { \
7629+ if (IS_ERR(p)) \
7630+ AuDbg("err %ld\n", PTR_ERR(p)); \
7631+} while (0)
7632+
7633+/* dirty macros for debug print, use with "%.*s" and caution */
7634+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 7635+
7636+/* ---------------------------------------------------------------------- */
7637+
dece6358 7638+struct dentry;
1facf9fc 7639+#ifdef CONFIG_AUFS_DEBUG
c1595e42 7640+extern struct mutex au_dbg_mtx;
1facf9fc 7641+extern char *au_plevel;
7642+struct au_nhash;
7643+void au_dpri_whlist(struct au_nhash *whlist);
7644+struct au_vdir;
7645+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 7646+struct inode;
1facf9fc 7647+void au_dpri_inode(struct inode *inode);
2cbb1c4b 7648+void au_dpri_dalias(struct inode *inode);
1facf9fc 7649+void au_dpri_dentry(struct dentry *dentry);
dece6358 7650+struct file;
1facf9fc 7651+void au_dpri_file(struct file *filp);
dece6358 7652+struct super_block;
1facf9fc 7653+void au_dpri_sb(struct super_block *sb);
7654+
027c5e7a
AM
7655+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
7656+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 7657+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 7658+void au_dbg_verify_kthread(void);
7659+
7660+int __init au_debug_init(void);
7e9cd9fe 7661+
1facf9fc 7662+#define AuDbgWhlist(w) do { \
c1595e42 7663+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7664+ AuDbg(#w "\n"); \
7665+ au_dpri_whlist(w); \
c1595e42 7666+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7667+} while (0)
7668+
7669+#define AuDbgVdir(v) do { \
c1595e42 7670+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7671+ AuDbg(#v "\n"); \
7672+ au_dpri_vdir(v); \
c1595e42 7673+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7674+} while (0)
7675+
7676+#define AuDbgInode(i) do { \
c1595e42 7677+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7678+ AuDbg(#i "\n"); \
7679+ au_dpri_inode(i); \
c1595e42 7680+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7681+} while (0)
7682+
2cbb1c4b 7683+#define AuDbgDAlias(i) do { \
c1595e42 7684+ mutex_lock(&au_dbg_mtx); \
2cbb1c4b
JR
7685+ AuDbg(#i "\n"); \
7686+ au_dpri_dalias(i); \
c1595e42 7687+ mutex_unlock(&au_dbg_mtx); \
2cbb1c4b
JR
7688+} while (0)
7689+
1facf9fc 7690+#define AuDbgDentry(d) do { \
c1595e42 7691+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7692+ AuDbg(#d "\n"); \
7693+ au_dpri_dentry(d); \
c1595e42 7694+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7695+} while (0)
7696+
7697+#define AuDbgFile(f) do { \
c1595e42 7698+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7699+ AuDbg(#f "\n"); \
7700+ au_dpri_file(f); \
c1595e42 7701+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7702+} while (0)
7703+
7704+#define AuDbgSb(sb) do { \
c1595e42 7705+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7706+ AuDbg(#sb "\n"); \
7707+ au_dpri_sb(sb); \
c1595e42 7708+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7709+} while (0)
7710+
4a4d8108
AM
7711+#define AuDbgSym(addr) do { \
7712+ char sym[KSYM_SYMBOL_LEN]; \
7713+ sprint_symbol(sym, (unsigned long)addr); \
7714+ AuDbg("%s\n", sym); \
7715+} while (0)
1facf9fc 7716+#else
027c5e7a 7717+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
7718+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
7719+AuStubVoid(au_dbg_verify_kthread, void)
7720+AuStubInt0(__init au_debug_init, void)
1facf9fc 7721+
1facf9fc 7722+#define AuDbgWhlist(w) do {} while (0)
7723+#define AuDbgVdir(v) do {} while (0)
7724+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 7725+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 7726+#define AuDbgDentry(d) do {} while (0)
7727+#define AuDbgFile(f) do {} while (0)
7728+#define AuDbgSb(sb) do {} while (0)
4a4d8108 7729+#define AuDbgSym(addr) do {} while (0)
1facf9fc 7730+#endif /* CONFIG_AUFS_DEBUG */
7731+
7732+/* ---------------------------------------------------------------------- */
7733+
7734+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
7735+int __init au_sysrq_init(void);
7736+void au_sysrq_fin(void);
7737+
7738+#ifdef CONFIG_HW_CONSOLE
7739+#define au_dbg_blocked() do { \
7740+ WARN_ON(1); \
0c5527e5 7741+ handle_sysrq('w'); \
1facf9fc 7742+} while (0)
7743+#else
4a4d8108 7744+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7745+#endif
7746+
7747+#else
4a4d8108
AM
7748+AuStubInt0(__init au_sysrq_init, void)
7749+AuStubVoid(au_sysrq_fin, void)
7750+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7751+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
7752+
7753+#endif /* __KERNEL__ */
7754+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
7755diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
7756--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
3c1bdaff 7757+++ linux/fs/aufs/dentry.c 2017-09-05 10:42:11.055421928 +0200
e2f27e51 7758@@ -0,0 +1,1130 @@
1facf9fc 7759+/*
a2654f78 7760+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 7761+ *
7762+ * This program, aufs is free software; you can redistribute it and/or modify
7763+ * it under the terms of the GNU General Public License as published by
7764+ * the Free Software Foundation; either version 2 of the License, or
7765+ * (at your option) any later version.
dece6358
AM
7766+ *
7767+ * This program is distributed in the hope that it will be useful,
7768+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7769+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7770+ * GNU General Public License for more details.
7771+ *
7772+ * You should have received a copy of the GNU General Public License
523b37e3 7773+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7774+ */
7775+
7776+/*
7777+ * lookup and dentry operations
7778+ */
7779+
dece6358 7780+#include <linux/namei.h>
1facf9fc 7781+#include "aufs.h"
7782+
1facf9fc 7783+struct au_do_lookup_args {
7784+ unsigned int flags;
7785+ mode_t type;
1facf9fc 7786+};
7787+
7788+/*
7789+ * returns positive/negative dentry, NULL or an error.
7790+ * NULL means whiteout-ed or not-found.
7791+ */
7792+static struct dentry*
7793+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
7794+ aufs_bindex_t bindex, struct qstr *wh_name,
7795+ struct au_do_lookup_args *args)
7796+{
7797+ struct dentry *h_dentry;
2000de60 7798+ struct inode *h_inode;
1facf9fc 7799+ struct au_branch *br;
7800+ int wh_found, opq;
7801+ unsigned char wh_able;
7802+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
076b876e
AM
7803+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
7804+ IGNORE_PERM);
1facf9fc 7805+
1facf9fc 7806+ wh_found = 0;
7807+ br = au_sbr(dentry->d_sb, bindex);
7808+ wh_able = !!au_br_whable(br->br_perm);
7809+ if (wh_able)
e2f27e51 7810+ wh_found = au_wh_test(h_parent, wh_name, ignore_perm);
1facf9fc 7811+ h_dentry = ERR_PTR(wh_found);
7812+ if (!wh_found)
7813+ goto real_lookup;
7814+ if (unlikely(wh_found < 0))
7815+ goto out;
7816+
7817+ /* We found a whiteout */
5afbbe0d 7818+ /* au_set_dbbot(dentry, bindex); */
1facf9fc 7819+ au_set_dbwh(dentry, bindex);
7820+ if (!allow_neg)
7821+ return NULL; /* success */
7822+
4f0767ce 7823+real_lookup:
076b876e
AM
7824+ if (!ignore_perm)
7825+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
7826+ else
7827+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
2000de60
JR
7828+ if (IS_ERR(h_dentry)) {
7829+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG
7830+ && !allow_neg)
7831+ h_dentry = NULL;
1facf9fc 7832+ goto out;
2000de60 7833+ }
1facf9fc 7834+
5527c038
JR
7835+ h_inode = d_inode(h_dentry);
7836+ if (d_is_negative(h_dentry)) {
1facf9fc 7837+ if (!allow_neg)
7838+ goto out_neg;
7839+ } else if (wh_found
7840+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
7841+ goto out_neg;
7842+
5afbbe0d
AM
7843+ if (au_dbbot(dentry) <= bindex)
7844+ au_set_dbbot(dentry, bindex);
7845+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
7846+ au_set_dbtop(dentry, bindex);
1facf9fc 7847+ au_set_h_dptr(dentry, bindex, h_dentry);
7848+
2000de60
JR
7849+ if (!d_is_dir(h_dentry)
7850+ || !wh_able
5527c038 7851+ || (d_really_is_positive(dentry) && !d_is_dir(dentry)))
1facf9fc 7852+ goto out; /* success */
7853+
3c1bdaff 7854+ vfsub_inode_lock_shared_nested(h_inode, AuLsc_I_CHILD);
076b876e 7855+ opq = au_diropq_test(h_dentry);
3c1bdaff 7856+ inode_unlock_shared(h_inode);
1facf9fc 7857+ if (opq > 0)
7858+ au_set_dbdiropq(dentry, bindex);
7859+ else if (unlikely(opq < 0)) {
7860+ au_set_h_dptr(dentry, bindex, NULL);
7861+ h_dentry = ERR_PTR(opq);
7862+ }
7863+ goto out;
7864+
4f0767ce 7865+out_neg:
1facf9fc 7866+ dput(h_dentry);
7867+ h_dentry = NULL;
4f0767ce 7868+out:
1facf9fc 7869+ return h_dentry;
7870+}
7871+
dece6358
AM
7872+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
7873+{
7874+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
7875+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
7876+ return -EPERM;
7877+ return 0;
7878+}
7879+
1facf9fc 7880+/*
7881+ * returns the number of lower positive dentries,
7882+ * otherwise an error.
7883+ * can be called at unlinking with @type is zero.
7884+ */
5afbbe0d
AM
7885+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
7886+ unsigned int flags)
1facf9fc 7887+{
7888+ int npositive, err;
7889+ aufs_bindex_t bindex, btail, bdiropq;
076b876e 7890+ unsigned char isdir, dirperm1;
1facf9fc 7891+ struct qstr whname;
7892+ struct au_do_lookup_args args = {
5afbbe0d 7893+ .flags = flags
1facf9fc 7894+ };
7895+ const struct qstr *name = &dentry->d_name;
7896+ struct dentry *parent;
076b876e 7897+ struct super_block *sb;
1facf9fc 7898+
076b876e
AM
7899+ sb = dentry->d_sb;
7900+ err = au_test_shwh(sb, name);
dece6358 7901+ if (unlikely(err))
1facf9fc 7902+ goto out;
7903+
7904+ err = au_wh_name_alloc(&whname, name);
7905+ if (unlikely(err))
7906+ goto out;
7907+
2000de60 7908+ isdir = !!d_is_dir(dentry);
076b876e 7909+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
1facf9fc 7910+
7911+ npositive = 0;
4a4d8108 7912+ parent = dget_parent(dentry);
1facf9fc 7913+ btail = au_dbtaildir(parent);
5afbbe0d 7914+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 7915+ struct dentry *h_parent, *h_dentry;
7916+ struct inode *h_inode, *h_dir;
7917+
7918+ h_dentry = au_h_dptr(dentry, bindex);
7919+ if (h_dentry) {
5527c038 7920+ if (d_is_positive(h_dentry))
1facf9fc 7921+ npositive++;
5afbbe0d 7922+ break;
1facf9fc 7923+ }
7924+ h_parent = au_h_dptr(parent, bindex);
2000de60 7925+ if (!h_parent || !d_is_dir(h_parent))
1facf9fc 7926+ continue;
7927+
5527c038 7928+ h_dir = d_inode(h_parent);
3c1bdaff 7929+ vfsub_inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
1facf9fc 7930+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
7931+ &args);
3c1bdaff 7932+ inode_unlock_shared(h_dir);
1facf9fc 7933+ err = PTR_ERR(h_dentry);
7934+ if (IS_ERR(h_dentry))
4a4d8108 7935+ goto out_parent;
2000de60
JR
7936+ if (h_dentry)
7937+ au_fclr_lkup(args.flags, ALLOW_NEG);
076b876e
AM
7938+ if (dirperm1)
7939+ au_fset_lkup(args.flags, IGNORE_PERM);
1facf9fc 7940+
79b8bda9 7941+ if (au_dbwh(dentry) == bindex)
1facf9fc 7942+ break;
7943+ if (!h_dentry)
7944+ continue;
5527c038 7945+ if (d_is_negative(h_dentry))
1facf9fc 7946+ continue;
5527c038 7947+ h_inode = d_inode(h_dentry);
1facf9fc 7948+ npositive++;
7949+ if (!args.type)
7950+ args.type = h_inode->i_mode & S_IFMT;
7951+ if (args.type != S_IFDIR)
7952+ break;
7953+ else if (isdir) {
7954+ /* the type of lower may be different */
7955+ bdiropq = au_dbdiropq(dentry);
7956+ if (bdiropq >= 0 && bdiropq <= bindex)
7957+ break;
7958+ }
7959+ }
7960+
7961+ if (npositive) {
7962+ AuLabel(positive);
5afbbe0d 7963+ au_update_dbtop(dentry);
1facf9fc 7964+ }
7965+ err = npositive;
076b876e 7966+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
5afbbe0d 7967+ && au_dbtop(dentry) < 0)) {
1facf9fc 7968+ err = -EIO;
523b37e3
AM
7969+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
7970+ dentry, err);
027c5e7a 7971+ }
1facf9fc 7972+
4f0767ce 7973+out_parent:
4a4d8108 7974+ dput(parent);
1c60b727 7975+ kfree(whname.name);
4f0767ce 7976+out:
1facf9fc 7977+ return err;
7978+}
7979+
076b876e 7980+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
1facf9fc 7981+{
7982+ struct dentry *dentry;
7983+ int wkq_err;
7984+
5527c038 7985+ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC))
b4510431 7986+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 7987+ else {
b4510431
AM
7988+ struct vfsub_lkup_one_args args = {
7989+ .errp = &dentry,
7990+ .name = name,
7991+ .parent = parent
1facf9fc 7992+ };
7993+
b4510431 7994+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 7995+ if (unlikely(wkq_err))
7996+ dentry = ERR_PTR(wkq_err);
7997+ }
7998+
7999+ return dentry;
8000+}
8001+
8002+/*
8003+ * lookup @dentry on @bindex which should be negative.
8004+ */
86dc4139 8005+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 8006+{
8007+ int err;
8008+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 8009+ struct au_branch *br;
1facf9fc 8010+
1facf9fc 8011+ parent = dget_parent(dentry);
8012+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
8013+ br = au_sbr(dentry->d_sb, bindex);
8014+ if (wh)
8015+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
8016+ else
076b876e 8017+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 8018+ err = PTR_ERR(h_dentry);
8019+ if (IS_ERR(h_dentry))
8020+ goto out;
5527c038 8021+ if (unlikely(d_is_positive(h_dentry))) {
1facf9fc 8022+ err = -EIO;
523b37e3 8023+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 8024+ dput(h_dentry);
8025+ goto out;
8026+ }
8027+
4a4d8108 8028+ err = 0;
5afbbe0d
AM
8029+ if (bindex < au_dbtop(dentry))
8030+ au_set_dbtop(dentry, bindex);
8031+ if (au_dbbot(dentry) < bindex)
8032+ au_set_dbbot(dentry, bindex);
1facf9fc 8033+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 8034+
4f0767ce 8035+out:
1facf9fc 8036+ dput(parent);
8037+ return err;
8038+}
8039+
8040+/* ---------------------------------------------------------------------- */
8041+
8042+/* subset of struct inode */
8043+struct au_iattr {
8044+ unsigned long i_ino;
8045+ /* unsigned int i_nlink; */
0c3ec466
AM
8046+ kuid_t i_uid;
8047+ kgid_t i_gid;
1facf9fc 8048+ u64 i_version;
8049+/*
8050+ loff_t i_size;
8051+ blkcnt_t i_blocks;
8052+*/
8053+ umode_t i_mode;
8054+};
8055+
8056+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
8057+{
8058+ ia->i_ino = h_inode->i_ino;
8059+ /* ia->i_nlink = h_inode->i_nlink; */
8060+ ia->i_uid = h_inode->i_uid;
8061+ ia->i_gid = h_inode->i_gid;
8062+ ia->i_version = h_inode->i_version;
8063+/*
8064+ ia->i_size = h_inode->i_size;
8065+ ia->i_blocks = h_inode->i_blocks;
8066+*/
8067+ ia->i_mode = (h_inode->i_mode & S_IFMT);
8068+}
8069+
8070+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
8071+{
8072+ return ia->i_ino != h_inode->i_ino
8073+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 8074+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 8075+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 8076+ || ia->i_version != h_inode->i_version
8077+/*
8078+ || ia->i_size != h_inode->i_size
8079+ || ia->i_blocks != h_inode->i_blocks
8080+*/
8081+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
8082+}
8083+
8084+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
8085+ struct au_branch *br)
8086+{
8087+ int err;
8088+ struct au_iattr ia;
8089+ struct inode *h_inode;
8090+ struct dentry *h_d;
8091+ struct super_block *h_sb;
8092+
8093+ err = 0;
8094+ memset(&ia, -1, sizeof(ia));
8095+ h_sb = h_dentry->d_sb;
5527c038
JR
8096+ h_inode = NULL;
8097+ if (d_is_positive(h_dentry)) {
8098+ h_inode = d_inode(h_dentry);
1facf9fc 8099+ au_iattr_save(&ia, h_inode);
5527c038 8100+ } else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
1facf9fc 8101+ /* nfs d_revalidate may return 0 for negative dentry */
8102+ /* fuse d_revalidate always return 0 for negative dentry */
8103+ goto out;
8104+
8105+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 8106+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 8107+ err = PTR_ERR(h_d);
8108+ if (IS_ERR(h_d))
8109+ goto out;
8110+
8111+ err = 0;
8112+ if (unlikely(h_d != h_dentry
5527c038 8113+ || d_inode(h_d) != h_inode
1facf9fc 8114+ || (h_inode && au_iattr_test(&ia, h_inode))))
8115+ err = au_busy_or_stale();
8116+ dput(h_d);
8117+
4f0767ce 8118+out:
1facf9fc 8119+ AuTraceErr(err);
8120+ return err;
8121+}
8122+
8123+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8124+ struct dentry *h_parent, struct au_branch *br)
8125+{
8126+ int err;
8127+
8128+ err = 0;
027c5e7a
AM
8129+ if (udba == AuOpt_UDBA_REVAL
8130+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 8131+ IMustLock(h_dir);
5527c038 8132+ err = (d_inode(h_dentry->d_parent) != h_dir);
027c5e7a 8133+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 8134+ err = au_h_verify_dentry(h_dentry, h_parent, br);
8135+
8136+ return err;
8137+}
8138+
8139+/* ---------------------------------------------------------------------- */
8140+
027c5e7a 8141+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 8142+{
027c5e7a 8143+ int err;
5afbbe0d 8144+ aufs_bindex_t new_bindex, bindex, bbot, bwh, bdiropq;
027c5e7a
AM
8145+ struct au_hdentry tmp, *p, *q;
8146+ struct au_dinfo *dinfo;
8147+ struct super_block *sb;
1facf9fc 8148+
027c5e7a 8149+ DiMustWriteLock(dentry);
1308ab2a 8150+
027c5e7a
AM
8151+ sb = dentry->d_sb;
8152+ dinfo = au_di(dentry);
5afbbe0d 8153+ bbot = dinfo->di_bbot;
1facf9fc 8154+ bwh = dinfo->di_bwh;
8155+ bdiropq = dinfo->di_bdiropq;
5afbbe0d
AM
8156+ bindex = dinfo->di_btop;
8157+ p = au_hdentry(dinfo, bindex);
8158+ for (; bindex <= bbot; bindex++, p++) {
027c5e7a 8159+ if (!p->hd_dentry)
1facf9fc 8160+ continue;
8161+
027c5e7a
AM
8162+ new_bindex = au_br_index(sb, p->hd_id);
8163+ if (new_bindex == bindex)
1facf9fc 8164+ continue;
1facf9fc 8165+
1facf9fc 8166+ if (dinfo->di_bwh == bindex)
8167+ bwh = new_bindex;
8168+ if (dinfo->di_bdiropq == bindex)
8169+ bdiropq = new_bindex;
8170+ if (new_bindex < 0) {
8171+ au_hdput(p);
8172+ p->hd_dentry = NULL;
8173+ continue;
8174+ }
8175+
8176+ /* swap two lower dentries, and loop again */
5afbbe0d 8177+ q = au_hdentry(dinfo, new_bindex);
1facf9fc 8178+ tmp = *q;
8179+ *q = *p;
8180+ *p = tmp;
8181+ if (tmp.hd_dentry) {
8182+ bindex--;
8183+ p--;
8184+ }
8185+ }
8186+
1facf9fc 8187+ dinfo->di_bwh = -1;
5afbbe0d 8188+ if (bwh >= 0 && bwh <= au_sbbot(sb) && au_sbr_whable(sb, bwh))
1facf9fc 8189+ dinfo->di_bwh = bwh;
8190+
8191+ dinfo->di_bdiropq = -1;
8192+ if (bdiropq >= 0
5afbbe0d 8193+ && bdiropq <= au_sbbot(sb)
1facf9fc 8194+ && au_sbr_whable(sb, bdiropq))
8195+ dinfo->di_bdiropq = bdiropq;
8196+
027c5e7a 8197+ err = -EIO;
5afbbe0d
AM
8198+ dinfo->di_btop = -1;
8199+ dinfo->di_bbot = -1;
8200+ bbot = au_dbbot(parent);
8201+ bindex = 0;
8202+ p = au_hdentry(dinfo, bindex);
8203+ for (; bindex <= bbot; bindex++, p++)
1facf9fc 8204+ if (p->hd_dentry) {
5afbbe0d 8205+ dinfo->di_btop = bindex;
1facf9fc 8206+ break;
8207+ }
8208+
5afbbe0d
AM
8209+ if (dinfo->di_btop >= 0) {
8210+ bindex = bbot;
8211+ p = au_hdentry(dinfo, bindex);
8212+ for (; bindex >= 0; bindex--, p--)
027c5e7a 8213+ if (p->hd_dentry) {
5afbbe0d 8214+ dinfo->di_bbot = bindex;
027c5e7a
AM
8215+ err = 0;
8216+ break;
8217+ }
8218+ }
8219+
8220+ return err;
1facf9fc 8221+}
8222+
027c5e7a 8223+static void au_do_hide(struct dentry *dentry)
1facf9fc 8224+{
027c5e7a 8225+ struct inode *inode;
1facf9fc 8226+
5527c038
JR
8227+ if (d_really_is_positive(dentry)) {
8228+ inode = d_inode(dentry);
8229+ if (!d_is_dir(dentry)) {
027c5e7a
AM
8230+ if (inode->i_nlink && !d_unhashed(dentry))
8231+ drop_nlink(inode);
8232+ } else {
8233+ clear_nlink(inode);
8234+ /* stop next lookup */
8235+ inode->i_flags |= S_DEAD;
8236+ }
8237+ smp_mb(); /* necessary? */
8238+ }
8239+ d_drop(dentry);
8240+}
1308ab2a 8241+
027c5e7a
AM
8242+static int au_hide_children(struct dentry *parent)
8243+{
8244+ int err, i, j, ndentry;
8245+ struct au_dcsub_pages dpages;
8246+ struct au_dpage *dpage;
8247+ struct dentry *dentry;
1facf9fc 8248+
027c5e7a 8249+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 8250+ if (unlikely(err))
8251+ goto out;
027c5e7a
AM
8252+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
8253+ if (unlikely(err))
8254+ goto out_dpages;
1facf9fc 8255+
027c5e7a
AM
8256+ /* in reverse order */
8257+ for (i = dpages.ndpage - 1; i >= 0; i--) {
8258+ dpage = dpages.dpages + i;
8259+ ndentry = dpage->ndentry;
8260+ for (j = ndentry - 1; j >= 0; j--) {
8261+ dentry = dpage->dentries[j];
8262+ if (dentry != parent)
8263+ au_do_hide(dentry);
8264+ }
8265+ }
1facf9fc 8266+
027c5e7a
AM
8267+out_dpages:
8268+ au_dpages_free(&dpages);
4f0767ce 8269+out:
027c5e7a 8270+ return err;
1facf9fc 8271+}
8272+
027c5e7a 8273+static void au_hide(struct dentry *dentry)
1facf9fc 8274+{
027c5e7a 8275+ int err;
1facf9fc 8276+
027c5e7a 8277+ AuDbgDentry(dentry);
2000de60 8278+ if (d_is_dir(dentry)) {
027c5e7a
AM
8279+ /* shrink_dcache_parent(dentry); */
8280+ err = au_hide_children(dentry);
8281+ if (unlikely(err))
523b37e3
AM
8282+ AuIOErr("%pd, failed hiding children, ignored %d\n",
8283+ dentry, err);
027c5e7a
AM
8284+ }
8285+ au_do_hide(dentry);
8286+}
1facf9fc 8287+
027c5e7a
AM
8288+/*
8289+ * By adding a dirty branch, a cached dentry may be affected in various ways.
8290+ *
8291+ * a dirty branch is added
8292+ * - on the top of layers
8293+ * - in the middle of layers
8294+ * - to the bottom of layers
8295+ *
8296+ * on the added branch there exists
8297+ * - a whiteout
8298+ * - a diropq
8299+ * - a same named entry
8300+ * + exist
8301+ * * negative --> positive
8302+ * * positive --> positive
8303+ * - type is unchanged
8304+ * - type is changed
8305+ * + doesn't exist
8306+ * * negative --> negative
8307+ * * positive --> negative (rejected by au_br_del() for non-dir case)
8308+ * - none
8309+ */
8310+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
8311+ struct au_dinfo *tmp)
8312+{
8313+ int err;
5afbbe0d 8314+ aufs_bindex_t bindex, bbot;
027c5e7a
AM
8315+ struct {
8316+ struct dentry *dentry;
8317+ struct inode *inode;
8318+ mode_t mode;
be52b249
AM
8319+ } orig_h, tmp_h = {
8320+ .dentry = NULL
8321+ };
027c5e7a
AM
8322+ struct au_hdentry *hd;
8323+ struct inode *inode, *h_inode;
8324+ struct dentry *h_dentry;
8325+
8326+ err = 0;
5afbbe0d 8327+ AuDebugOn(dinfo->di_btop < 0);
027c5e7a 8328+ orig_h.mode = 0;
5afbbe0d 8329+ orig_h.dentry = au_hdentry(dinfo, dinfo->di_btop)->hd_dentry;
5527c038
JR
8330+ orig_h.inode = NULL;
8331+ if (d_is_positive(orig_h.dentry)) {
8332+ orig_h.inode = d_inode(orig_h.dentry);
027c5e7a 8333+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
5527c038 8334+ }
5afbbe0d
AM
8335+ if (tmp->di_btop >= 0) {
8336+ tmp_h.dentry = au_hdentry(tmp, tmp->di_btop)->hd_dentry;
5527c038
JR
8337+ if (d_is_positive(tmp_h.dentry)) {
8338+ tmp_h.inode = d_inode(tmp_h.dentry);
027c5e7a 8339+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
5527c038 8340+ }
027c5e7a
AM
8341+ }
8342+
5527c038
JR
8343+ inode = NULL;
8344+ if (d_really_is_positive(dentry))
8345+ inode = d_inode(dentry);
027c5e7a
AM
8346+ if (!orig_h.inode) {
8347+ AuDbg("nagative originally\n");
8348+ if (inode) {
8349+ au_hide(dentry);
8350+ goto out;
8351+ }
8352+ AuDebugOn(inode);
5afbbe0d 8353+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
027c5e7a
AM
8354+ AuDebugOn(dinfo->di_bdiropq != -1);
8355+
8356+ if (!tmp_h.inode) {
8357+ AuDbg("negative --> negative\n");
8358+ /* should have only one negative lower */
5afbbe0d
AM
8359+ if (tmp->di_btop >= 0
8360+ && tmp->di_btop < dinfo->di_btop) {
8361+ AuDebugOn(tmp->di_btop != tmp->di_bbot);
8362+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
8363+ au_set_h_dptr(dentry, dinfo->di_btop, NULL);
027c5e7a 8364+ au_di_cp(dinfo, tmp);
5afbbe0d
AM
8365+ hd = au_hdentry(tmp, tmp->di_btop);
8366+ au_set_h_dptr(dentry, tmp->di_btop,
027c5e7a
AM
8367+ dget(hd->hd_dentry));
8368+ }
8369+ au_dbg_verify_dinode(dentry);
8370+ } else {
8371+ AuDbg("negative --> positive\n");
8372+ /*
8373+ * similar to the behaviour of creating with bypassing
8374+ * aufs.
8375+ * unhash it in order to force an error in the
8376+ * succeeding create operation.
8377+ * we should not set S_DEAD here.
8378+ */
8379+ d_drop(dentry);
8380+ /* au_di_swap(tmp, dinfo); */
8381+ au_dbg_verify_dinode(dentry);
8382+ }
8383+ } else {
8384+ AuDbg("positive originally\n");
8385+ /* inode may be NULL */
8386+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
8387+ if (!tmp_h.inode) {
8388+ AuDbg("positive --> negative\n");
8389+ /* or bypassing aufs */
8390+ au_hide(dentry);
5afbbe0d 8391+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_btop)
027c5e7a
AM
8392+ dinfo->di_bwh = tmp->di_bwh;
8393+ if (inode)
8394+ err = au_refresh_hinode_self(inode);
8395+ au_dbg_verify_dinode(dentry);
8396+ } else if (orig_h.mode == tmp_h.mode) {
8397+ AuDbg("positive --> positive, same type\n");
8398+ if (!S_ISDIR(orig_h.mode)
5afbbe0d 8399+ && dinfo->di_btop > tmp->di_btop) {
027c5e7a
AM
8400+ /*
8401+ * similar to the behaviour of removing and
8402+ * creating.
8403+ */
8404+ au_hide(dentry);
8405+ if (inode)
8406+ err = au_refresh_hinode_self(inode);
8407+ au_dbg_verify_dinode(dentry);
8408+ } else {
8409+ /* fill empty slots */
5afbbe0d
AM
8410+ if (dinfo->di_btop > tmp->di_btop)
8411+ dinfo->di_btop = tmp->di_btop;
8412+ if (dinfo->di_bbot < tmp->di_bbot)
8413+ dinfo->di_bbot = tmp->di_bbot;
027c5e7a
AM
8414+ dinfo->di_bwh = tmp->di_bwh;
8415+ dinfo->di_bdiropq = tmp->di_bdiropq;
5afbbe0d
AM
8416+ bbot = dinfo->di_bbot;
8417+ bindex = tmp->di_btop;
8418+ hd = au_hdentry(tmp, bindex);
8419+ for (; bindex <= bbot; bindex++, hd++) {
027c5e7a
AM
8420+ if (au_h_dptr(dentry, bindex))
8421+ continue;
5afbbe0d 8422+ h_dentry = hd->hd_dentry;
027c5e7a
AM
8423+ if (!h_dentry)
8424+ continue;
5527c038
JR
8425+ AuDebugOn(d_is_negative(h_dentry));
8426+ h_inode = d_inode(h_dentry);
027c5e7a
AM
8427+ AuDebugOn(orig_h.mode
8428+ != (h_inode->i_mode
8429+ & S_IFMT));
8430+ au_set_h_dptr(dentry, bindex,
8431+ dget(h_dentry));
8432+ }
5afbbe0d
AM
8433+ if (inode)
8434+ err = au_refresh_hinode(inode, dentry);
027c5e7a
AM
8435+ au_dbg_verify_dinode(dentry);
8436+ }
8437+ } else {
8438+ AuDbg("positive --> positive, different type\n");
8439+ /* similar to the behaviour of removing and creating */
8440+ au_hide(dentry);
8441+ if (inode)
8442+ err = au_refresh_hinode_self(inode);
8443+ au_dbg_verify_dinode(dentry);
8444+ }
8445+ }
8446+
8447+out:
8448+ return err;
8449+}
8450+
79b8bda9
AM
8451+void au_refresh_dop(struct dentry *dentry, int force_reval)
8452+{
8453+ const struct dentry_operations *dop
8454+ = force_reval ? &aufs_dop : dentry->d_sb->s_d_op;
8455+ static const unsigned int mask
8456+ = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE;
8457+
8458+ BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags));
8459+
8460+ if (dentry->d_op == dop)
8461+ return;
8462+
8463+ AuDbg("%pd\n", dentry);
8464+ spin_lock(&dentry->d_lock);
8465+ if (dop == &aufs_dop)
8466+ dentry->d_flags |= mask;
8467+ else
8468+ dentry->d_flags &= ~mask;
8469+ dentry->d_op = dop;
8470+ spin_unlock(&dentry->d_lock);
8471+}
8472+
027c5e7a
AM
8473+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
8474+{
e2f27e51 8475+ int err, ebrange, nbr;
027c5e7a
AM
8476+ unsigned int sigen;
8477+ struct au_dinfo *dinfo, *tmp;
8478+ struct super_block *sb;
8479+ struct inode *inode;
8480+
8481+ DiMustWriteLock(dentry);
8482+ AuDebugOn(IS_ROOT(dentry));
5527c038 8483+ AuDebugOn(d_really_is_negative(parent));
027c5e7a
AM
8484+
8485+ sb = dentry->d_sb;
027c5e7a
AM
8486+ sigen = au_sigen(sb);
8487+ err = au_digen_test(parent, sigen);
8488+ if (unlikely(err))
8489+ goto out;
8490+
e2f27e51 8491+ nbr = au_sbbot(sb) + 1;
027c5e7a 8492+ dinfo = au_di(dentry);
e2f27e51 8493+ err = au_di_realloc(dinfo, nbr, /*may_shrink*/0);
027c5e7a
AM
8494+ if (unlikely(err))
8495+ goto out;
8496+ ebrange = au_dbrange_test(dentry);
8497+ if (!ebrange)
8498+ ebrange = au_do_refresh_hdentry(dentry, parent);
8499+
38d290e6 8500+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
5afbbe0d 8501+ AuDebugOn(au_dbtop(dentry) < 0 && au_dbbot(dentry) >= 0);
5527c038
JR
8502+ if (d_really_is_positive(dentry)) {
8503+ inode = d_inode(dentry);
027c5e7a 8504+ err = au_refresh_hinode_self(inode);
5527c038 8505+ }
027c5e7a
AM
8506+ au_dbg_verify_dinode(dentry);
8507+ if (!err)
8508+ goto out_dgen; /* success */
8509+ goto out;
8510+ }
8511+
8512+ /* temporary dinfo */
8513+ AuDbgDentry(dentry);
8514+ err = -ENOMEM;
8515+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
8516+ if (unlikely(!tmp))
8517+ goto out;
8518+ au_di_swap(tmp, dinfo);
8519+ /* returns the number of positive dentries */
8520+ /*
8521+ * if current working dir is removed, it returns an error.
8522+ * but the dentry is legal.
8523+ */
5afbbe0d 8524+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG);
027c5e7a
AM
8525+ AuDbgDentry(dentry);
8526+ au_di_swap(tmp, dinfo);
8527+ if (err == -ENOENT)
8528+ err = 0;
8529+ if (err >= 0) {
8530+ /* compare/refresh by dinfo */
8531+ AuDbgDentry(dentry);
8532+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
8533+ au_dbg_verify_dinode(dentry);
8534+ AuTraceErr(err);
8535+ }
e2f27e51 8536+ au_di_realloc(dinfo, nbr, /*may_shrink*/1); /* harmless if err */
027c5e7a
AM
8537+ au_rw_write_unlock(&tmp->di_rwsem);
8538+ au_di_free(tmp);
8539+ if (unlikely(err))
8540+ goto out;
8541+
8542+out_dgen:
8543+ au_update_digen(dentry);
8544+out:
8545+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 8546+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
8547+ AuDbgDentry(dentry);
8548+ }
8549+ AuTraceErr(err);
8550+ return err;
8551+}
8552+
b4510431
AM
8553+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
8554+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
8555+{
8556+ int err, valid;
027c5e7a
AM
8557+
8558+ err = 0;
8559+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
8560+ goto out;
027c5e7a
AM
8561+
8562+ AuDbg("b%d\n", bindex);
b4510431
AM
8563+ /*
8564+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
8565+ * due to whiteout and branch permission.
8566+ */
8567+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
8568+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
8569+ /* it may return tri-state */
8570+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 8571+
8572+ if (unlikely(valid < 0))
8573+ err = valid;
8574+ else if (!valid)
8575+ err = -EINVAL;
8576+
4f0767ce 8577+out:
1facf9fc 8578+ AuTraceErr(err);
8579+ return err;
8580+}
8581+
8582+/* todo: remove this */
8583+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 8584+ unsigned int flags, int do_udba)
1facf9fc 8585+{
8586+ int err;
8587+ umode_t mode, h_mode;
5afbbe0d 8588+ aufs_bindex_t bindex, btail, btop, ibs, ibe;
38d290e6 8589+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
4a4d8108 8590+ struct inode *h_inode, *h_cached_inode;
1facf9fc 8591+ struct dentry *h_dentry;
8592+ struct qstr *name, *h_name;
8593+
8594+ err = 0;
8595+ plus = 0;
8596+ mode = 0;
1facf9fc 8597+ ibs = -1;
8598+ ibe = -1;
8599+ unhashed = !!d_unhashed(dentry);
8600+ is_root = !!IS_ROOT(dentry);
8601+ name = &dentry->d_name;
38d290e6 8602+ tmpfile = au_di(dentry)->di_tmpfile;
1facf9fc 8603+
8604+ /*
7f207e10
AM
8605+ * Theoretically, REVAL test should be unnecessary in case of
8606+ * {FS,I}NOTIFY.
8607+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 8608+ * IN_ATTRIB for atime/nlink/pageio
1facf9fc 8609+ * Let's do REVAL test too.
8610+ */
8611+ if (do_udba && inode) {
8612+ mode = (inode->i_mode & S_IFMT);
8613+ plus = (inode->i_nlink > 0);
5afbbe0d
AM
8614+ ibs = au_ibtop(inode);
8615+ ibe = au_ibbot(inode);
1facf9fc 8616+ }
8617+
5afbbe0d
AM
8618+ btop = au_dbtop(dentry);
8619+ btail = btop;
1facf9fc 8620+ if (inode && S_ISDIR(inode->i_mode))
8621+ btail = au_dbtaildir(dentry);
5afbbe0d 8622+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 8623+ h_dentry = au_h_dptr(dentry, bindex);
8624+ if (!h_dentry)
8625+ continue;
8626+
523b37e3
AM
8627+ AuDbg("b%d, %pd\n", bindex, h_dentry);
8628+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 8629+ spin_lock(&h_dentry->d_lock);
1facf9fc 8630+ h_name = &h_dentry->d_name;
8631+ if (unlikely(do_udba
8632+ && !is_root
523b37e3
AM
8633+ && ((!h_nfs
8634+ && (unhashed != !!d_unhashed(h_dentry)
38d290e6
JR
8635+ || (!tmpfile
8636+ && !au_qstreq(name, h_name))
8637+ ))
523b37e3
AM
8638+ || (h_nfs
8639+ && !(flags & LOOKUP_OPEN)
8640+ && (h_dentry->d_flags
8641+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 8642+ )) {
38d290e6
JR
8643+ int h_unhashed;
8644+
8645+ h_unhashed = d_unhashed(h_dentry);
027c5e7a 8646+ spin_unlock(&h_dentry->d_lock);
38d290e6
JR
8647+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
8648+ unhashed, h_unhashed, dentry, h_dentry);
1facf9fc 8649+ goto err;
8650+ }
027c5e7a 8651+ spin_unlock(&h_dentry->d_lock);
1facf9fc 8652+
b4510431 8653+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 8654+ if (unlikely(err))
8655+ /* do not goto err, to keep the errno */
8656+ break;
8657+
8658+ /* todo: plink too? */
8659+ if (!do_udba)
8660+ continue;
8661+
8662+ /* UDBA tests */
5527c038 8663+ if (unlikely(!!inode != d_is_positive(h_dentry)))
1facf9fc 8664+ goto err;
8665+
5527c038
JR
8666+ h_inode = NULL;
8667+ if (d_is_positive(h_dentry))
8668+ h_inode = d_inode(h_dentry);
1facf9fc 8669+ h_plus = plus;
8670+ h_mode = mode;
8671+ h_cached_inode = h_inode;
8672+ if (h_inode) {
8673+ h_mode = (h_inode->i_mode & S_IFMT);
8674+ h_plus = (h_inode->i_nlink > 0);
8675+ }
8676+ if (inode && ibs <= bindex && bindex <= ibe)
8677+ h_cached_inode = au_h_iptr(inode, bindex);
8678+
523b37e3 8679+ if (!h_nfs) {
38d290e6 8680+ if (unlikely(plus != h_plus && !tmpfile))
523b37e3
AM
8681+ goto err;
8682+ } else {
8683+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
8684+ && !is_root
8685+ && !IS_ROOT(h_dentry)
8686+ && unhashed != d_unhashed(h_dentry)))
8687+ goto err;
8688+ }
8689+ if (unlikely(mode != h_mode
1facf9fc 8690+ || h_cached_inode != h_inode))
8691+ goto err;
8692+ continue;
8693+
f6b6e03d 8694+err:
1facf9fc 8695+ err = -EINVAL;
8696+ break;
8697+ }
8698+
523b37e3 8699+ AuTraceErr(err);
1facf9fc 8700+ return err;
8701+}
8702+
027c5e7a 8703+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 8704+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
8705+{
8706+ int err;
8707+ struct dentry *parent;
1facf9fc 8708+
027c5e7a 8709+ if (!au_digen_test(dentry, sigen))
1facf9fc 8710+ return 0;
8711+
8712+ parent = dget_parent(dentry);
8713+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8714+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 8715+ au_dbg_verify_gen(parent, sigen);
027c5e7a 8716+ err = au_refresh_dentry(dentry, parent);
1facf9fc 8717+ di_read_unlock(parent, AuLock_IR);
8718+ dput(parent);
027c5e7a 8719+ AuTraceErr(err);
1facf9fc 8720+ return err;
8721+}
8722+
8723+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
8724+{
8725+ int err;
8726+ struct dentry *d, *parent;
1facf9fc 8727+
027c5e7a 8728+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 8729+ return simple_reval_dpath(dentry, sigen);
8730+
8731+ /* slow loop, keep it simple and stupid */
8732+ /* cf: au_cpup_dirs() */
8733+ err = 0;
8734+ parent = NULL;
027c5e7a 8735+ while (au_digen_test(dentry, sigen)) {
1facf9fc 8736+ d = dentry;
8737+ while (1) {
8738+ dput(parent);
8739+ parent = dget_parent(d);
027c5e7a 8740+ if (!au_digen_test(parent, sigen))
1facf9fc 8741+ break;
8742+ d = parent;
8743+ }
8744+
1facf9fc 8745+ if (d != dentry)
027c5e7a 8746+ di_write_lock_child2(d);
1facf9fc 8747+
8748+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
8749+ if (au_digen_test(d, sigen)) {
8750+ /*
8751+ * todo: consolidate with simple_reval_dpath(),
8752+ * do_refresh() and au_reval_for_attr().
8753+ */
1facf9fc 8754+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8755+ err = au_refresh_dentry(d, parent);
1facf9fc 8756+ di_read_unlock(parent, AuLock_IR);
8757+ }
8758+
8759+ if (d != dentry)
8760+ di_write_unlock(d);
8761+ dput(parent);
8762+ if (unlikely(err))
8763+ break;
8764+ }
8765+
8766+ return err;
8767+}
8768+
8769+/*
8770+ * if valid returns 1, otherwise 0.
8771+ */
b4510431 8772+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 8773+{
8774+ int valid, err;
8775+ unsigned int sigen;
8776+ unsigned char do_udba;
8777+ struct super_block *sb;
8778+ struct inode *inode;
8779+
027c5e7a 8780+ /* todo: support rcu-walk? */
b4510431 8781+ if (flags & LOOKUP_RCU)
027c5e7a
AM
8782+ return -ECHILD;
8783+
8784+ valid = 0;
8785+ if (unlikely(!au_di(dentry)))
8786+ goto out;
8787+
e49829fe 8788+ valid = 1;
1facf9fc 8789+ sb = dentry->d_sb;
e49829fe
JR
8790+ /*
8791+ * todo: very ugly
8792+ * i_mutex of parent dir may be held,
8793+ * but we should not return 'invalid' due to busy.
8794+ */
8795+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
8796+ if (unlikely(err)) {
8797+ valid = err;
027c5e7a 8798+ AuTraceErr(err);
e49829fe
JR
8799+ goto out;
8800+ }
5527c038
JR
8801+ inode = NULL;
8802+ if (d_really_is_positive(dentry))
8803+ inode = d_inode(dentry);
5afbbe0d 8804+ if (unlikely(inode && au_is_bad_inode(inode))) {
c1595e42
JR
8805+ err = -EINVAL;
8806+ AuTraceErr(err);
8807+ goto out_dgrade;
8808+ }
027c5e7a
AM
8809+ if (unlikely(au_dbrange_test(dentry))) {
8810+ err = -EINVAL;
8811+ AuTraceErr(err);
8812+ goto out_dgrade;
1facf9fc 8813+ }
027c5e7a
AM
8814+
8815+ sigen = au_sigen(sb);
8816+ if (au_digen_test(dentry, sigen)) {
1facf9fc 8817+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
8818+ err = au_reval_dpath(dentry, sigen);
8819+ if (unlikely(err)) {
8820+ AuTraceErr(err);
1facf9fc 8821+ goto out_dgrade;
027c5e7a 8822+ }
1facf9fc 8823+ }
8824+ di_downgrade_lock(dentry, AuLock_IR);
8825+
1facf9fc 8826+ err = -EINVAL;
c1595e42 8827+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
523b37e3 8828+ && inode
38d290e6 8829+ && !(inode->i_state && I_LINKABLE)
79b8bda9
AM
8830+ && (IS_DEADDIR(inode) || !inode->i_nlink)) {
8831+ AuTraceErr(err);
027c5e7a 8832+ goto out_inval;
79b8bda9 8833+ }
027c5e7a 8834+
1facf9fc 8835+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
8836+ if (do_udba && inode) {
5afbbe0d 8837+ aufs_bindex_t btop = au_ibtop(inode);
027c5e7a 8838+ struct inode *h_inode;
1facf9fc 8839+
5afbbe0d
AM
8840+ if (btop >= 0) {
8841+ h_inode = au_h_iptr(inode, btop);
79b8bda9
AM
8842+ if (h_inode && au_test_higen(inode, h_inode)) {
8843+ AuTraceErr(err);
027c5e7a 8844+ goto out_inval;
79b8bda9 8845+ }
027c5e7a 8846+ }
1facf9fc 8847+ }
8848+
b4510431 8849+ err = h_d_revalidate(dentry, inode, flags, do_udba);
5afbbe0d 8850+ if (unlikely(!err && do_udba && au_dbtop(dentry) < 0)) {
1facf9fc 8851+ err = -EIO;
523b37e3
AM
8852+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
8853+ dentry, err);
027c5e7a 8854+ }
e49829fe 8855+ goto out_inval;
1facf9fc 8856+
4f0767ce 8857+out_dgrade:
1facf9fc 8858+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 8859+out_inval:
1facf9fc 8860+ aufs_read_unlock(dentry, AuLock_IR);
8861+ AuTraceErr(err);
8862+ valid = !err;
e49829fe 8863+out:
027c5e7a 8864+ if (!valid) {
523b37e3 8865+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
8866+ d_drop(dentry);
8867+ }
1facf9fc 8868+ return valid;
8869+}
8870+
8871+static void aufs_d_release(struct dentry *dentry)
8872+{
027c5e7a 8873+ if (au_di(dentry)) {
4a4d8108
AM
8874+ au_di_fin(dentry);
8875+ au_hn_di_reinit(dentry);
1facf9fc 8876+ }
1facf9fc 8877+}
8878+
4a4d8108 8879+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
8880+ .d_revalidate = aufs_d_revalidate,
8881+ .d_weak_revalidate = aufs_d_revalidate,
8882+ .d_release = aufs_d_release
1facf9fc 8883+};
79b8bda9
AM
8884+
8885+/* aufs_dop without d_revalidate */
8886+const struct dentry_operations aufs_dop_noreval = {
8887+ .d_release = aufs_d_release
8888+};
7f207e10
AM
8889diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
8890--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
8891+++ linux/fs/aufs/dentry.h 2017-07-29 12:14:25.899708630 +0200
8892@@ -0,0 +1,252 @@
1facf9fc 8893+/*
a2654f78 8894+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 8895+ *
8896+ * This program, aufs is free software; you can redistribute it and/or modify
8897+ * it under the terms of the GNU General Public License as published by
8898+ * the Free Software Foundation; either version 2 of the License, or
8899+ * (at your option) any later version.
dece6358
AM
8900+ *
8901+ * This program is distributed in the hope that it will be useful,
8902+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8903+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8904+ * GNU General Public License for more details.
8905+ *
8906+ * You should have received a copy of the GNU General Public License
523b37e3 8907+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8908+ */
8909+
8910+/*
8911+ * lookup and dentry operations
8912+ */
8913+
8914+#ifndef __AUFS_DENTRY_H__
8915+#define __AUFS_DENTRY_H__
8916+
8917+#ifdef __KERNEL__
8918+
dece6358 8919+#include <linux/dcache.h>
1facf9fc 8920+#include "rwsem.h"
8921+
1facf9fc 8922+struct au_hdentry {
8923+ struct dentry *hd_dentry;
027c5e7a 8924+ aufs_bindex_t hd_id;
1facf9fc 8925+};
8926+
8927+struct au_dinfo {
8928+ atomic_t di_generation;
8929+
dece6358 8930+ struct au_rwsem di_rwsem;
5afbbe0d 8931+ aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq;
38d290e6 8932+ unsigned char di_tmpfile; /* to allow the different name */
1c60b727 8933+ struct au_hdentry *di_hdentry;
4a4d8108 8934+} ____cacheline_aligned_in_smp;
1facf9fc 8935+
8936+/* ---------------------------------------------------------------------- */
8937+
5afbbe0d
AM
8938+/* flags for au_lkup_dentry() */
8939+#define AuLkup_ALLOW_NEG 1
8940+#define AuLkup_IGNORE_PERM (1 << 1)
8941+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
8942+#define au_fset_lkup(flags, name) \
8943+ do { (flags) |= AuLkup_##name; } while (0)
8944+#define au_fclr_lkup(flags, name) \
8945+ do { (flags) &= ~AuLkup_##name; } while (0)
8946+
8947+/* ---------------------------------------------------------------------- */
8948+
1facf9fc 8949+/* dentry.c */
79b8bda9 8950+extern const struct dentry_operations aufs_dop, aufs_dop_noreval;
1facf9fc 8951+struct au_branch;
076b876e 8952+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
1facf9fc 8953+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8954+ struct dentry *h_parent, struct au_branch *br);
8955+
5afbbe0d
AM
8956+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop,
8957+ unsigned int flags);
86dc4139 8958+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 8959+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 8960+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
79b8bda9 8961+void au_refresh_dop(struct dentry *dentry, int force_reval);
1facf9fc 8962+
8963+/* dinfo.c */
4a4d8108 8964+void au_di_init_once(void *_di);
027c5e7a
AM
8965+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
8966+void au_di_free(struct au_dinfo *dinfo);
8967+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
8968+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
8969+int au_di_init(struct dentry *dentry);
8970+void au_di_fin(struct dentry *dentry);
e2f27e51 8971+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink);
1facf9fc 8972+
8973+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
8974+void di_read_unlock(struct dentry *d, int flags);
8975+void di_downgrade_lock(struct dentry *d, int flags);
8976+void di_write_lock(struct dentry *d, unsigned int lsc);
8977+void di_write_unlock(struct dentry *d);
8978+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
8979+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
8980+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
8981+
8982+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 8983+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 8984+aufs_bindex_t au_dbtail(struct dentry *dentry);
8985+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
8986+
8987+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8988+ struct dentry *h_dentry);
027c5e7a
AM
8989+int au_digen_test(struct dentry *dentry, unsigned int sigen);
8990+int au_dbrange_test(struct dentry *dentry);
1facf9fc 8991+void au_update_digen(struct dentry *dentry);
8992+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
5afbbe0d
AM
8993+void au_update_dbtop(struct dentry *dentry);
8994+void au_update_dbbot(struct dentry *dentry);
1facf9fc 8995+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
8996+
8997+/* ---------------------------------------------------------------------- */
8998+
8999+static inline struct au_dinfo *au_di(struct dentry *dentry)
9000+{
9001+ return dentry->d_fsdata;
9002+}
9003+
9004+/* ---------------------------------------------------------------------- */
9005+
9006+/* lock subclass for dinfo */
9007+enum {
9008+ AuLsc_DI_CHILD, /* child first */
4a4d8108 9009+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 9010+ AuLsc_DI_CHILD3, /* copyup dirs */
9011+ AuLsc_DI_PARENT,
9012+ AuLsc_DI_PARENT2,
027c5e7a
AM
9013+ AuLsc_DI_PARENT3,
9014+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 9015+};
9016+
9017+/*
9018+ * di_read_lock_child, di_write_lock_child,
9019+ * di_read_lock_child2, di_write_lock_child2,
9020+ * di_read_lock_child3, di_write_lock_child3,
9021+ * di_read_lock_parent, di_write_lock_parent,
9022+ * di_read_lock_parent2, di_write_lock_parent2,
9023+ * di_read_lock_parent3, di_write_lock_parent3,
9024+ */
9025+#define AuReadLockFunc(name, lsc) \
9026+static inline void di_read_lock_##name(struct dentry *d, int flags) \
9027+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
9028+
9029+#define AuWriteLockFunc(name, lsc) \
9030+static inline void di_write_lock_##name(struct dentry *d) \
9031+{ di_write_lock(d, AuLsc_DI_##lsc); }
9032+
9033+#define AuRWLockFuncs(name, lsc) \
9034+ AuReadLockFunc(name, lsc) \
9035+ AuWriteLockFunc(name, lsc)
9036+
9037+AuRWLockFuncs(child, CHILD);
9038+AuRWLockFuncs(child2, CHILD2);
9039+AuRWLockFuncs(child3, CHILD3);
9040+AuRWLockFuncs(parent, PARENT);
9041+AuRWLockFuncs(parent2, PARENT2);
9042+AuRWLockFuncs(parent3, PARENT3);
9043+
9044+#undef AuReadLockFunc
9045+#undef AuWriteLockFunc
9046+#undef AuRWLockFuncs
9047+
9048+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
9049+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
9050+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 9051+
9052+/* ---------------------------------------------------------------------- */
9053+
9054+/* todo: memory barrier? */
9055+static inline unsigned int au_digen(struct dentry *d)
9056+{
9057+ return atomic_read(&au_di(d)->di_generation);
9058+}
9059+
9060+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
9061+{
9062+ hdentry->hd_dentry = NULL;
9063+}
9064+
5afbbe0d
AM
9065+static inline struct au_hdentry *au_hdentry(struct au_dinfo *di,
9066+ aufs_bindex_t bindex)
9067+{
9068+ return di->di_hdentry + bindex;
9069+}
9070+
1facf9fc 9071+static inline void au_hdput(struct au_hdentry *hd)
9072+{
4a4d8108
AM
9073+ if (hd)
9074+ dput(hd->hd_dentry);
1facf9fc 9075+}
9076+
5afbbe0d 9077+static inline aufs_bindex_t au_dbtop(struct dentry *dentry)
1facf9fc 9078+{
1308ab2a 9079+ DiMustAnyLock(dentry);
5afbbe0d 9080+ return au_di(dentry)->di_btop;
1facf9fc 9081+}
9082+
5afbbe0d 9083+static inline aufs_bindex_t au_dbbot(struct dentry *dentry)
1facf9fc 9084+{
1308ab2a 9085+ DiMustAnyLock(dentry);
5afbbe0d 9086+ return au_di(dentry)->di_bbot;
1facf9fc 9087+}
9088+
9089+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
9090+{
1308ab2a 9091+ DiMustAnyLock(dentry);
1facf9fc 9092+ return au_di(dentry)->di_bwh;
9093+}
9094+
9095+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
9096+{
1308ab2a 9097+ DiMustAnyLock(dentry);
1facf9fc 9098+ return au_di(dentry)->di_bdiropq;
9099+}
9100+
9101+/* todo: hard/soft set? */
5afbbe0d 9102+static inline void au_set_dbtop(struct dentry *dentry, aufs_bindex_t bindex)
1facf9fc 9103+{
1308ab2a 9104+ DiMustWriteLock(dentry);
5afbbe0d 9105+ au_di(dentry)->di_btop = bindex;
1facf9fc 9106+}
9107+
5afbbe0d 9108+static inline void au_set_dbbot(struct dentry *dentry, aufs_bindex_t bindex)
1facf9fc 9109+{
1308ab2a 9110+ DiMustWriteLock(dentry);
5afbbe0d 9111+ au_di(dentry)->di_bbot = bindex;
1facf9fc 9112+}
9113+
9114+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
9115+{
1308ab2a 9116+ DiMustWriteLock(dentry);
5afbbe0d 9117+ /* dbwh can be outside of btop - bbot range */
1facf9fc 9118+ au_di(dentry)->di_bwh = bindex;
9119+}
9120+
9121+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
9122+{
1308ab2a 9123+ DiMustWriteLock(dentry);
1facf9fc 9124+ au_di(dentry)->di_bdiropq = bindex;
9125+}
9126+
9127+/* ---------------------------------------------------------------------- */
9128+
4a4d8108 9129+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 9130+static inline void au_digen_dec(struct dentry *d)
9131+{
e49829fe 9132+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 9133+}
9134+
4a4d8108 9135+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 9136+{
9137+ dentry->d_fsdata = NULL;
9138+}
9139+#else
4a4d8108
AM
9140+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
9141+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 9142+
9143+#endif /* __KERNEL__ */
9144+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
9145diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
9146--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 9147+++ linux/fs/aufs/dinfo.c 2017-07-29 12:14:25.899708630 +0200
e2f27e51 9148@@ -0,0 +1,553 @@
1facf9fc 9149+/*
a2654f78 9150+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 9151+ *
9152+ * This program, aufs is free software; you can redistribute it and/or modify
9153+ * it under the terms of the GNU General Public License as published by
9154+ * the Free Software Foundation; either version 2 of the License, or
9155+ * (at your option) any later version.
dece6358
AM
9156+ *
9157+ * This program is distributed in the hope that it will be useful,
9158+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9159+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9160+ * GNU General Public License for more details.
9161+ *
9162+ * You should have received a copy of the GNU General Public License
523b37e3 9163+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9164+ */
9165+
9166+/*
9167+ * dentry private data
9168+ */
9169+
9170+#include "aufs.h"
9171+
e49829fe 9172+void au_di_init_once(void *_dinfo)
4a4d8108 9173+{
e49829fe 9174+ struct au_dinfo *dinfo = _dinfo;
4a4d8108 9175+
e49829fe 9176+ au_rw_init(&dinfo->di_rwsem);
4a4d8108
AM
9177+}
9178+
027c5e7a 9179+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 9180+{
9181+ struct au_dinfo *dinfo;
027c5e7a 9182+ int nbr, i;
1facf9fc 9183+
9184+ dinfo = au_cache_alloc_dinfo();
9185+ if (unlikely(!dinfo))
9186+ goto out;
9187+
5afbbe0d 9188+ nbr = au_sbbot(sb) + 1;
1facf9fc 9189+ if (nbr <= 0)
9190+ nbr = 1;
9191+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
9192+ if (dinfo->di_hdentry) {
9193+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
5afbbe0d
AM
9194+ dinfo->di_btop = -1;
9195+ dinfo->di_bbot = -1;
027c5e7a
AM
9196+ dinfo->di_bwh = -1;
9197+ dinfo->di_bdiropq = -1;
38d290e6 9198+ dinfo->di_tmpfile = 0;
027c5e7a
AM
9199+ for (i = 0; i < nbr; i++)
9200+ dinfo->di_hdentry[i].hd_id = -1;
9201+ goto out;
9202+ }
1facf9fc 9203+
1c60b727 9204+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
9205+ dinfo = NULL;
9206+
4f0767ce 9207+out:
027c5e7a 9208+ return dinfo;
1facf9fc 9209+}
9210+
027c5e7a 9211+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 9212+{
4a4d8108 9213+ struct au_hdentry *p;
5afbbe0d 9214+ aufs_bindex_t bbot, bindex;
4a4d8108
AM
9215+
9216+ /* dentry may not be revalidated */
5afbbe0d 9217+ bindex = dinfo->di_btop;
4a4d8108 9218+ if (bindex >= 0) {
5afbbe0d
AM
9219+ bbot = dinfo->di_bbot;
9220+ p = au_hdentry(dinfo, bindex);
9221+ while (bindex++ <= bbot)
4a4d8108
AM
9222+ au_hdput(p++);
9223+ }
1c60b727
AM
9224+ kfree(dinfo->di_hdentry);
9225+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
9226+}
9227+
9228+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
9229+{
9230+ struct au_hdentry *p;
9231+ aufs_bindex_t bi;
9232+
9233+ AuRwMustWriteLock(&a->di_rwsem);
9234+ AuRwMustWriteLock(&b->di_rwsem);
9235+
9236+#define DiSwap(v, name) \
9237+ do { \
9238+ v = a->di_##name; \
9239+ a->di_##name = b->di_##name; \
9240+ b->di_##name = v; \
9241+ } while (0)
9242+
9243+ DiSwap(p, hdentry);
5afbbe0d
AM
9244+ DiSwap(bi, btop);
9245+ DiSwap(bi, bbot);
027c5e7a
AM
9246+ DiSwap(bi, bwh);
9247+ DiSwap(bi, bdiropq);
9248+ /* smp_mb(); */
9249+
9250+#undef DiSwap
9251+}
9252+
9253+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
9254+{
9255+ AuRwMustWriteLock(&dst->di_rwsem);
9256+ AuRwMustWriteLock(&src->di_rwsem);
9257+
5afbbe0d
AM
9258+ dst->di_btop = src->di_btop;
9259+ dst->di_bbot = src->di_bbot;
027c5e7a
AM
9260+ dst->di_bwh = src->di_bwh;
9261+ dst->di_bdiropq = src->di_bdiropq;
9262+ /* smp_mb(); */
9263+}
9264+
9265+int au_di_init(struct dentry *dentry)
9266+{
9267+ int err;
9268+ struct super_block *sb;
9269+ struct au_dinfo *dinfo;
9270+
9271+ err = 0;
9272+ sb = dentry->d_sb;
9273+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
9274+ if (dinfo) {
9275+ atomic_set(&dinfo->di_generation, au_sigen(sb));
9276+ /* smp_mb(); */ /* atomic_set */
9277+ dentry->d_fsdata = dinfo;
9278+ } else
9279+ err = -ENOMEM;
9280+
9281+ return err;
9282+}
9283+
9284+void au_di_fin(struct dentry *dentry)
9285+{
9286+ struct au_dinfo *dinfo;
9287+
9288+ dinfo = au_di(dentry);
9289+ AuRwDestroy(&dinfo->di_rwsem);
9290+ au_di_free(dinfo);
4a4d8108
AM
9291+}
9292+
e2f27e51 9293+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink)
1facf9fc 9294+{
9295+ int err, sz;
9296+ struct au_hdentry *hdp;
9297+
1308ab2a 9298+ AuRwMustWriteLock(&dinfo->di_rwsem);
9299+
1facf9fc 9300+ err = -ENOMEM;
5afbbe0d 9301+ sz = sizeof(*hdp) * (dinfo->di_bbot + 1);
1facf9fc 9302+ if (!sz)
9303+ sz = sizeof(*hdp);
e2f27e51
AM
9304+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS,
9305+ may_shrink);
1facf9fc 9306+ if (hdp) {
9307+ dinfo->di_hdentry = hdp;
9308+ err = 0;
9309+ }
9310+
9311+ return err;
9312+}
9313+
9314+/* ---------------------------------------------------------------------- */
9315+
9316+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
9317+{
9318+ switch (lsc) {
9319+ case AuLsc_DI_CHILD:
9320+ ii_write_lock_child(inode);
9321+ break;
9322+ case AuLsc_DI_CHILD2:
9323+ ii_write_lock_child2(inode);
9324+ break;
9325+ case AuLsc_DI_CHILD3:
9326+ ii_write_lock_child3(inode);
9327+ break;
9328+ case AuLsc_DI_PARENT:
9329+ ii_write_lock_parent(inode);
9330+ break;
9331+ case AuLsc_DI_PARENT2:
9332+ ii_write_lock_parent2(inode);
9333+ break;
9334+ case AuLsc_DI_PARENT3:
9335+ ii_write_lock_parent3(inode);
9336+ break;
9337+ default:
9338+ BUG();
9339+ }
9340+}
9341+
9342+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
9343+{
9344+ switch (lsc) {
9345+ case AuLsc_DI_CHILD:
9346+ ii_read_lock_child(inode);
9347+ break;
9348+ case AuLsc_DI_CHILD2:
9349+ ii_read_lock_child2(inode);
9350+ break;
9351+ case AuLsc_DI_CHILD3:
9352+ ii_read_lock_child3(inode);
9353+ break;
9354+ case AuLsc_DI_PARENT:
9355+ ii_read_lock_parent(inode);
9356+ break;
9357+ case AuLsc_DI_PARENT2:
9358+ ii_read_lock_parent2(inode);
9359+ break;
9360+ case AuLsc_DI_PARENT3:
9361+ ii_read_lock_parent3(inode);
9362+ break;
9363+ default:
9364+ BUG();
9365+ }
9366+}
9367+
9368+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
9369+{
5527c038
JR
9370+ struct inode *inode;
9371+
dece6358 9372+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
5527c038
JR
9373+ if (d_really_is_positive(d)) {
9374+ inode = d_inode(d);
1facf9fc 9375+ if (au_ftest_lock(flags, IW))
5527c038 9376+ do_ii_write_lock(inode, lsc);
1facf9fc 9377+ else if (au_ftest_lock(flags, IR))
5527c038 9378+ do_ii_read_lock(inode, lsc);
1facf9fc 9379+ }
9380+}
9381+
9382+void di_read_unlock(struct dentry *d, int flags)
9383+{
5527c038
JR
9384+ struct inode *inode;
9385+
9386+ if (d_really_is_positive(d)) {
9387+ inode = d_inode(d);
027c5e7a
AM
9388+ if (au_ftest_lock(flags, IW)) {
9389+ au_dbg_verify_dinode(d);
5527c038 9390+ ii_write_unlock(inode);
027c5e7a
AM
9391+ } else if (au_ftest_lock(flags, IR)) {
9392+ au_dbg_verify_dinode(d);
5527c038 9393+ ii_read_unlock(inode);
027c5e7a 9394+ }
1facf9fc 9395+ }
dece6358 9396+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 9397+}
9398+
9399+void di_downgrade_lock(struct dentry *d, int flags)
9400+{
5527c038
JR
9401+ if (d_really_is_positive(d) && au_ftest_lock(flags, IR))
9402+ ii_downgrade_lock(d_inode(d));
dece6358 9403+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 9404+}
9405+
9406+void di_write_lock(struct dentry *d, unsigned int lsc)
9407+{
dece6358 9408+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
5527c038
JR
9409+ if (d_really_is_positive(d))
9410+ do_ii_write_lock(d_inode(d), lsc);
1facf9fc 9411+}
9412+
9413+void di_write_unlock(struct dentry *d)
9414+{
027c5e7a 9415+ au_dbg_verify_dinode(d);
5527c038
JR
9416+ if (d_really_is_positive(d))
9417+ ii_write_unlock(d_inode(d));
dece6358 9418+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 9419+}
9420+
9421+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
9422+{
9423+ AuDebugOn(d1 == d2
5527c038 9424+ || d_inode(d1) == d_inode(d2)
1facf9fc 9425+ || d1->d_sb != d2->d_sb);
9426+
521ced18
JR
9427+ if ((isdir && au_test_subdir(d1, d2))
9428+ || d1 < d2) {
1facf9fc 9429+ di_write_lock_child(d1);
9430+ di_write_lock_child2(d2);
9431+ } else {
1facf9fc 9432+ di_write_lock_child(d2);
9433+ di_write_lock_child2(d1);
9434+ }
9435+}
9436+
9437+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
9438+{
9439+ AuDebugOn(d1 == d2
5527c038 9440+ || d_inode(d1) == d_inode(d2)
1facf9fc 9441+ || d1->d_sb != d2->d_sb);
9442+
521ced18
JR
9443+ if ((isdir && au_test_subdir(d1, d2))
9444+ || d1 < d2) {
1facf9fc 9445+ di_write_lock_parent(d1);
9446+ di_write_lock_parent2(d2);
9447+ } else {
1facf9fc 9448+ di_write_lock_parent(d2);
9449+ di_write_lock_parent2(d1);
9450+ }
9451+}
9452+
9453+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
9454+{
9455+ di_write_unlock(d1);
5527c038 9456+ if (d_inode(d1) == d_inode(d2))
dece6358 9457+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 9458+ else
9459+ di_write_unlock(d2);
9460+}
9461+
9462+/* ---------------------------------------------------------------------- */
9463+
9464+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
9465+{
9466+ struct dentry *d;
9467+
1308ab2a 9468+ DiMustAnyLock(dentry);
9469+
5afbbe0d 9470+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
1facf9fc 9471+ return NULL;
9472+ AuDebugOn(bindex < 0);
5afbbe0d 9473+ d = au_hdentry(au_di(dentry), bindex)->hd_dentry;
c1595e42 9474+ AuDebugOn(d && au_dcount(d) <= 0);
1facf9fc 9475+ return d;
9476+}
9477+
2cbb1c4b
JR
9478+/*
9479+ * extended version of au_h_dptr().
38d290e6
JR
9480+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
9481+ * error.
2cbb1c4b
JR
9482+ */
9483+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
9484+{
9485+ struct dentry *h_dentry;
9486+ struct inode *inode, *h_inode;
9487+
5527c038 9488+ AuDebugOn(d_really_is_negative(dentry));
2cbb1c4b
JR
9489+
9490+ h_dentry = NULL;
5afbbe0d
AM
9491+ if (au_dbtop(dentry) <= bindex
9492+ && bindex <= au_dbbot(dentry))
2cbb1c4b 9493+ h_dentry = au_h_dptr(dentry, bindex);
38d290e6 9494+ if (h_dentry && !au_d_linkable(h_dentry)) {
2cbb1c4b
JR
9495+ dget(h_dentry);
9496+ goto out; /* success */
9497+ }
9498+
5527c038 9499+ inode = d_inode(dentry);
5afbbe0d
AM
9500+ AuDebugOn(bindex < au_ibtop(inode));
9501+ AuDebugOn(au_ibbot(inode) < bindex);
2cbb1c4b
JR
9502+ h_inode = au_h_iptr(inode, bindex);
9503+ h_dentry = d_find_alias(h_inode);
9504+ if (h_dentry) {
9505+ if (!IS_ERR(h_dentry)) {
38d290e6 9506+ if (!au_d_linkable(h_dentry))
2cbb1c4b
JR
9507+ goto out; /* success */
9508+ dput(h_dentry);
9509+ } else
9510+ goto out;
9511+ }
9512+
9513+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
9514+ h_dentry = au_plink_lkup(inode, bindex);
9515+ AuDebugOn(!h_dentry);
9516+ if (!IS_ERR(h_dentry)) {
9517+ if (!au_d_hashed_positive(h_dentry))
9518+ goto out; /* success */
9519+ dput(h_dentry);
9520+ h_dentry = NULL;
9521+ }
9522+ }
9523+
9524+out:
9525+ AuDbgDentry(h_dentry);
9526+ return h_dentry;
9527+}
9528+
1facf9fc 9529+aufs_bindex_t au_dbtail(struct dentry *dentry)
9530+{
5afbbe0d 9531+ aufs_bindex_t bbot, bwh;
1facf9fc 9532+
5afbbe0d
AM
9533+ bbot = au_dbbot(dentry);
9534+ if (0 <= bbot) {
1facf9fc 9535+ bwh = au_dbwh(dentry);
9536+ if (!bwh)
9537+ return bwh;
5afbbe0d 9538+ if (0 < bwh && bwh < bbot)
1facf9fc 9539+ return bwh - 1;
9540+ }
5afbbe0d 9541+ return bbot;
1facf9fc 9542+}
9543+
9544+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
9545+{
5afbbe0d 9546+ aufs_bindex_t bbot, bopq;
1facf9fc 9547+
5afbbe0d
AM
9548+ bbot = au_dbtail(dentry);
9549+ if (0 <= bbot) {
1facf9fc 9550+ bopq = au_dbdiropq(dentry);
5afbbe0d
AM
9551+ if (0 <= bopq && bopq < bbot)
9552+ bbot = bopq;
1facf9fc 9553+ }
5afbbe0d 9554+ return bbot;
1facf9fc 9555+}
9556+
9557+/* ---------------------------------------------------------------------- */
9558+
9559+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9560+ struct dentry *h_dentry)
9561+{
5afbbe0d
AM
9562+ struct au_dinfo *dinfo;
9563+ struct au_hdentry *hd;
027c5e7a 9564+ struct au_branch *br;
1facf9fc 9565+
1308ab2a 9566+ DiMustWriteLock(dentry);
9567+
5afbbe0d
AM
9568+ dinfo = au_di(dentry);
9569+ hd = au_hdentry(dinfo, bindex);
4a4d8108 9570+ au_hdput(hd);
1facf9fc 9571+ hd->hd_dentry = h_dentry;
027c5e7a
AM
9572+ if (h_dentry) {
9573+ br = au_sbr(dentry->d_sb, bindex);
9574+ hd->hd_id = br->br_id;
9575+ }
9576+}
9577+
9578+int au_dbrange_test(struct dentry *dentry)
9579+{
9580+ int err;
5afbbe0d 9581+ aufs_bindex_t btop, bbot;
027c5e7a
AM
9582+
9583+ err = 0;
5afbbe0d
AM
9584+ btop = au_dbtop(dentry);
9585+ bbot = au_dbbot(dentry);
9586+ if (btop >= 0)
9587+ AuDebugOn(bbot < 0 && btop > bbot);
027c5e7a
AM
9588+ else {
9589+ err = -EIO;
5afbbe0d 9590+ AuDebugOn(bbot >= 0);
027c5e7a
AM
9591+ }
9592+
9593+ return err;
9594+}
9595+
9596+int au_digen_test(struct dentry *dentry, unsigned int sigen)
9597+{
9598+ int err;
9599+
9600+ err = 0;
9601+ if (unlikely(au_digen(dentry) != sigen
5527c038 9602+ || au_iigen_test(d_inode(dentry), sigen)))
027c5e7a
AM
9603+ err = -EIO;
9604+
9605+ return err;
1facf9fc 9606+}
9607+
9608+void au_update_digen(struct dentry *dentry)
9609+{
9610+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
9611+ /* smp_mb(); */ /* atomic_set */
9612+}
9613+
9614+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
9615+{
9616+ struct au_dinfo *dinfo;
9617+ struct dentry *h_d;
4a4d8108 9618+ struct au_hdentry *hdp;
5afbbe0d 9619+ aufs_bindex_t bindex, bbot;
1facf9fc 9620+
1308ab2a 9621+ DiMustWriteLock(dentry);
9622+
1facf9fc 9623+ dinfo = au_di(dentry);
5afbbe0d 9624+ if (!dinfo || dinfo->di_btop < 0)
1facf9fc 9625+ return;
9626+
9627+ if (do_put_zero) {
5afbbe0d
AM
9628+ bbot = dinfo->di_bbot;
9629+ bindex = dinfo->di_btop;
9630+ hdp = au_hdentry(dinfo, bindex);
9631+ for (; bindex <= bbot; bindex++, hdp++) {
9632+ h_d = hdp->hd_dentry;
5527c038 9633+ if (h_d && d_is_negative(h_d))
1facf9fc 9634+ au_set_h_dptr(dentry, bindex, NULL);
9635+ }
9636+ }
9637+
5afbbe0d
AM
9638+ dinfo->di_btop = 0;
9639+ hdp = au_hdentry(dinfo, dinfo->di_btop);
9640+ for (; dinfo->di_btop <= dinfo->di_bbot; dinfo->di_btop++, hdp++)
9641+ if (hdp->hd_dentry)
1facf9fc 9642+ break;
5afbbe0d
AM
9643+ if (dinfo->di_btop > dinfo->di_bbot) {
9644+ dinfo->di_btop = -1;
9645+ dinfo->di_bbot = -1;
1facf9fc 9646+ return;
9647+ }
9648+
5afbbe0d
AM
9649+ hdp = au_hdentry(dinfo, dinfo->di_bbot);
9650+ for (; dinfo->di_bbot >= 0; dinfo->di_bbot--, hdp--)
9651+ if (hdp->hd_dentry)
1facf9fc 9652+ break;
5afbbe0d 9653+ AuDebugOn(dinfo->di_btop > dinfo->di_bbot || dinfo->di_bbot < 0);
1facf9fc 9654+}
9655+
5afbbe0d 9656+void au_update_dbtop(struct dentry *dentry)
1facf9fc 9657+{
5afbbe0d 9658+ aufs_bindex_t bindex, bbot;
1facf9fc 9659+ struct dentry *h_dentry;
9660+
5afbbe0d
AM
9661+ bbot = au_dbbot(dentry);
9662+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) {
1facf9fc 9663+ h_dentry = au_h_dptr(dentry, bindex);
9664+ if (!h_dentry)
9665+ continue;
5527c038 9666+ if (d_is_positive(h_dentry)) {
5afbbe0d 9667+ au_set_dbtop(dentry, bindex);
1facf9fc 9668+ return;
9669+ }
9670+ au_set_h_dptr(dentry, bindex, NULL);
9671+ }
9672+}
9673+
5afbbe0d 9674+void au_update_dbbot(struct dentry *dentry)
1facf9fc 9675+{
5afbbe0d 9676+ aufs_bindex_t bindex, btop;
1facf9fc 9677+ struct dentry *h_dentry;
9678+
5afbbe0d
AM
9679+ btop = au_dbtop(dentry);
9680+ for (bindex = au_dbbot(dentry); bindex >= btop; bindex--) {
1facf9fc 9681+ h_dentry = au_h_dptr(dentry, bindex);
9682+ if (!h_dentry)
9683+ continue;
5527c038 9684+ if (d_is_positive(h_dentry)) {
5afbbe0d 9685+ au_set_dbbot(dentry, bindex);
1facf9fc 9686+ return;
9687+ }
9688+ au_set_h_dptr(dentry, bindex, NULL);
9689+ }
9690+}
9691+
9692+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
9693+{
5afbbe0d 9694+ aufs_bindex_t bindex, bbot;
1facf9fc 9695+
5afbbe0d
AM
9696+ bbot = au_dbbot(dentry);
9697+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++)
1facf9fc 9698+ if (au_h_dptr(dentry, bindex) == h_dentry)
9699+ return bindex;
9700+ return -1;
9701+}
7f207e10
AM
9702diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
9703--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
3c1bdaff 9704+++ linux/fs/aufs/dir.c 2017-09-05 10:42:11.058755349 +0200
1c60b727 9705@@ -0,0 +1,759 @@
1facf9fc 9706+/*
a2654f78 9707+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 9708+ *
9709+ * This program, aufs is free software; you can redistribute it and/or modify
9710+ * it under the terms of the GNU General Public License as published by
9711+ * the Free Software Foundation; either version 2 of the License, or
9712+ * (at your option) any later version.
dece6358
AM
9713+ *
9714+ * This program is distributed in the hope that it will be useful,
9715+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9716+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9717+ * GNU General Public License for more details.
9718+ *
9719+ * You should have received a copy of the GNU General Public License
523b37e3 9720+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9721+ */
9722+
9723+/*
9724+ * directory operations
9725+ */
9726+
9727+#include <linux/fs_stack.h>
9728+#include "aufs.h"
9729+
9730+void au_add_nlink(struct inode *dir, struct inode *h_dir)
9731+{
9dbd164d
AM
9732+ unsigned int nlink;
9733+
1facf9fc 9734+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9735+
9dbd164d
AM
9736+ nlink = dir->i_nlink;
9737+ nlink += h_dir->i_nlink - 2;
1facf9fc 9738+ if (h_dir->i_nlink < 2)
9dbd164d 9739+ nlink += 2;
f6b6e03d 9740+ smp_mb(); /* for i_nlink */
7eafdf33 9741+ /* 0 can happen in revaliding */
92d182d2 9742+ set_nlink(dir, nlink);
1facf9fc 9743+}
9744+
9745+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
9746+{
9dbd164d
AM
9747+ unsigned int nlink;
9748+
1facf9fc 9749+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9750+
9dbd164d
AM
9751+ nlink = dir->i_nlink;
9752+ nlink -= h_dir->i_nlink - 2;
1facf9fc 9753+ if (h_dir->i_nlink < 2)
9dbd164d 9754+ nlink -= 2;
f6b6e03d 9755+ smp_mb(); /* for i_nlink */
92d182d2 9756+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 9757+ set_nlink(dir, nlink);
1facf9fc 9758+}
9759+
1308ab2a 9760+loff_t au_dir_size(struct file *file, struct dentry *dentry)
9761+{
9762+ loff_t sz;
5afbbe0d 9763+ aufs_bindex_t bindex, bbot;
1308ab2a 9764+ struct file *h_file;
9765+ struct dentry *h_dentry;
9766+
9767+ sz = 0;
9768+ if (file) {
2000de60 9769+ AuDebugOn(!d_is_dir(file->f_path.dentry));
1308ab2a 9770+
5afbbe0d
AM
9771+ bbot = au_fbbot_dir(file);
9772+ for (bindex = au_fbtop(file);
9773+ bindex <= bbot && sz < KMALLOC_MAX_SIZE;
1308ab2a 9774+ bindex++) {
4a4d8108 9775+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
9776+ if (h_file && file_inode(h_file))
9777+ sz += vfsub_f_size_read(h_file);
1308ab2a 9778+ }
9779+ } else {
9780+ AuDebugOn(!dentry);
2000de60 9781+ AuDebugOn(!d_is_dir(dentry));
1308ab2a 9782+
5afbbe0d
AM
9783+ bbot = au_dbtaildir(dentry);
9784+ for (bindex = au_dbtop(dentry);
9785+ bindex <= bbot && sz < KMALLOC_MAX_SIZE;
1308ab2a 9786+ bindex++) {
9787+ h_dentry = au_h_dptr(dentry, bindex);
5527c038
JR
9788+ if (h_dentry && d_is_positive(h_dentry))
9789+ sz += i_size_read(d_inode(h_dentry));
1308ab2a 9790+ }
9791+ }
9792+ if (sz < KMALLOC_MAX_SIZE)
9793+ sz = roundup_pow_of_two(sz);
9794+ if (sz > KMALLOC_MAX_SIZE)
9795+ sz = KMALLOC_MAX_SIZE;
9796+ else if (sz < NAME_MAX) {
9797+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
9798+ sz = AUFS_RDBLK_DEF;
9799+ }
9800+ return sz;
9801+}
9802+
b912730e
AM
9803+struct au_dir_ts_arg {
9804+ struct dentry *dentry;
9805+ aufs_bindex_t brid;
9806+};
9807+
9808+static void au_do_dir_ts(void *arg)
9809+{
9810+ struct au_dir_ts_arg *a = arg;
9811+ struct au_dtime dt;
9812+ struct path h_path;
9813+ struct inode *dir, *h_dir;
9814+ struct super_block *sb;
9815+ struct au_branch *br;
9816+ struct au_hinode *hdir;
9817+ int err;
5afbbe0d 9818+ aufs_bindex_t btop, bindex;
b912730e
AM
9819+
9820+ sb = a->dentry->d_sb;
5527c038 9821+ if (d_really_is_negative(a->dentry))
b912730e 9822+ goto out;
5527c038 9823+ /* no dir->i_mutex lock */
b95c5147
AM
9824+ aufs_read_lock(a->dentry, AuLock_DW); /* noflush */
9825+
5527c038 9826+ dir = d_inode(a->dentry);
5afbbe0d 9827+ btop = au_ibtop(dir);
b912730e 9828+ bindex = au_br_index(sb, a->brid);
5afbbe0d 9829+ if (bindex < btop)
b912730e
AM
9830+ goto out_unlock;
9831+
9832+ br = au_sbr(sb, bindex);
9833+ h_path.dentry = au_h_dptr(a->dentry, bindex);
9834+ if (!h_path.dentry)
9835+ goto out_unlock;
9836+ h_path.mnt = au_br_mnt(br);
9837+ au_dtime_store(&dt, a->dentry, &h_path);
9838+
5afbbe0d 9839+ br = au_sbr(sb, btop);
b912730e
AM
9840+ if (!au_br_writable(br->br_perm))
9841+ goto out_unlock;
5afbbe0d 9842+ h_path.dentry = au_h_dptr(a->dentry, btop);
b912730e
AM
9843+ h_path.mnt = au_br_mnt(br);
9844+ err = vfsub_mnt_want_write(h_path.mnt);
9845+ if (err)
9846+ goto out_unlock;
5afbbe0d
AM
9847+ hdir = au_hi(dir, btop);
9848+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
9849+ h_dir = au_h_iptr(dir, btop);
b912730e
AM
9850+ if (h_dir->i_nlink
9851+ && timespec_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) {
9852+ dt.dt_h_path = h_path;
9853+ au_dtime_revert(&dt);
9854+ }
5afbbe0d 9855+ au_hn_inode_unlock(hdir);
b912730e
AM
9856+ vfsub_mnt_drop_write(h_path.mnt);
9857+ au_cpup_attr_timesizes(dir);
9858+
9859+out_unlock:
9860+ aufs_read_unlock(a->dentry, AuLock_DW);
9861+out:
9862+ dput(a->dentry);
9863+ au_nwt_done(&au_sbi(sb)->si_nowait);
1c60b727 9864+ kfree(arg);
b912730e
AM
9865+}
9866+
9867+void au_dir_ts(struct inode *dir, aufs_bindex_t bindex)
9868+{
9869+ int perm, wkq_err;
5afbbe0d 9870+ aufs_bindex_t btop;
b912730e
AM
9871+ struct au_dir_ts_arg *arg;
9872+ struct dentry *dentry;
9873+ struct super_block *sb;
9874+
9875+ IMustLock(dir);
9876+
9877+ dentry = d_find_any_alias(dir);
9878+ AuDebugOn(!dentry);
9879+ sb = dentry->d_sb;
5afbbe0d
AM
9880+ btop = au_ibtop(dir);
9881+ if (btop == bindex) {
b912730e
AM
9882+ au_cpup_attr_timesizes(dir);
9883+ goto out;
9884+ }
9885+
5afbbe0d 9886+ perm = au_sbr_perm(sb, btop);
b912730e
AM
9887+ if (!au_br_writable(perm))
9888+ goto out;
9889+
9890+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
9891+ if (!arg)
9892+ goto out;
9893+
9894+ arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */
9895+ arg->brid = au_sbr_id(sb, bindex);
9896+ wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0);
9897+ if (unlikely(wkq_err)) {
9898+ pr_err("wkq %d\n", wkq_err);
9899+ dput(dentry);
1c60b727 9900+ kfree(arg);
b912730e
AM
9901+ }
9902+
9903+out:
9904+ dput(dentry);
9905+}
9906+
1facf9fc 9907+/* ---------------------------------------------------------------------- */
9908+
9909+static int reopen_dir(struct file *file)
9910+{
9911+ int err;
9912+ unsigned int flags;
5afbbe0d 9913+ aufs_bindex_t bindex, btail, btop;
1facf9fc 9914+ struct dentry *dentry, *h_dentry;
9915+ struct file *h_file;
9916+
9917+ /* open all lower dirs */
2000de60 9918+ dentry = file->f_path.dentry;
5afbbe0d
AM
9919+ btop = au_dbtop(dentry);
9920+ for (bindex = au_fbtop(file); bindex < btop; bindex++)
1facf9fc 9921+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d 9922+ au_set_fbtop(file, btop);
1facf9fc 9923+
9924+ btail = au_dbtaildir(dentry);
5afbbe0d 9925+ for (bindex = au_fbbot_dir(file); btail < bindex; bindex--)
1facf9fc 9926+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d 9927+ au_set_fbbot_dir(file, btail);
1facf9fc 9928+
4a4d8108 9929+ flags = vfsub_file_flags(file);
5afbbe0d 9930+ for (bindex = btop; bindex <= btail; bindex++) {
1facf9fc 9931+ h_dentry = au_h_dptr(dentry, bindex);
9932+ if (!h_dentry)
9933+ continue;
4a4d8108 9934+ h_file = au_hf_dir(file, bindex);
1facf9fc 9935+ if (h_file)
9936+ continue;
9937+
392086de 9938+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9939+ err = PTR_ERR(h_file);
9940+ if (IS_ERR(h_file))
9941+ goto out; /* close all? */
9942+ au_set_h_fptr(file, bindex, h_file);
9943+ }
9944+ au_update_figen(file);
9945+ /* todo: necessary? */
9946+ /* file->f_ra = h_file->f_ra; */
9947+ err = 0;
9948+
4f0767ce 9949+out:
1facf9fc 9950+ return err;
9951+}
9952+
b912730e 9953+static int do_open_dir(struct file *file, int flags, struct file *h_file)
1facf9fc 9954+{
9955+ int err;
9956+ aufs_bindex_t bindex, btail;
9957+ struct dentry *dentry, *h_dentry;
8cdd5066 9958+ struct vfsmount *mnt;
1facf9fc 9959+
1308ab2a 9960+ FiMustWriteLock(file);
b912730e 9961+ AuDebugOn(h_file);
1308ab2a 9962+
523b37e3 9963+ err = 0;
8cdd5066 9964+ mnt = file->f_path.mnt;
2000de60 9965+ dentry = file->f_path.dentry;
5527c038 9966+ file->f_version = d_inode(dentry)->i_version;
5afbbe0d
AM
9967+ bindex = au_dbtop(dentry);
9968+ au_set_fbtop(file, bindex);
1facf9fc 9969+ btail = au_dbtaildir(dentry);
5afbbe0d 9970+ au_set_fbbot_dir(file, btail);
1facf9fc 9971+ for (; !err && bindex <= btail; bindex++) {
9972+ h_dentry = au_h_dptr(dentry, bindex);
9973+ if (!h_dentry)
9974+ continue;
9975+
8cdd5066
JR
9976+ err = vfsub_test_mntns(mnt, h_dentry->d_sb);
9977+ if (unlikely(err))
9978+ break;
392086de 9979+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9980+ if (IS_ERR(h_file)) {
9981+ err = PTR_ERR(h_file);
9982+ break;
9983+ }
9984+ au_set_h_fptr(file, bindex, h_file);
9985+ }
9986+ au_update_figen(file);
9987+ /* todo: necessary? */
9988+ /* file->f_ra = h_file->f_ra; */
9989+ if (!err)
9990+ return 0; /* success */
9991+
9992+ /* close all */
5afbbe0d 9993+ for (bindex = au_fbtop(file); bindex <= btail; bindex++)
1facf9fc 9994+ au_set_h_fptr(file, bindex, NULL);
5afbbe0d
AM
9995+ au_set_fbtop(file, -1);
9996+ au_set_fbbot_dir(file, -1);
4a4d8108 9997+
1facf9fc 9998+ return err;
9999+}
10000+
10001+static int aufs_open_dir(struct inode *inode __maybe_unused,
10002+ struct file *file)
10003+{
4a4d8108
AM
10004+ int err;
10005+ struct super_block *sb;
10006+ struct au_fidir *fidir;
10007+
10008+ err = -ENOMEM;
2000de60 10009+ sb = file->f_path.dentry->d_sb;
4a4d8108 10010+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 10011+ fidir = au_fidir_alloc(sb);
4a4d8108 10012+ if (fidir) {
b912730e
AM
10013+ struct au_do_open_args args = {
10014+ .open = do_open_dir,
10015+ .fidir = fidir
10016+ };
10017+ err = au_do_open(file, &args);
4a4d8108 10018+ if (unlikely(err))
1c60b727 10019+ kfree(fidir);
4a4d8108
AM
10020+ }
10021+ si_read_unlock(sb);
10022+ return err;
1facf9fc 10023+}
10024+
10025+static int aufs_release_dir(struct inode *inode __maybe_unused,
10026+ struct file *file)
10027+{
10028+ struct au_vdir *vdir_cache;
4a4d8108
AM
10029+ struct au_finfo *finfo;
10030+ struct au_fidir *fidir;
f0c0a007 10031+ struct au_hfile *hf;
5afbbe0d 10032+ aufs_bindex_t bindex, bbot;
1facf9fc 10033+
4a4d8108
AM
10034+ finfo = au_fi(file);
10035+ fidir = finfo->fi_hdir;
10036+ if (fidir) {
076b876e 10037+ au_sphl_del(&finfo->fi_hlist,
2000de60 10038+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108
AM
10039+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
10040+ if (vdir_cache)
1c60b727 10041+ au_vdir_free(vdir_cache);
4a4d8108
AM
10042+
10043+ bindex = finfo->fi_btop;
10044+ if (bindex >= 0) {
f0c0a007 10045+ hf = fidir->fd_hfile + bindex;
4a4d8108
AM
10046+ /*
10047+ * calls fput() instead of filp_close(),
10048+ * since no dnotify or lock for the lower file.
10049+ */
5afbbe0d 10050+ bbot = fidir->fd_bbot;
f0c0a007
AM
10051+ for (; bindex <= bbot; bindex++, hf++)
10052+ if (hf->hf_file)
1c60b727 10053+ au_hfput(hf, /*execed*/0);
4a4d8108 10054+ }
1c60b727 10055+ kfree(fidir);
4a4d8108 10056+ finfo->fi_hdir = NULL;
1facf9fc 10057+ }
1c60b727 10058+ au_finfo_fin(file);
1facf9fc 10059+ return 0;
10060+}
10061+
10062+/* ---------------------------------------------------------------------- */
10063+
4a4d8108
AM
10064+static int au_do_flush_dir(struct file *file, fl_owner_t id)
10065+{
10066+ int err;
5afbbe0d 10067+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
10068+ struct file *h_file;
10069+
10070+ err = 0;
5afbbe0d
AM
10071+ bbot = au_fbbot_dir(file);
10072+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) {
4a4d8108
AM
10073+ h_file = au_hf_dir(file, bindex);
10074+ if (h_file)
10075+ err = vfsub_flush(h_file, id);
10076+ }
10077+ return err;
10078+}
10079+
10080+static int aufs_flush_dir(struct file *file, fl_owner_t id)
10081+{
10082+ return au_do_flush(file, id, au_do_flush_dir);
10083+}
10084+
10085+/* ---------------------------------------------------------------------- */
10086+
1facf9fc 10087+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
10088+{
10089+ int err;
5afbbe0d 10090+ aufs_bindex_t bbot, bindex;
1facf9fc 10091+ struct inode *inode;
10092+ struct super_block *sb;
10093+
10094+ err = 0;
10095+ sb = dentry->d_sb;
5527c038 10096+ inode = d_inode(dentry);
1facf9fc 10097+ IMustLock(inode);
5afbbe0d
AM
10098+ bbot = au_dbbot(dentry);
10099+ for (bindex = au_dbtop(dentry); !err && bindex <= bbot; bindex++) {
1facf9fc 10100+ struct path h_path;
1facf9fc 10101+
10102+ if (au_test_ro(sb, bindex, inode))
10103+ continue;
10104+ h_path.dentry = au_h_dptr(dentry, bindex);
10105+ if (!h_path.dentry)
10106+ continue;
1facf9fc 10107+
1facf9fc 10108+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 10109+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 10110+ }
10111+
10112+ return err;
10113+}
10114+
10115+static int au_do_fsync_dir(struct file *file, int datasync)
10116+{
10117+ int err;
5afbbe0d 10118+ aufs_bindex_t bbot, bindex;
1facf9fc 10119+ struct file *h_file;
10120+ struct super_block *sb;
10121+ struct inode *inode;
1facf9fc 10122+
521ced18 10123+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0);
1facf9fc 10124+ if (unlikely(err))
10125+ goto out;
10126+
c06a8ce3 10127+ inode = file_inode(file);
b912730e 10128+ sb = inode->i_sb;
5afbbe0d
AM
10129+ bbot = au_fbbot_dir(file);
10130+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) {
4a4d8108 10131+ h_file = au_hf_dir(file, bindex);
1facf9fc 10132+ if (!h_file || au_test_ro(sb, bindex, inode))
10133+ continue;
10134+
53392da6 10135+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 10136+ }
10137+
4f0767ce 10138+out:
1facf9fc 10139+ return err;
10140+}
10141+
10142+/*
10143+ * @file may be NULL
10144+ */
1e00d052
AM
10145+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
10146+ int datasync)
1facf9fc 10147+{
10148+ int err;
b752ccd1 10149+ struct dentry *dentry;
5527c038 10150+ struct inode *inode;
1facf9fc 10151+ struct super_block *sb;
1facf9fc 10152+
10153+ err = 0;
2000de60 10154+ dentry = file->f_path.dentry;
5527c038 10155+ inode = d_inode(dentry);
febd17d6 10156+ inode_lock(inode);
1facf9fc 10157+ sb = dentry->d_sb;
10158+ si_noflush_read_lock(sb);
10159+ if (file)
10160+ err = au_do_fsync_dir(file, datasync);
10161+ else {
10162+ di_write_lock_child(dentry);
10163+ err = au_do_fsync_dir_no_file(dentry, datasync);
10164+ }
5527c038 10165+ au_cpup_attr_timesizes(inode);
1facf9fc 10166+ di_write_unlock(dentry);
10167+ if (file)
10168+ fi_write_unlock(file);
10169+
10170+ si_read_unlock(sb);
febd17d6 10171+ inode_unlock(inode);
1facf9fc 10172+ return err;
10173+}
10174+
10175+/* ---------------------------------------------------------------------- */
10176+
5afbbe0d 10177+static int aufs_iterate_shared(struct file *file, struct dir_context *ctx)
1facf9fc 10178+{
10179+ int err;
10180+ struct dentry *dentry;
9dbd164d 10181+ struct inode *inode, *h_inode;
1facf9fc 10182+ struct super_block *sb;
10183+
523b37e3 10184+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 10185+
2000de60 10186+ dentry = file->f_path.dentry;
5527c038 10187+ inode = d_inode(dentry);
1facf9fc 10188+ IMustLock(inode);
10189+
10190+ sb = dentry->d_sb;
10191+ si_read_lock(sb, AuLock_FLUSH);
521ced18 10192+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0);
1facf9fc 10193+ if (unlikely(err))
10194+ goto out;
027c5e7a
AM
10195+ err = au_alive_dir(dentry);
10196+ if (!err)
10197+ err = au_vdir_init(file);
1facf9fc 10198+ di_downgrade_lock(dentry, AuLock_IR);
10199+ if (unlikely(err))
10200+ goto out_unlock;
10201+
5afbbe0d 10202+ h_inode = au_h_iptr(inode, au_ibtop(inode));
b752ccd1 10203+ if (!au_test_nfsd()) {
392086de 10204+ err = au_vdir_fill_de(file, ctx);
9dbd164d 10205+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 10206+ } else {
10207+ /*
10208+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
10209+ * encode_fh() and others.
10210+ */
9dbd164d 10211+ atomic_inc(&h_inode->i_count);
1facf9fc 10212+ di_read_unlock(dentry, AuLock_IR);
10213+ si_read_unlock(sb);
392086de 10214+ err = au_vdir_fill_de(file, ctx);
1facf9fc 10215+ fsstack_copy_attr_atime(inode, h_inode);
10216+ fi_write_unlock(file);
9dbd164d 10217+ iput(h_inode);
1facf9fc 10218+
10219+ AuTraceErr(err);
10220+ return err;
10221+ }
10222+
4f0767ce 10223+out_unlock:
1facf9fc 10224+ di_read_unlock(dentry, AuLock_IR);
10225+ fi_write_unlock(file);
4f0767ce 10226+out:
1facf9fc 10227+ si_read_unlock(sb);
10228+ return err;
10229+}
10230+
10231+/* ---------------------------------------------------------------------- */
10232+
10233+#define AuTestEmpty_WHONLY 1
dece6358
AM
10234+#define AuTestEmpty_CALLED (1 << 1)
10235+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 10236+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
10237+#define au_fset_testempty(flags, name) \
10238+ do { (flags) |= AuTestEmpty_##name; } while (0)
10239+#define au_fclr_testempty(flags, name) \
10240+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 10241+
dece6358
AM
10242+#ifndef CONFIG_AUFS_SHWH
10243+#undef AuTestEmpty_SHWH
10244+#define AuTestEmpty_SHWH 0
10245+#endif
10246+
1facf9fc 10247+struct test_empty_arg {
392086de 10248+ struct dir_context ctx;
1308ab2a 10249+ struct au_nhash *whlist;
1facf9fc 10250+ unsigned int flags;
10251+ int err;
10252+ aufs_bindex_t bindex;
10253+};
10254+
392086de
AM
10255+static int test_empty_cb(struct dir_context *ctx, const char *__name,
10256+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 10257+ unsigned int d_type)
1facf9fc 10258+{
392086de
AM
10259+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
10260+ ctx);
1facf9fc 10261+ char *name = (void *)__name;
10262+
10263+ arg->err = 0;
10264+ au_fset_testempty(arg->flags, CALLED);
10265+ /* smp_mb(); */
10266+ if (name[0] == '.'
10267+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
10268+ goto out; /* success */
10269+
10270+ if (namelen <= AUFS_WH_PFX_LEN
10271+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
10272+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 10273+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 10274+ arg->err = -ENOTEMPTY;
10275+ goto out;
10276+ }
10277+
10278+ name += AUFS_WH_PFX_LEN;
10279+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 10280+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 10281+ arg->err = au_nhash_append_wh
1308ab2a 10282+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 10283+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 10284+
4f0767ce 10285+out:
1facf9fc 10286+ /* smp_mb(); */
10287+ AuTraceErr(arg->err);
10288+ return arg->err;
10289+}
10290+
10291+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
10292+{
10293+ int err;
10294+ struct file *h_file;
10295+
10296+ h_file = au_h_open(dentry, arg->bindex,
10297+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 10298+ /*file*/NULL, /*force_wr*/0);
1facf9fc 10299+ err = PTR_ERR(h_file);
10300+ if (IS_ERR(h_file))
10301+ goto out;
10302+
10303+ err = 0;
10304+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 10305+ && !file_inode(h_file)->i_nlink)
1facf9fc 10306+ goto out_put;
10307+
10308+ do {
10309+ arg->err = 0;
10310+ au_fclr_testempty(arg->flags, CALLED);
10311+ /* smp_mb(); */
392086de 10312+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 10313+ if (err >= 0)
10314+ err = arg->err;
10315+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
10316+
4f0767ce 10317+out_put:
1facf9fc 10318+ fput(h_file);
10319+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 10320+out:
1facf9fc 10321+ return err;
10322+}
10323+
10324+struct do_test_empty_args {
10325+ int *errp;
10326+ struct dentry *dentry;
10327+ struct test_empty_arg *arg;
10328+};
10329+
10330+static void call_do_test_empty(void *args)
10331+{
10332+ struct do_test_empty_args *a = args;
10333+ *a->errp = do_test_empty(a->dentry, a->arg);
10334+}
10335+
10336+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
10337+{
10338+ int err, wkq_err;
10339+ struct dentry *h_dentry;
10340+ struct inode *h_inode;
10341+
10342+ h_dentry = au_h_dptr(dentry, arg->bindex);
5527c038 10343+ h_inode = d_inode(h_dentry);
53392da6 10344+ /* todo: i_mode changes anytime? */
3c1bdaff 10345+ vfsub_inode_lock_shared_nested(h_inode, AuLsc_I_CHILD);
1facf9fc 10346+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
3c1bdaff 10347+ inode_unlock_shared(h_inode);
1facf9fc 10348+ if (!err)
10349+ err = do_test_empty(dentry, arg);
10350+ else {
10351+ struct do_test_empty_args args = {
10352+ .errp = &err,
10353+ .dentry = dentry,
10354+ .arg = arg
10355+ };
10356+ unsigned int flags = arg->flags;
10357+
10358+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
10359+ if (unlikely(wkq_err))
10360+ err = wkq_err;
10361+ arg->flags = flags;
10362+ }
10363+
10364+ return err;
10365+}
10366+
10367+int au_test_empty_lower(struct dentry *dentry)
10368+{
10369+ int err;
1308ab2a 10370+ unsigned int rdhash;
5afbbe0d 10371+ aufs_bindex_t bindex, btop, btail;
1308ab2a 10372+ struct au_nhash whlist;
392086de
AM
10373+ struct test_empty_arg arg = {
10374+ .ctx = {
2000de60 10375+ .actor = test_empty_cb
392086de
AM
10376+ }
10377+ };
076b876e 10378+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
1facf9fc 10379+
dece6358
AM
10380+ SiMustAnyLock(dentry->d_sb);
10381+
1308ab2a 10382+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
10383+ if (!rdhash)
10384+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
10385+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 10386+ if (unlikely(err))
1facf9fc 10387+ goto out;
10388+
1facf9fc 10389+ arg.flags = 0;
1308ab2a 10390+ arg.whlist = &whlist;
5afbbe0d 10391+ btop = au_dbtop(dentry);
dece6358
AM
10392+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10393+ au_fset_testempty(arg.flags, SHWH);
076b876e
AM
10394+ test_empty = do_test_empty;
10395+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
10396+ test_empty = sio_test_empty;
5afbbe0d 10397+ arg.bindex = btop;
076b876e 10398+ err = test_empty(dentry, &arg);
1facf9fc 10399+ if (unlikely(err))
10400+ goto out_whlist;
10401+
10402+ au_fset_testempty(arg.flags, WHONLY);
10403+ btail = au_dbtaildir(dentry);
5afbbe0d 10404+ for (bindex = btop + 1; !err && bindex <= btail; bindex++) {
1facf9fc 10405+ struct dentry *h_dentry;
10406+
10407+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 10408+ if (h_dentry && d_is_positive(h_dentry)) {
1facf9fc 10409+ arg.bindex = bindex;
076b876e 10410+ err = test_empty(dentry, &arg);
1facf9fc 10411+ }
10412+ }
10413+
4f0767ce 10414+out_whlist:
1308ab2a 10415+ au_nhash_wh_free(&whlist);
4f0767ce 10416+out:
1facf9fc 10417+ return err;
10418+}
10419+
10420+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
10421+{
10422+ int err;
392086de
AM
10423+ struct test_empty_arg arg = {
10424+ .ctx = {
2000de60 10425+ .actor = test_empty_cb
392086de
AM
10426+ }
10427+ };
1facf9fc 10428+ aufs_bindex_t bindex, btail;
10429+
10430+ err = 0;
1308ab2a 10431+ arg.whlist = whlist;
1facf9fc 10432+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
10433+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10434+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 10435+ btail = au_dbtaildir(dentry);
5afbbe0d 10436+ for (bindex = au_dbtop(dentry); !err && bindex <= btail; bindex++) {
1facf9fc 10437+ struct dentry *h_dentry;
10438+
10439+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 10440+ if (h_dentry && d_is_positive(h_dentry)) {
1facf9fc 10441+ arg.bindex = bindex;
10442+ err = sio_test_empty(dentry, &arg);
10443+ }
10444+ }
10445+
10446+ return err;
10447+}
10448+
10449+/* ---------------------------------------------------------------------- */
10450+
10451+const struct file_operations aufs_dir_fop = {
4a4d8108 10452+ .owner = THIS_MODULE,
027c5e7a 10453+ .llseek = default_llseek,
1facf9fc 10454+ .read = generic_read_dir,
5afbbe0d 10455+ .iterate_shared = aufs_iterate_shared,
1facf9fc 10456+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
10457+#ifdef CONFIG_COMPAT
10458+ .compat_ioctl = aufs_compat_ioctl_dir,
10459+#endif
1facf9fc 10460+ .open = aufs_open_dir,
10461+ .release = aufs_release_dir,
4a4d8108 10462+ .flush = aufs_flush_dir,
1facf9fc 10463+ .fsync = aufs_fsync_dir
10464+};
7f207e10
AM
10465diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
10466--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
10467+++ linux/fs/aufs/dir.h 2017-07-29 12:14:25.899708630 +0200
10468@@ -0,0 +1,131 @@
1facf9fc 10469+/*
a2654f78 10470+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 10471+ *
10472+ * This program, aufs is free software; you can redistribute it and/or modify
10473+ * it under the terms of the GNU General Public License as published by
10474+ * the Free Software Foundation; either version 2 of the License, or
10475+ * (at your option) any later version.
dece6358
AM
10476+ *
10477+ * This program is distributed in the hope that it will be useful,
10478+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10479+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10480+ * GNU General Public License for more details.
10481+ *
10482+ * You should have received a copy of the GNU General Public License
523b37e3 10483+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10484+ */
10485+
10486+/*
10487+ * directory operations
10488+ */
10489+
10490+#ifndef __AUFS_DIR_H__
10491+#define __AUFS_DIR_H__
10492+
10493+#ifdef __KERNEL__
10494+
10495+#include <linux/fs.h>
1facf9fc 10496+
10497+/* ---------------------------------------------------------------------- */
10498+
10499+/* need to be faster and smaller */
10500+
10501+struct au_nhash {
dece6358
AM
10502+ unsigned int nh_num;
10503+ struct hlist_head *nh_head;
1facf9fc 10504+};
10505+
10506+struct au_vdir_destr {
10507+ unsigned char len;
10508+ unsigned char name[0];
10509+} __packed;
10510+
10511+struct au_vdir_dehstr {
10512+ struct hlist_node hash;
1c60b727 10513+ struct au_vdir_destr *str;
4a4d8108 10514+} ____cacheline_aligned_in_smp;
1facf9fc 10515+
10516+struct au_vdir_de {
10517+ ino_t de_ino;
10518+ unsigned char de_type;
10519+ /* caution: packed */
10520+ struct au_vdir_destr de_str;
10521+} __packed;
10522+
10523+struct au_vdir_wh {
10524+ struct hlist_node wh_hash;
dece6358
AM
10525+#ifdef CONFIG_AUFS_SHWH
10526+ ino_t wh_ino;
1facf9fc 10527+ aufs_bindex_t wh_bindex;
dece6358
AM
10528+ unsigned char wh_type;
10529+#else
10530+ aufs_bindex_t wh_bindex;
10531+#endif
10532+ /* caution: packed */
1facf9fc 10533+ struct au_vdir_destr wh_str;
10534+} __packed;
10535+
10536+union au_vdir_deblk_p {
10537+ unsigned char *deblk;
10538+ struct au_vdir_de *de;
10539+};
10540+
10541+struct au_vdir {
10542+ unsigned char **vd_deblk;
10543+ unsigned long vd_nblk;
1facf9fc 10544+ struct {
10545+ unsigned long ul;
10546+ union au_vdir_deblk_p p;
10547+ } vd_last;
10548+
10549+ unsigned long vd_version;
dece6358 10550+ unsigned int vd_deblk_sz;
1c60b727 10551+ unsigned long vd_jiffy;
4a4d8108 10552+} ____cacheline_aligned_in_smp;
1facf9fc 10553+
10554+/* ---------------------------------------------------------------------- */
10555+
10556+/* dir.c */
10557+extern const struct file_operations aufs_dir_fop;
10558+void au_add_nlink(struct inode *dir, struct inode *h_dir);
10559+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 10560+loff_t au_dir_size(struct file *file, struct dentry *dentry);
b912730e 10561+void au_dir_ts(struct inode *dir, aufs_bindex_t bsrc);
1facf9fc 10562+int au_test_empty_lower(struct dentry *dentry);
10563+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
10564+
10565+/* vdir.c */
1308ab2a 10566+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
10567+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
10568+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 10569+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
10570+ int limit);
dece6358
AM
10571+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
10572+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
10573+ unsigned int d_type, aufs_bindex_t bindex,
10574+ unsigned char shwh);
1c60b727 10575+void au_vdir_free(struct au_vdir *vdir);
1facf9fc 10576+int au_vdir_init(struct file *file);
392086de 10577+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 10578+
10579+/* ioctl.c */
10580+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
10581+
1308ab2a 10582+#ifdef CONFIG_AUFS_RDU
10583+/* rdu.c */
10584+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
10585+#ifdef CONFIG_COMPAT
10586+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
10587+ unsigned long arg);
10588+#endif
1308ab2a 10589+#else
c1595e42
JR
10590+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file,
10591+ unsigned int cmd, unsigned long arg)
b752ccd1 10592+#ifdef CONFIG_COMPAT
c1595e42
JR
10593+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file,
10594+ unsigned int cmd, unsigned long arg)
b752ccd1 10595+#endif
1308ab2a 10596+#endif
10597+
1facf9fc 10598+#endif /* __KERNEL__ */
10599+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
10600diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
10601--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 10602+++ linux/fs/aufs/dynop.c 2017-07-29 12:14:25.899708630 +0200
e2f27e51 10603@@ -0,0 +1,371 @@
1facf9fc 10604+/*
a2654f78 10605+ * Copyright (C) 2010-2017 Junjiro R. Okajima
1facf9fc 10606+ *
10607+ * This program, aufs is free software; you can redistribute it and/or modify
10608+ * it under the terms of the GNU General Public License as published by
10609+ * the Free Software Foundation; either version 2 of the License, or
10610+ * (at your option) any later version.
dece6358
AM
10611+ *
10612+ * This program is distributed in the hope that it will be useful,
10613+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10614+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10615+ * GNU General Public License for more details.
10616+ *
10617+ * You should have received a copy of the GNU General Public License
523b37e3 10618+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10619+ */
10620+
10621+/*
4a4d8108 10622+ * dynamically customizable operations for regular files
1facf9fc 10623+ */
10624+
1facf9fc 10625+#include "aufs.h"
10626+
4a4d8108 10627+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 10628+
4a4d8108
AM
10629+/*
10630+ * How large will these lists be?
10631+ * Usually just a few elements, 20-30 at most for each, I guess.
10632+ */
f0c0a007 10633+static struct au_sphlhead dynop[AuDyLast];
4a4d8108 10634+
f0c0a007 10635+static struct au_dykey *dy_gfind_get(struct au_sphlhead *sphl, const void *h_op)
1facf9fc 10636+{
4a4d8108 10637+ struct au_dykey *key, *tmp;
f0c0a007 10638+ struct hlist_head *head;
1facf9fc 10639+
4a4d8108 10640+ key = NULL;
f0c0a007 10641+ head = &sphl->head;
4a4d8108 10642+ rcu_read_lock();
f0c0a007 10643+ hlist_for_each_entry_rcu(tmp, head, dk_hnode)
4a4d8108
AM
10644+ if (tmp->dk_op.dy_hop == h_op) {
10645+ key = tmp;
10646+ kref_get(&key->dk_kref);
10647+ break;
10648+ }
10649+ rcu_read_unlock();
10650+
10651+ return key;
1facf9fc 10652+}
10653+
4a4d8108 10654+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 10655+{
4a4d8108
AM
10656+ struct au_dykey **k, *found;
10657+ const void *h_op = key->dk_op.dy_hop;
10658+ int i;
1facf9fc 10659+
4a4d8108
AM
10660+ found = NULL;
10661+ k = br->br_dykey;
10662+ for (i = 0; i < AuBrDynOp; i++)
10663+ if (k[i]) {
10664+ if (k[i]->dk_op.dy_hop == h_op) {
10665+ found = k[i];
10666+ break;
10667+ }
10668+ } else
10669+ break;
10670+ if (!found) {
10671+ spin_lock(&br->br_dykey_lock);
10672+ for (; i < AuBrDynOp; i++)
10673+ if (k[i]) {
10674+ if (k[i]->dk_op.dy_hop == h_op) {
10675+ found = k[i];
10676+ break;
10677+ }
10678+ } else {
10679+ k[i] = key;
10680+ break;
10681+ }
10682+ spin_unlock(&br->br_dykey_lock);
10683+ BUG_ON(i == AuBrDynOp); /* expand the array */
10684+ }
10685+
10686+ return found;
1facf9fc 10687+}
10688+
4a4d8108 10689+/* kref_get() if @key is already added */
f0c0a007 10690+static struct au_dykey *dy_gadd(struct au_sphlhead *sphl, struct au_dykey *key)
4a4d8108
AM
10691+{
10692+ struct au_dykey *tmp, *found;
f0c0a007 10693+ struct hlist_head *head;
4a4d8108 10694+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 10695+
4a4d8108 10696+ found = NULL;
f0c0a007
AM
10697+ head = &sphl->head;
10698+ spin_lock(&sphl->spin);
10699+ hlist_for_each_entry(tmp, head, dk_hnode)
4a4d8108
AM
10700+ if (tmp->dk_op.dy_hop == h_op) {
10701+ kref_get(&tmp->dk_kref);
10702+ found = tmp;
10703+ break;
10704+ }
10705+ if (!found)
f0c0a007
AM
10706+ hlist_add_head_rcu(&key->dk_hnode, head);
10707+ spin_unlock(&sphl->spin);
1facf9fc 10708+
4a4d8108
AM
10709+ if (!found)
10710+ DyPrSym(key);
10711+ return found;
10712+}
10713+
10714+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 10715+{
4a4d8108
AM
10716+ struct au_dykey *key;
10717+
10718+ key = container_of(rcu, struct au_dykey, dk_rcu);
10719+ DyPrSym(key);
1c60b727 10720+ kfree(key);
1facf9fc 10721+}
10722+
4a4d8108
AM
10723+static void dy_free(struct kref *kref)
10724+{
10725+ struct au_dykey *key;
f0c0a007 10726+ struct au_sphlhead *sphl;
1facf9fc 10727+
4a4d8108 10728+ key = container_of(kref, struct au_dykey, dk_kref);
f0c0a007
AM
10729+ sphl = dynop + key->dk_op.dy_type;
10730+ au_sphl_del_rcu(&key->dk_hnode, sphl);
4a4d8108
AM
10731+ call_rcu(&key->dk_rcu, dy_free_rcu);
10732+}
10733+
10734+void au_dy_put(struct au_dykey *key)
1facf9fc 10735+{
4a4d8108
AM
10736+ kref_put(&key->dk_kref, dy_free);
10737+}
1facf9fc 10738+
4a4d8108
AM
10739+/* ---------------------------------------------------------------------- */
10740+
10741+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
10742+
10743+#ifdef CONFIG_AUFS_DEBUG
10744+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 10745+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
10746+#else
10747+#define DyDbgDeclare(cnt) do {} while (0)
10748+#define DyDbgInc(cnt) do {} while (0)
10749+#endif
10750+
10751+#define DySet(func, dst, src, h_op, h_sb) do { \
10752+ DyDbgInc(cnt); \
10753+ if (h_op->func) { \
10754+ if (src.func) \
10755+ dst.func = src.func; \
10756+ else \
10757+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
10758+ } \
10759+} while (0)
10760+
10761+#define DySetForce(func, dst, src) do { \
10762+ AuDebugOn(!src.func); \
10763+ DyDbgInc(cnt); \
10764+ dst.func = src.func; \
10765+} while (0)
10766+
10767+#define DySetAop(func) \
10768+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
10769+#define DySetAopForce(func) \
10770+ DySetForce(func, dyaop->da_op, aufs_aop)
10771+
10772+static void dy_aop(struct au_dykey *key, const void *h_op,
10773+ struct super_block *h_sb __maybe_unused)
10774+{
10775+ struct au_dyaop *dyaop = (void *)key;
10776+ const struct address_space_operations *h_aop = h_op;
10777+ DyDbgDeclare(cnt);
10778+
10779+ AuDbg("%s\n", au_sbtype(h_sb));
10780+
10781+ DySetAop(writepage);
10782+ DySetAopForce(readpage); /* force */
4a4d8108
AM
10783+ DySetAop(writepages);
10784+ DySetAop(set_page_dirty);
10785+ DySetAop(readpages);
10786+ DySetAop(write_begin);
10787+ DySetAop(write_end);
10788+ DySetAop(bmap);
10789+ DySetAop(invalidatepage);
10790+ DySetAop(releasepage);
027c5e7a 10791+ DySetAop(freepage);
7e9cd9fe 10792+ /* this one will be changed according to an aufs mount option */
4a4d8108 10793+ DySetAop(direct_IO);
4a4d8108 10794+ DySetAop(migratepage);
e2f27e51
AM
10795+ DySetAop(isolate_page);
10796+ DySetAop(putback_page);
4a4d8108
AM
10797+ DySetAop(launder_page);
10798+ DySetAop(is_partially_uptodate);
392086de 10799+ DySetAop(is_dirty_writeback);
4a4d8108 10800+ DySetAop(error_remove_page);
b4510431
AM
10801+ DySetAop(swap_activate);
10802+ DySetAop(swap_deactivate);
4a4d8108
AM
10803+
10804+ DyDbgSize(cnt, *h_aop);
4a4d8108
AM
10805+}
10806+
4a4d8108
AM
10807+/* ---------------------------------------------------------------------- */
10808+
10809+static void dy_bug(struct kref *kref)
10810+{
10811+ BUG();
10812+}
10813+
10814+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
10815+{
10816+ struct au_dykey *key, *old;
f0c0a007 10817+ struct au_sphlhead *sphl;
b752ccd1 10818+ struct op {
4a4d8108 10819+ unsigned int sz;
b752ccd1
AM
10820+ void (*set)(struct au_dykey *key, const void *h_op,
10821+ struct super_block *h_sb __maybe_unused);
10822+ };
10823+ static const struct op a[] = {
4a4d8108
AM
10824+ [AuDy_AOP] = {
10825+ .sz = sizeof(struct au_dyaop),
b752ccd1 10826+ .set = dy_aop
4a4d8108 10827+ }
b752ccd1
AM
10828+ };
10829+ const struct op *p;
4a4d8108 10830+
f0c0a007
AM
10831+ sphl = dynop + op->dy_type;
10832+ key = dy_gfind_get(sphl, op->dy_hop);
4a4d8108
AM
10833+ if (key)
10834+ goto out_add; /* success */
10835+
10836+ p = a + op->dy_type;
10837+ key = kzalloc(p->sz, GFP_NOFS);
10838+ if (unlikely(!key)) {
10839+ key = ERR_PTR(-ENOMEM);
10840+ goto out;
10841+ }
10842+
10843+ key->dk_op.dy_hop = op->dy_hop;
10844+ kref_init(&key->dk_kref);
86dc4139 10845+ p->set(key, op->dy_hop, au_br_sb(br));
f0c0a007 10846+ old = dy_gadd(sphl, key);
4a4d8108 10847+ if (old) {
1c60b727 10848+ kfree(key);
4a4d8108
AM
10849+ key = old;
10850+ }
10851+
10852+out_add:
10853+ old = dy_bradd(br, key);
10854+ if (old)
10855+ /* its ref-count should never be zero here */
10856+ kref_put(&key->dk_kref, dy_bug);
10857+out:
10858+ return key;
10859+}
10860+
10861+/* ---------------------------------------------------------------------- */
10862+/*
10863+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
c1595e42 10864+ * This behaviour is necessary to return an error from open(O_DIRECT) instead
4a4d8108
AM
10865+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
10866+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
10867+ * See the aufs manual in detail.
4a4d8108
AM
10868+ */
10869+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
10870+{
7e9cd9fe 10871+ if (!do_dx)
4a4d8108 10872+ dyaop->da_op.direct_IO = NULL;
7e9cd9fe 10873+ else
4a4d8108 10874+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
4a4d8108
AM
10875+}
10876+
10877+static struct au_dyaop *dy_aget(struct au_branch *br,
10878+ const struct address_space_operations *h_aop,
10879+ int do_dx)
10880+{
10881+ struct au_dyaop *dyaop;
10882+ struct au_dynop op;
10883+
10884+ op.dy_type = AuDy_AOP;
10885+ op.dy_haop = h_aop;
10886+ dyaop = (void *)dy_get(&op, br);
10887+ if (IS_ERR(dyaop))
10888+ goto out;
10889+ dy_adx(dyaop, do_dx);
10890+
10891+out:
10892+ return dyaop;
10893+}
10894+
10895+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10896+ struct inode *h_inode)
10897+{
10898+ int err, do_dx;
10899+ struct super_block *sb;
10900+ struct au_branch *br;
10901+ struct au_dyaop *dyaop;
10902+
10903+ AuDebugOn(!S_ISREG(h_inode->i_mode));
10904+ IiMustWriteLock(inode);
10905+
10906+ sb = inode->i_sb;
10907+ br = au_sbr(sb, bindex);
10908+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
10909+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
10910+ err = PTR_ERR(dyaop);
10911+ if (IS_ERR(dyaop))
10912+ /* unnecessary to call dy_fput() */
10913+ goto out;
10914+
10915+ err = 0;
10916+ inode->i_mapping->a_ops = &dyaop->da_op;
10917+
10918+out:
10919+ return err;
10920+}
10921+
b752ccd1
AM
10922+/*
10923+ * Is it safe to replace a_ops during the inode/file is in operation?
10924+ * Yes, I hope so.
10925+ */
10926+int au_dy_irefresh(struct inode *inode)
10927+{
10928+ int err;
5afbbe0d 10929+ aufs_bindex_t btop;
b752ccd1
AM
10930+ struct inode *h_inode;
10931+
10932+ err = 0;
10933+ if (S_ISREG(inode->i_mode)) {
5afbbe0d
AM
10934+ btop = au_ibtop(inode);
10935+ h_inode = au_h_iptr(inode, btop);
10936+ err = au_dy_iaop(inode, btop, h_inode);
b752ccd1
AM
10937+ }
10938+ return err;
10939+}
10940+
4a4d8108
AM
10941+void au_dy_arefresh(int do_dx)
10942+{
f0c0a007
AM
10943+ struct au_sphlhead *sphl;
10944+ struct hlist_head *head;
4a4d8108
AM
10945+ struct au_dykey *key;
10946+
f0c0a007
AM
10947+ sphl = dynop + AuDy_AOP;
10948+ head = &sphl->head;
10949+ spin_lock(&sphl->spin);
10950+ hlist_for_each_entry(key, head, dk_hnode)
4a4d8108 10951+ dy_adx((void *)key, do_dx);
f0c0a007 10952+ spin_unlock(&sphl->spin);
4a4d8108
AM
10953+}
10954+
4a4d8108
AM
10955+/* ---------------------------------------------------------------------- */
10956+
10957+void __init au_dy_init(void)
10958+{
10959+ int i;
10960+
10961+ /* make sure that 'struct au_dykey *' can be any type */
10962+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
10963+
10964+ for (i = 0; i < AuDyLast; i++)
f0c0a007 10965+ au_sphl_init(dynop + i);
4a4d8108
AM
10966+}
10967+
10968+void au_dy_fin(void)
10969+{
10970+ int i;
10971+
10972+ for (i = 0; i < AuDyLast; i++)
f0c0a007 10973+ WARN_ON(!hlist_empty(&dynop[i].head));
4a4d8108 10974+}
7f207e10
AM
10975diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
10976--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 10977+++ linux/fs/aufs/dynop.h 2017-07-29 12:14:25.899708630 +0200
7e9cd9fe 10978@@ -0,0 +1,74 @@
4a4d8108 10979+/*
a2654f78 10980+ * Copyright (C) 2010-2017 Junjiro R. Okajima
4a4d8108
AM
10981+ *
10982+ * This program, aufs is free software; you can redistribute it and/or modify
10983+ * it under the terms of the GNU General Public License as published by
10984+ * the Free Software Foundation; either version 2 of the License, or
10985+ * (at your option) any later version.
10986+ *
10987+ * This program is distributed in the hope that it will be useful,
10988+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10989+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10990+ * GNU General Public License for more details.
10991+ *
10992+ * You should have received a copy of the GNU General Public License
523b37e3 10993+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10994+ */
10995+
10996+/*
10997+ * dynamically customizable operations (for regular files only)
10998+ */
10999+
11000+#ifndef __AUFS_DYNOP_H__
11001+#define __AUFS_DYNOP_H__
11002+
11003+#ifdef __KERNEL__
11004+
7e9cd9fe
AM
11005+#include <linux/fs.h>
11006+#include <linux/kref.h>
4a4d8108 11007+
2cbb1c4b 11008+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
11009+
11010+struct au_dynop {
11011+ int dy_type;
11012+ union {
11013+ const void *dy_hop;
11014+ const struct address_space_operations *dy_haop;
4a4d8108
AM
11015+ };
11016+};
11017+
11018+struct au_dykey {
11019+ union {
f0c0a007 11020+ struct hlist_node dk_hnode;
4a4d8108
AM
11021+ struct rcu_head dk_rcu;
11022+ };
11023+ struct au_dynop dk_op;
11024+
11025+ /*
11026+ * during I am in the branch local array, kref is gotten. when the
11027+ * branch is removed, kref is put.
11028+ */
11029+ struct kref dk_kref;
11030+};
11031+
11032+/* stop unioning since their sizes are very different from each other */
11033+struct au_dyaop {
11034+ struct au_dykey da_key;
11035+ struct address_space_operations da_op; /* not const */
4a4d8108
AM
11036+};
11037+
4a4d8108
AM
11038+/* ---------------------------------------------------------------------- */
11039+
11040+/* dynop.c */
11041+struct au_branch;
11042+void au_dy_put(struct au_dykey *key);
11043+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
11044+ struct inode *h_inode);
b752ccd1 11045+int au_dy_irefresh(struct inode *inode);
4a4d8108 11046+void au_dy_arefresh(int do_dio);
4a4d8108
AM
11047+
11048+void __init au_dy_init(void);
11049+void au_dy_fin(void);
11050+
4a4d8108
AM
11051+#endif /* __KERNEL__ */
11052+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
11053diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
11054--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 11055+++ linux/fs/aufs/export.c 2017-07-29 12:14:25.903042072 +0200
f2c43d5f 11056@@ -0,0 +1,836 @@
4a4d8108 11057+/*
a2654f78 11058+ * Copyright (C) 2005-2017 Junjiro R. Okajima
4a4d8108
AM
11059+ *
11060+ * This program, aufs is free software; you can redistribute it and/or modify
11061+ * it under the terms of the GNU General Public License as published by
11062+ * the Free Software Foundation; either version 2 of the License, or
11063+ * (at your option) any later version.
11064+ *
11065+ * This program is distributed in the hope that it will be useful,
11066+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11067+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11068+ * GNU General Public License for more details.
11069+ *
11070+ * You should have received a copy of the GNU General Public License
523b37e3 11071+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
11072+ */
11073+
11074+/*
11075+ * export via nfs
11076+ */
11077+
11078+#include <linux/exportfs.h>
7eafdf33 11079+#include <linux/fs_struct.h>
4a4d8108
AM
11080+#include <linux/namei.h>
11081+#include <linux/nsproxy.h>
11082+#include <linux/random.h>
11083+#include <linux/writeback.h>
11084+#include "aufs.h"
11085+
11086+union conv {
11087+#ifdef CONFIG_AUFS_INO_T_64
11088+ __u32 a[2];
11089+#else
11090+ __u32 a[1];
11091+#endif
11092+ ino_t ino;
11093+};
11094+
11095+static ino_t decode_ino(__u32 *a)
11096+{
11097+ union conv u;
11098+
11099+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
11100+ u.a[0] = a[0];
11101+#ifdef CONFIG_AUFS_INO_T_64
11102+ u.a[1] = a[1];
11103+#endif
11104+ return u.ino;
11105+}
11106+
11107+static void encode_ino(__u32 *a, ino_t ino)
11108+{
11109+ union conv u;
11110+
11111+ u.ino = ino;
11112+ a[0] = u.a[0];
11113+#ifdef CONFIG_AUFS_INO_T_64
11114+ a[1] = u.a[1];
11115+#endif
11116+}
11117+
11118+/* NFS file handle */
11119+enum {
11120+ Fh_br_id,
11121+ Fh_sigen,
11122+#ifdef CONFIG_AUFS_INO_T_64
11123+ /* support 64bit inode number */
11124+ Fh_ino1,
11125+ Fh_ino2,
11126+ Fh_dir_ino1,
11127+ Fh_dir_ino2,
11128+#else
11129+ Fh_ino1,
11130+ Fh_dir_ino1,
11131+#endif
11132+ Fh_igen,
11133+ Fh_h_type,
11134+ Fh_tail,
11135+
11136+ Fh_ino = Fh_ino1,
11137+ Fh_dir_ino = Fh_dir_ino1
11138+};
11139+
11140+static int au_test_anon(struct dentry *dentry)
11141+{
027c5e7a 11142+ /* note: read d_flags without d_lock */
4a4d8108
AM
11143+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
11144+}
11145+
a2a7ad62
AM
11146+int au_test_nfsd(void)
11147+{
11148+ int ret;
11149+ struct task_struct *tsk = current;
11150+ char comm[sizeof(tsk->comm)];
11151+
11152+ ret = 0;
11153+ if (tsk->flags & PF_KTHREAD) {
11154+ get_task_comm(comm, tsk);
11155+ ret = !strcmp(comm, "nfsd");
11156+ }
11157+
11158+ return ret;
11159+}
11160+
4a4d8108
AM
11161+/* ---------------------------------------------------------------------- */
11162+/* inode generation external table */
11163+
b752ccd1 11164+void au_xigen_inc(struct inode *inode)
4a4d8108 11165+{
4a4d8108
AM
11166+ loff_t pos;
11167+ ssize_t sz;
11168+ __u32 igen;
11169+ struct super_block *sb;
11170+ struct au_sbinfo *sbinfo;
11171+
4a4d8108 11172+ sb = inode->i_sb;
b752ccd1 11173+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 11174+
b752ccd1 11175+ sbinfo = au_sbi(sb);
1facf9fc 11176+ pos = inode->i_ino;
11177+ pos *= sizeof(igen);
11178+ igen = inode->i_generation + 1;
1facf9fc 11179+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
11180+ sizeof(igen), &pos);
11181+ if (sz == sizeof(igen))
b752ccd1 11182+ return; /* success */
1facf9fc 11183+
b752ccd1 11184+ if (unlikely(sz >= 0))
1facf9fc 11185+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 11186+}
11187+
11188+int au_xigen_new(struct inode *inode)
11189+{
11190+ int err;
11191+ loff_t pos;
11192+ ssize_t sz;
11193+ struct super_block *sb;
11194+ struct au_sbinfo *sbinfo;
11195+ struct file *file;
11196+
11197+ err = 0;
11198+ /* todo: dirty, at mount time */
11199+ if (inode->i_ino == AUFS_ROOT_INO)
11200+ goto out;
11201+ sb = inode->i_sb;
dece6358 11202+ SiMustAnyLock(sb);
1facf9fc 11203+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
11204+ goto out;
11205+
11206+ err = -EFBIG;
11207+ pos = inode->i_ino;
11208+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
11209+ AuIOErr1("too large i%lld\n", pos);
11210+ goto out;
11211+ }
11212+ pos *= sizeof(inode->i_generation);
11213+
11214+ err = 0;
11215+ sbinfo = au_sbi(sb);
11216+ file = sbinfo->si_xigen;
11217+ BUG_ON(!file);
11218+
c06a8ce3 11219+ if (vfsub_f_size_read(file)
1facf9fc 11220+ < pos + sizeof(inode->i_generation)) {
11221+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
11222+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
11223+ sizeof(inode->i_generation), &pos);
11224+ } else
11225+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
11226+ sizeof(inode->i_generation), &pos);
11227+ if (sz == sizeof(inode->i_generation))
11228+ goto out; /* success */
11229+
11230+ err = sz;
11231+ if (unlikely(sz >= 0)) {
11232+ err = -EIO;
11233+ AuIOErr("xigen error (%zd)\n", sz);
11234+ }
11235+
4f0767ce 11236+out:
1facf9fc 11237+ return err;
11238+}
11239+
11240+int au_xigen_set(struct super_block *sb, struct file *base)
11241+{
11242+ int err;
11243+ struct au_sbinfo *sbinfo;
11244+ struct file *file;
11245+
dece6358
AM
11246+ SiMustWriteLock(sb);
11247+
1facf9fc 11248+ sbinfo = au_sbi(sb);
11249+ file = au_xino_create2(base, sbinfo->si_xigen);
11250+ err = PTR_ERR(file);
11251+ if (IS_ERR(file))
11252+ goto out;
11253+ err = 0;
11254+ if (sbinfo->si_xigen)
11255+ fput(sbinfo->si_xigen);
11256+ sbinfo->si_xigen = file;
11257+
4f0767ce 11258+out:
1facf9fc 11259+ return err;
11260+}
11261+
11262+void au_xigen_clr(struct super_block *sb)
11263+{
11264+ struct au_sbinfo *sbinfo;
11265+
dece6358
AM
11266+ SiMustWriteLock(sb);
11267+
1facf9fc 11268+ sbinfo = au_sbi(sb);
11269+ if (sbinfo->si_xigen) {
11270+ fput(sbinfo->si_xigen);
11271+ sbinfo->si_xigen = NULL;
11272+ }
11273+}
11274+
11275+/* ---------------------------------------------------------------------- */
11276+
11277+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
11278+ ino_t dir_ino)
11279+{
11280+ struct dentry *dentry, *d;
11281+ struct inode *inode;
11282+ unsigned int sigen;
11283+
11284+ dentry = NULL;
11285+ inode = ilookup(sb, ino);
11286+ if (!inode)
11287+ goto out;
11288+
11289+ dentry = ERR_PTR(-ESTALE);
11290+ sigen = au_sigen(sb);
5afbbe0d 11291+ if (unlikely(au_is_bad_inode(inode)
1facf9fc 11292+ || IS_DEADDIR(inode)
537831f9 11293+ || sigen != au_iigen(inode, NULL)))
1facf9fc 11294+ goto out_iput;
11295+
11296+ dentry = NULL;
11297+ if (!dir_ino || S_ISDIR(inode->i_mode))
11298+ dentry = d_find_alias(inode);
11299+ else {
027c5e7a 11300+ spin_lock(&inode->i_lock);
c1595e42 11301+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 11302+ spin_lock(&d->d_lock);
1facf9fc 11303+ if (!au_test_anon(d)
5527c038 11304+ && d_inode(d->d_parent)->i_ino == dir_ino) {
027c5e7a
AM
11305+ dentry = dget_dlock(d);
11306+ spin_unlock(&d->d_lock);
1facf9fc 11307+ break;
11308+ }
027c5e7a
AM
11309+ spin_unlock(&d->d_lock);
11310+ }
11311+ spin_unlock(&inode->i_lock);
1facf9fc 11312+ }
027c5e7a 11313+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 11314+ /* need to refresh */
1facf9fc 11315+ dput(dentry);
2cbb1c4b 11316+ dentry = NULL;
1facf9fc 11317+ }
11318+
4f0767ce 11319+out_iput:
1facf9fc 11320+ iput(inode);
4f0767ce 11321+out:
2cbb1c4b 11322+ AuTraceErrPtr(dentry);
1facf9fc 11323+ return dentry;
11324+}
11325+
11326+/* ---------------------------------------------------------------------- */
11327+
11328+/* todo: dirty? */
11329+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
11330+
11331+struct au_compare_mnt_args {
11332+ /* input */
11333+ struct super_block *sb;
11334+
11335+ /* output */
11336+ struct vfsmount *mnt;
11337+};
11338+
11339+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
11340+{
11341+ struct au_compare_mnt_args *a = arg;
11342+
11343+ if (mnt->mnt_sb != a->sb)
11344+ return 0;
11345+ a->mnt = mntget(mnt);
11346+ return 1;
11347+}
11348+
1facf9fc 11349+static struct vfsmount *au_mnt_get(struct super_block *sb)
11350+{
4a4d8108 11351+ int err;
7eafdf33 11352+ struct path root;
4a4d8108
AM
11353+ struct au_compare_mnt_args args = {
11354+ .sb = sb
11355+ };
1facf9fc 11356+
7eafdf33 11357+ get_fs_root(current->fs, &root);
523b37e3 11358+ rcu_read_lock();
7eafdf33 11359+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 11360+ rcu_read_unlock();
7eafdf33 11361+ path_put(&root);
4a4d8108
AM
11362+ AuDebugOn(!err);
11363+ AuDebugOn(!args.mnt);
11364+ return args.mnt;
1facf9fc 11365+}
11366+
11367+struct au_nfsd_si_lock {
4a4d8108 11368+ unsigned int sigen;
027c5e7a 11369+ aufs_bindex_t bindex, br_id;
1facf9fc 11370+ unsigned char force_lock;
11371+};
11372+
027c5e7a
AM
11373+static int si_nfsd_read_lock(struct super_block *sb,
11374+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 11375+{
027c5e7a 11376+ int err;
1facf9fc 11377+ aufs_bindex_t bindex;
11378+
11379+ si_read_lock(sb, AuLock_FLUSH);
11380+
11381+ /* branch id may be wrapped around */
027c5e7a 11382+ err = 0;
1facf9fc 11383+ bindex = au_br_index(sb, nsi_lock->br_id);
11384+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
11385+ goto out; /* success */
11386+
027c5e7a
AM
11387+ err = -ESTALE;
11388+ bindex = -1;
1facf9fc 11389+ if (!nsi_lock->force_lock)
11390+ si_read_unlock(sb);
1facf9fc 11391+
4f0767ce 11392+out:
027c5e7a
AM
11393+ nsi_lock->bindex = bindex;
11394+ return err;
1facf9fc 11395+}
11396+
11397+struct find_name_by_ino {
392086de 11398+ struct dir_context ctx;
1facf9fc 11399+ int called, found;
11400+ ino_t ino;
11401+ char *name;
11402+ int namelen;
11403+};
11404+
11405+static int
392086de
AM
11406+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
11407+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 11408+{
392086de
AM
11409+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
11410+ ctx);
1facf9fc 11411+
11412+ a->called++;
11413+ if (a->ino != ino)
11414+ return 0;
11415+
11416+ memcpy(a->name, name, namelen);
11417+ a->namelen = namelen;
11418+ a->found = 1;
11419+ return 1;
11420+}
11421+
11422+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
11423+ struct au_nfsd_si_lock *nsi_lock)
11424+{
11425+ struct dentry *dentry, *parent;
11426+ struct file *file;
11427+ struct inode *dir;
392086de
AM
11428+ struct find_name_by_ino arg = {
11429+ .ctx = {
2000de60 11430+ .actor = find_name_by_ino
392086de
AM
11431+ }
11432+ };
1facf9fc 11433+ int err;
11434+
11435+ parent = path->dentry;
11436+ if (nsi_lock)
11437+ si_read_unlock(parent->d_sb);
4a4d8108 11438+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 11439+ dentry = (void *)file;
11440+ if (IS_ERR(file))
11441+ goto out;
11442+
11443+ dentry = ERR_PTR(-ENOMEM);
537831f9 11444+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 11445+ if (unlikely(!arg.name))
11446+ goto out_file;
11447+ arg.ino = ino;
11448+ arg.found = 0;
11449+ do {
11450+ arg.called = 0;
11451+ /* smp_mb(); */
392086de 11452+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 11453+ } while (!err && !arg.found && arg.called);
11454+ dentry = ERR_PTR(err);
11455+ if (unlikely(err))
11456+ goto out_name;
1716fcea
AM
11457+ /* instead of ENOENT */
11458+ dentry = ERR_PTR(-ESTALE);
1facf9fc 11459+ if (!arg.found)
11460+ goto out_name;
11461+
b4510431 11462+ /* do not call vfsub_lkup_one() */
5527c038 11463+ dir = d_inode(parent);
febd17d6 11464+ dentry = vfsub_lookup_one_len_unlocked(arg.name, parent, arg.namelen);
1facf9fc 11465+ AuTraceErrPtr(dentry);
11466+ if (IS_ERR(dentry))
11467+ goto out_name;
11468+ AuDebugOn(au_test_anon(dentry));
5527c038 11469+ if (unlikely(d_really_is_negative(dentry))) {
1facf9fc 11470+ dput(dentry);
11471+ dentry = ERR_PTR(-ENOENT);
11472+ }
11473+
4f0767ce 11474+out_name:
1c60b727 11475+ free_page((unsigned long)arg.name);
4f0767ce 11476+out_file:
1facf9fc 11477+ fput(file);
4f0767ce 11478+out:
1facf9fc 11479+ if (unlikely(nsi_lock
11480+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
11481+ if (!IS_ERR(dentry)) {
11482+ dput(dentry);
11483+ dentry = ERR_PTR(-ESTALE);
11484+ }
11485+ AuTraceErrPtr(dentry);
11486+ return dentry;
11487+}
11488+
11489+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
11490+ ino_t dir_ino,
11491+ struct au_nfsd_si_lock *nsi_lock)
11492+{
11493+ struct dentry *dentry;
11494+ struct path path;
11495+
11496+ if (dir_ino != AUFS_ROOT_INO) {
11497+ path.dentry = decode_by_ino(sb, dir_ino, 0);
11498+ dentry = path.dentry;
11499+ if (!path.dentry || IS_ERR(path.dentry))
11500+ goto out;
11501+ AuDebugOn(au_test_anon(path.dentry));
11502+ } else
11503+ path.dentry = dget(sb->s_root);
11504+
11505+ path.mnt = au_mnt_get(sb);
11506+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
11507+ path_put(&path);
11508+
4f0767ce 11509+out:
1facf9fc 11510+ AuTraceErrPtr(dentry);
11511+ return dentry;
11512+}
11513+
11514+/* ---------------------------------------------------------------------- */
11515+
11516+static int h_acceptable(void *expv, struct dentry *dentry)
11517+{
11518+ return 1;
11519+}
11520+
11521+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
11522+ char *buf, int len, struct super_block *sb)
11523+{
11524+ char *p;
11525+ int n;
11526+ struct path path;
11527+
11528+ p = d_path(h_rootpath, buf, len);
11529+ if (IS_ERR(p))
11530+ goto out;
11531+ n = strlen(p);
11532+
11533+ path.mnt = h_rootpath->mnt;
11534+ path.dentry = h_parent;
11535+ p = d_path(&path, buf, len);
11536+ if (IS_ERR(p))
11537+ goto out;
11538+ if (n != 1)
11539+ p += n;
11540+
11541+ path.mnt = au_mnt_get(sb);
11542+ path.dentry = sb->s_root;
11543+ p = d_path(&path, buf, len - strlen(p));
11544+ mntput(path.mnt);
11545+ if (IS_ERR(p))
11546+ goto out;
11547+ if (n != 1)
11548+ p[strlen(p)] = '/';
11549+
4f0767ce 11550+out:
1facf9fc 11551+ AuTraceErrPtr(p);
11552+ return p;
11553+}
11554+
11555+static
027c5e7a
AM
11556+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
11557+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 11558+{
11559+ struct dentry *dentry, *h_parent, *root;
11560+ struct super_block *h_sb;
11561+ char *pathname, *p;
11562+ struct vfsmount *h_mnt;
11563+ struct au_branch *br;
11564+ int err;
11565+ struct path path;
11566+
027c5e7a 11567+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 11568+ h_mnt = au_br_mnt(br);
1facf9fc 11569+ h_sb = h_mnt->mnt_sb;
11570+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
5afbbe0d 11571+ lockdep_off();
1facf9fc 11572+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
11573+ fh_len - Fh_tail, fh[Fh_h_type],
11574+ h_acceptable, /*context*/NULL);
5afbbe0d 11575+ lockdep_on();
1facf9fc 11576+ dentry = h_parent;
11577+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
11578+ AuWarn1("%s decode_fh failed, %ld\n",
11579+ au_sbtype(h_sb), PTR_ERR(h_parent));
11580+ goto out;
11581+ }
11582+ dentry = NULL;
11583+ if (unlikely(au_test_anon(h_parent))) {
11584+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
11585+ au_sbtype(h_sb));
11586+ goto out_h_parent;
11587+ }
11588+
11589+ dentry = ERR_PTR(-ENOMEM);
11590+ pathname = (void *)__get_free_page(GFP_NOFS);
11591+ if (unlikely(!pathname))
11592+ goto out_h_parent;
11593+
11594+ root = sb->s_root;
11595+ path.mnt = h_mnt;
11596+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 11597+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 11598+ di_read_unlock(root, !AuLock_IR);
11599+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
11600+ dentry = (void *)p;
11601+ if (IS_ERR(p))
11602+ goto out_pathname;
11603+
11604+ si_read_unlock(sb);
11605+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
11606+ dentry = ERR_PTR(err);
11607+ if (unlikely(err))
11608+ goto out_relock;
11609+
11610+ dentry = ERR_PTR(-ENOENT);
11611+ AuDebugOn(au_test_anon(path.dentry));
5527c038 11612+ if (unlikely(d_really_is_negative(path.dentry)))
1facf9fc 11613+ goto out_path;
11614+
5527c038 11615+ if (ino != d_inode(path.dentry)->i_ino)
1facf9fc 11616+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
11617+ else
11618+ dentry = dget(path.dentry);
11619+
4f0767ce 11620+out_path:
1facf9fc 11621+ path_put(&path);
4f0767ce 11622+out_relock:
1facf9fc 11623+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
11624+ if (!IS_ERR(dentry)) {
11625+ dput(dentry);
11626+ dentry = ERR_PTR(-ESTALE);
11627+ }
4f0767ce 11628+out_pathname:
1c60b727 11629+ free_page((unsigned long)pathname);
4f0767ce 11630+out_h_parent:
1facf9fc 11631+ dput(h_parent);
4f0767ce 11632+out:
1facf9fc 11633+ AuTraceErrPtr(dentry);
11634+ return dentry;
11635+}
11636+
11637+/* ---------------------------------------------------------------------- */
11638+
11639+static struct dentry *
11640+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
11641+ int fh_type)
11642+{
11643+ struct dentry *dentry;
11644+ __u32 *fh = fid->raw;
027c5e7a 11645+ struct au_branch *br;
1facf9fc 11646+ ino_t ino, dir_ino;
1facf9fc 11647+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 11648+ .force_lock = 0
11649+ };
11650+
1facf9fc 11651+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
11652+ /* it should never happen, but the file handle is unreliable */
11653+ if (unlikely(fh_len < Fh_tail))
11654+ goto out;
11655+ nsi_lock.sigen = fh[Fh_sigen];
11656+ nsi_lock.br_id = fh[Fh_br_id];
11657+
1facf9fc 11658+ /* branch id may be wrapped around */
027c5e7a
AM
11659+ br = NULL;
11660+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 11661+ goto out;
11662+ nsi_lock.force_lock = 1;
11663+
11664+ /* is this inode still cached? */
11665+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
11666+ /* it should never happen */
11667+ if (unlikely(ino == AUFS_ROOT_INO))
8cdd5066 11668+ goto out_unlock;
4a4d8108 11669+
1facf9fc 11670+ dir_ino = decode_ino(fh + Fh_dir_ino);
11671+ dentry = decode_by_ino(sb, ino, dir_ino);
11672+ if (IS_ERR(dentry))
11673+ goto out_unlock;
11674+ if (dentry)
11675+ goto accept;
11676+
11677+ /* is the parent dir cached? */
027c5e7a 11678+ br = au_sbr(sb, nsi_lock.bindex);
5afbbe0d 11679+ au_br_get(br);
1facf9fc 11680+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
11681+ if (IS_ERR(dentry))
11682+ goto out_unlock;
11683+ if (dentry)
11684+ goto accept;
11685+
11686+ /* lookup path */
027c5e7a 11687+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 11688+ if (IS_ERR(dentry))
11689+ goto out_unlock;
11690+ if (unlikely(!dentry))
11691+ /* todo?: make it ESTALE */
11692+ goto out_unlock;
11693+
4f0767ce 11694+accept:
027c5e7a 11695+ if (!au_digen_test(dentry, au_sigen(sb))
5527c038 11696+ && d_inode(dentry)->i_generation == fh[Fh_igen])
1facf9fc 11697+ goto out_unlock; /* success */
11698+
11699+ dput(dentry);
11700+ dentry = ERR_PTR(-ESTALE);
4f0767ce 11701+out_unlock:
027c5e7a 11702+ if (br)
5afbbe0d 11703+ au_br_put(br);
1facf9fc 11704+ si_read_unlock(sb);
4f0767ce 11705+out:
1facf9fc 11706+ AuTraceErrPtr(dentry);
11707+ return dentry;
11708+}
11709+
11710+#if 0 /* reserved for future use */
11711+/* support subtreecheck option */
11712+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
11713+ int fh_len, int fh_type)
11714+{
11715+ struct dentry *parent;
11716+ __u32 *fh = fid->raw;
11717+ ino_t dir_ino;
11718+
11719+ dir_ino = decode_ino(fh + Fh_dir_ino);
11720+ parent = decode_by_ino(sb, dir_ino, 0);
11721+ if (IS_ERR(parent))
11722+ goto out;
11723+ if (!parent)
11724+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
11725+ dir_ino, fh, fh_len);
11726+
4f0767ce 11727+out:
1facf9fc 11728+ AuTraceErrPtr(parent);
11729+ return parent;
11730+}
11731+#endif
11732+
11733+/* ---------------------------------------------------------------------- */
11734+
0c3ec466
AM
11735+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
11736+ struct inode *dir)
1facf9fc 11737+{
11738+ int err;
0c3ec466 11739+ aufs_bindex_t bindex;
1facf9fc 11740+ struct super_block *sb, *h_sb;
0c3ec466
AM
11741+ struct dentry *dentry, *parent, *h_parent;
11742+ struct inode *h_dir;
1facf9fc 11743+ struct au_branch *br;
11744+
1facf9fc 11745+ err = -ENOSPC;
11746+ if (unlikely(*max_len <= Fh_tail)) {
11747+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
11748+ goto out;
11749+ }
11750+
11751+ err = FILEID_ROOT;
0c3ec466
AM
11752+ if (inode->i_ino == AUFS_ROOT_INO) {
11753+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 11754+ goto out;
11755+ }
11756+
1facf9fc 11757+ h_parent = NULL;
0c3ec466
AM
11758+ sb = inode->i_sb;
11759+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
11760+ if (unlikely(err))
11761+ goto out;
11762+
1facf9fc 11763+#ifdef CONFIG_AUFS_DEBUG
11764+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
11765+ AuWarn1("NFS-exporting requires xino\n");
11766+#endif
027c5e7a 11767+ err = -EIO;
0c3ec466
AM
11768+ parent = NULL;
11769+ ii_read_lock_child(inode);
5afbbe0d 11770+ bindex = au_ibtop(inode);
0c3ec466 11771+ if (!dir) {
c1595e42 11772+ dentry = d_find_any_alias(inode);
0c3ec466
AM
11773+ if (unlikely(!dentry))
11774+ goto out_unlock;
11775+ AuDebugOn(au_test_anon(dentry));
11776+ parent = dget_parent(dentry);
11777+ dput(dentry);
11778+ if (unlikely(!parent))
11779+ goto out_unlock;
5527c038
JR
11780+ if (d_really_is_positive(parent))
11781+ dir = d_inode(parent);
1facf9fc 11782+ }
0c3ec466
AM
11783+
11784+ ii_read_lock_parent(dir);
11785+ h_dir = au_h_iptr(dir, bindex);
11786+ ii_read_unlock(dir);
11787+ if (unlikely(!h_dir))
11788+ goto out_parent;
c1595e42 11789+ h_parent = d_find_any_alias(h_dir);
1facf9fc 11790+ if (unlikely(!h_parent))
0c3ec466 11791+ goto out_hparent;
1facf9fc 11792+
11793+ err = -EPERM;
11794+ br = au_sbr(sb, bindex);
86dc4139 11795+ h_sb = au_br_sb(br);
1facf9fc 11796+ if (unlikely(!h_sb->s_export_op)) {
11797+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 11798+ goto out_hparent;
1facf9fc 11799+ }
11800+
11801+ fh[Fh_br_id] = br->br_id;
11802+ fh[Fh_sigen] = au_sigen(sb);
11803+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 11804+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 11805+ fh[Fh_igen] = inode->i_generation;
11806+
11807+ *max_len -= Fh_tail;
11808+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
11809+ max_len,
11810+ /*connectable or subtreecheck*/0);
11811+ err = fh[Fh_h_type];
11812+ *max_len += Fh_tail;
11813+ /* todo: macros? */
1716fcea 11814+ if (err != FILEID_INVALID)
1facf9fc 11815+ err = 99;
11816+ else
11817+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
11818+
0c3ec466 11819+out_hparent:
1facf9fc 11820+ dput(h_parent);
0c3ec466 11821+out_parent:
1facf9fc 11822+ dput(parent);
0c3ec466
AM
11823+out_unlock:
11824+ ii_read_unlock(inode);
11825+ si_read_unlock(sb);
4f0767ce 11826+out:
1facf9fc 11827+ if (unlikely(err < 0))
1716fcea 11828+ err = FILEID_INVALID;
1facf9fc 11829+ return err;
11830+}
11831+
11832+/* ---------------------------------------------------------------------- */
11833+
4a4d8108
AM
11834+static int aufs_commit_metadata(struct inode *inode)
11835+{
11836+ int err;
11837+ aufs_bindex_t bindex;
11838+ struct super_block *sb;
11839+ struct inode *h_inode;
11840+ int (*f)(struct inode *inode);
11841+
11842+ sb = inode->i_sb;
e49829fe 11843+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 11844+ ii_write_lock_child(inode);
5afbbe0d 11845+ bindex = au_ibtop(inode);
4a4d8108
AM
11846+ AuDebugOn(bindex < 0);
11847+ h_inode = au_h_iptr(inode, bindex);
11848+
11849+ f = h_inode->i_sb->s_export_op->commit_metadata;
11850+ if (f)
11851+ err = f(h_inode);
11852+ else {
11853+ struct writeback_control wbc = {
11854+ .sync_mode = WB_SYNC_ALL,
11855+ .nr_to_write = 0 /* metadata only */
11856+ };
11857+
11858+ err = sync_inode(h_inode, &wbc);
11859+ }
11860+
11861+ au_cpup_attr_timesizes(inode);
11862+ ii_write_unlock(inode);
11863+ si_read_unlock(sb);
11864+ return err;
11865+}
11866+
11867+/* ---------------------------------------------------------------------- */
11868+
1facf9fc 11869+static struct export_operations aufs_export_op = {
4a4d8108 11870+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 11871+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
11872+ .encode_fh = aufs_encode_fh,
11873+ .commit_metadata = aufs_commit_metadata
1facf9fc 11874+};
11875+
11876+void au_export_init(struct super_block *sb)
11877+{
11878+ struct au_sbinfo *sbinfo;
11879+ __u32 u;
11880+
5afbbe0d
AM
11881+ BUILD_BUG_ON_MSG(IS_BUILTIN(CONFIG_AUFS_FS)
11882+ && IS_MODULE(CONFIG_EXPORTFS),
11883+ AUFS_NAME ": unsupported configuration "
11884+ "CONFIG_EXPORTFS=m and CONFIG_AUFS_FS=y");
11885+
1facf9fc 11886+ sb->s_export_op = &aufs_export_op;
11887+ sbinfo = au_sbi(sb);
11888+ sbinfo->si_xigen = NULL;
11889+ get_random_bytes(&u, sizeof(u));
11890+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
11891+ atomic_set(&sbinfo->si_xigen_next, u);
11892+}
076b876e
AM
11893diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
11894--- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 11895+++ linux/fs/aufs/fhsm.c 2017-07-29 12:14:25.903042072 +0200
c1595e42 11896@@ -0,0 +1,426 @@
076b876e 11897+/*
a2654f78 11898+ * Copyright (C) 2011-2017 Junjiro R. Okajima
076b876e
AM
11899+ *
11900+ * This program, aufs is free software; you can redistribute it and/or modify
11901+ * it under the terms of the GNU General Public License as published by
11902+ * the Free Software Foundation; either version 2 of the License, or
11903+ * (at your option) any later version.
11904+ *
11905+ * This program is distributed in the hope that it will be useful,
11906+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11907+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11908+ * GNU General Public License for more details.
11909+ *
11910+ * You should have received a copy of the GNU General Public License
11911+ * along with this program; if not, write to the Free Software
11912+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11913+ */
11914+
11915+/*
11916+ * File-based Hierarchy Storage Management
11917+ */
11918+
11919+#include <linux/anon_inodes.h>
11920+#include <linux/poll.h>
11921+#include <linux/seq_file.h>
11922+#include <linux/statfs.h>
11923+#include "aufs.h"
11924+
c1595e42
JR
11925+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb)
11926+{
11927+ struct au_sbinfo *sbinfo;
11928+ struct au_fhsm *fhsm;
11929+
11930+ SiMustAnyLock(sb);
11931+
11932+ sbinfo = au_sbi(sb);
11933+ fhsm = &sbinfo->si_fhsm;
11934+ AuDebugOn(!fhsm);
11935+ return fhsm->fhsm_bottom;
11936+}
11937+
11938+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex)
11939+{
11940+ struct au_sbinfo *sbinfo;
11941+ struct au_fhsm *fhsm;
11942+
11943+ SiMustWriteLock(sb);
11944+
11945+ sbinfo = au_sbi(sb);
11946+ fhsm = &sbinfo->si_fhsm;
11947+ AuDebugOn(!fhsm);
11948+ fhsm->fhsm_bottom = bindex;
11949+}
11950+
11951+/* ---------------------------------------------------------------------- */
11952+
076b876e
AM
11953+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
11954+{
11955+ struct au_br_fhsm *bf;
11956+
11957+ bf = br->br_fhsm;
11958+ MtxMustLock(&bf->bf_lock);
11959+
11960+ return !bf->bf_readable
11961+ || time_after(jiffies,
11962+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
11963+}
11964+
11965+/* ---------------------------------------------------------------------- */
11966+
11967+static void au_fhsm_notify(struct super_block *sb, int val)
11968+{
11969+ struct au_sbinfo *sbinfo;
11970+ struct au_fhsm *fhsm;
11971+
11972+ SiMustAnyLock(sb);
11973+
11974+ sbinfo = au_sbi(sb);
11975+ fhsm = &sbinfo->si_fhsm;
11976+ if (au_fhsm_pid(fhsm)
11977+ && atomic_read(&fhsm->fhsm_readable) != -1) {
11978+ atomic_set(&fhsm->fhsm_readable, val);
11979+ if (val)
11980+ wake_up(&fhsm->fhsm_wqh);
11981+ }
11982+}
11983+
11984+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
11985+ struct aufs_stfs *rstfs, int do_lock, int do_notify)
11986+{
11987+ int err;
11988+ struct au_branch *br;
11989+ struct au_br_fhsm *bf;
11990+
11991+ br = au_sbr(sb, bindex);
11992+ AuDebugOn(au_br_rdonly(br));
11993+ bf = br->br_fhsm;
11994+ AuDebugOn(!bf);
11995+
11996+ if (do_lock)
11997+ mutex_lock(&bf->bf_lock);
11998+ else
11999+ MtxMustLock(&bf->bf_lock);
12000+
12001+ /* sb->s_root for NFS is unreliable */
12002+ err = au_br_stfs(br, &bf->bf_stfs);
12003+ if (unlikely(err)) {
12004+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
12005+ goto out;
12006+ }
12007+
12008+ bf->bf_jiffy = jiffies;
12009+ bf->bf_readable = 1;
12010+ if (do_notify)
12011+ au_fhsm_notify(sb, /*val*/1);
12012+ if (rstfs)
12013+ *rstfs = bf->bf_stfs;
12014+
12015+out:
12016+ if (do_lock)
12017+ mutex_unlock(&bf->bf_lock);
12018+ au_fhsm_notify(sb, /*val*/1);
12019+
12020+ return err;
12021+}
12022+
12023+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
12024+{
12025+ int err;
076b876e
AM
12026+ struct au_sbinfo *sbinfo;
12027+ struct au_fhsm *fhsm;
12028+ struct au_branch *br;
12029+ struct au_br_fhsm *bf;
12030+
12031+ AuDbg("b%d, force %d\n", bindex, force);
12032+ SiMustAnyLock(sb);
12033+
12034+ sbinfo = au_sbi(sb);
12035+ fhsm = &sbinfo->si_fhsm;
c1595e42
JR
12036+ if (!au_ftest_si(sbinfo, FHSM)
12037+ || fhsm->fhsm_bottom == bindex)
076b876e
AM
12038+ return;
12039+
12040+ br = au_sbr(sb, bindex);
12041+ bf = br->br_fhsm;
12042+ AuDebugOn(!bf);
12043+ mutex_lock(&bf->bf_lock);
12044+ if (force
12045+ || au_fhsm_pid(fhsm)
12046+ || au_fhsm_test_jiffy(sbinfo, br))
12047+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
12048+ /*do_notify*/1);
12049+ mutex_unlock(&bf->bf_lock);
12050+}
12051+
12052+void au_fhsm_wrote_all(struct super_block *sb, int force)
12053+{
5afbbe0d 12054+ aufs_bindex_t bindex, bbot;
076b876e
AM
12055+ struct au_branch *br;
12056+
12057+ /* exclude the bottom */
5afbbe0d
AM
12058+ bbot = au_fhsm_bottom(sb);
12059+ for (bindex = 0; bindex < bbot; bindex++) {
076b876e
AM
12060+ br = au_sbr(sb, bindex);
12061+ if (au_br_fhsm(br->br_perm))
12062+ au_fhsm_wrote(sb, bindex, force);
12063+ }
12064+}
12065+
12066+/* ---------------------------------------------------------------------- */
12067+
12068+static unsigned int au_fhsm_poll(struct file *file,
12069+ struct poll_table_struct *wait)
12070+{
12071+ unsigned int mask;
12072+ struct au_sbinfo *sbinfo;
12073+ struct au_fhsm *fhsm;
12074+
12075+ mask = 0;
12076+ sbinfo = file->private_data;
12077+ fhsm = &sbinfo->si_fhsm;
12078+ poll_wait(file, &fhsm->fhsm_wqh, wait);
12079+ if (atomic_read(&fhsm->fhsm_readable))
12080+ mask = POLLIN /* | POLLRDNORM */;
12081+
12082+ AuTraceErr((int)mask);
12083+ return mask;
12084+}
12085+
12086+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
12087+ struct aufs_stfs *stfs, __s16 brid)
12088+{
12089+ int err;
12090+
12091+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
12092+ if (!err)
12093+ err = __put_user(brid, &stbr->brid);
12094+ if (unlikely(err))
12095+ err = -EFAULT;
12096+
12097+ return err;
12098+}
12099+
12100+static ssize_t au_fhsm_do_read(struct super_block *sb,
12101+ struct aufs_stbr __user *stbr, size_t count)
12102+{
12103+ ssize_t err;
12104+ int nstbr;
5afbbe0d 12105+ aufs_bindex_t bindex, bbot;
076b876e
AM
12106+ struct au_branch *br;
12107+ struct au_br_fhsm *bf;
12108+
12109+ /* except the bottom branch */
12110+ err = 0;
12111+ nstbr = 0;
5afbbe0d
AM
12112+ bbot = au_fhsm_bottom(sb);
12113+ for (bindex = 0; !err && bindex < bbot; bindex++) {
076b876e
AM
12114+ br = au_sbr(sb, bindex);
12115+ if (!au_br_fhsm(br->br_perm))
12116+ continue;
12117+
12118+ bf = br->br_fhsm;
12119+ mutex_lock(&bf->bf_lock);
12120+ if (bf->bf_readable) {
12121+ err = -EFAULT;
12122+ if (count >= sizeof(*stbr))
12123+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
12124+ br->br_id);
12125+ if (!err) {
12126+ bf->bf_readable = 0;
12127+ count -= sizeof(*stbr);
12128+ nstbr++;
12129+ }
12130+ }
12131+ mutex_unlock(&bf->bf_lock);
12132+ }
12133+ if (!err)
12134+ err = sizeof(*stbr) * nstbr;
12135+
12136+ return err;
12137+}
12138+
12139+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
12140+ loff_t *pos)
12141+{
12142+ ssize_t err;
12143+ int readable;
5afbbe0d 12144+ aufs_bindex_t nfhsm, bindex, bbot;
076b876e
AM
12145+ struct au_sbinfo *sbinfo;
12146+ struct au_fhsm *fhsm;
12147+ struct au_branch *br;
12148+ struct super_block *sb;
12149+
12150+ err = 0;
12151+ sbinfo = file->private_data;
12152+ fhsm = &sbinfo->si_fhsm;
12153+need_data:
12154+ spin_lock_irq(&fhsm->fhsm_wqh.lock);
12155+ if (!atomic_read(&fhsm->fhsm_readable)) {
12156+ if (vfsub_file_flags(file) & O_NONBLOCK)
12157+ err = -EAGAIN;
12158+ else
12159+ err = wait_event_interruptible_locked_irq
12160+ (fhsm->fhsm_wqh,
12161+ atomic_read(&fhsm->fhsm_readable));
12162+ }
12163+ spin_unlock_irq(&fhsm->fhsm_wqh.lock);
12164+ if (unlikely(err))
12165+ goto out;
12166+
12167+ /* sb may already be dead */
12168+ au_rw_read_lock(&sbinfo->si_rwsem);
12169+ readable = atomic_read(&fhsm->fhsm_readable);
12170+ if (readable > 0) {
12171+ sb = sbinfo->si_sb;
12172+ AuDebugOn(!sb);
12173+ /* exclude the bottom branch */
12174+ nfhsm = 0;
5afbbe0d
AM
12175+ bbot = au_fhsm_bottom(sb);
12176+ for (bindex = 0; bindex < bbot; bindex++) {
076b876e
AM
12177+ br = au_sbr(sb, bindex);
12178+ if (au_br_fhsm(br->br_perm))
12179+ nfhsm++;
12180+ }
12181+ err = -EMSGSIZE;
12182+ if (nfhsm * sizeof(struct aufs_stbr) <= count) {
12183+ atomic_set(&fhsm->fhsm_readable, 0);
12184+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
12185+ count);
12186+ }
12187+ }
12188+ au_rw_read_unlock(&sbinfo->si_rwsem);
12189+ if (!readable)
12190+ goto need_data;
12191+
12192+out:
12193+ return err;
12194+}
12195+
12196+static int au_fhsm_release(struct inode *inode, struct file *file)
12197+{
12198+ struct au_sbinfo *sbinfo;
12199+ struct au_fhsm *fhsm;
12200+
12201+ /* sb may already be dead */
12202+ sbinfo = file->private_data;
12203+ fhsm = &sbinfo->si_fhsm;
12204+ spin_lock(&fhsm->fhsm_spin);
12205+ fhsm->fhsm_pid = 0;
12206+ spin_unlock(&fhsm->fhsm_spin);
12207+ kobject_put(&sbinfo->si_kobj);
12208+
12209+ return 0;
12210+}
12211+
12212+static const struct file_operations au_fhsm_fops = {
12213+ .owner = THIS_MODULE,
12214+ .llseek = noop_llseek,
12215+ .read = au_fhsm_read,
12216+ .poll = au_fhsm_poll,
12217+ .release = au_fhsm_release
12218+};
12219+
12220+int au_fhsm_fd(struct super_block *sb, int oflags)
12221+{
12222+ int err, fd;
12223+ struct au_sbinfo *sbinfo;
12224+ struct au_fhsm *fhsm;
12225+
12226+ err = -EPERM;
12227+ if (unlikely(!capable(CAP_SYS_ADMIN)))
12228+ goto out;
12229+
12230+ err = -EINVAL;
12231+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
12232+ goto out;
12233+
12234+ err = 0;
12235+ sbinfo = au_sbi(sb);
12236+ fhsm = &sbinfo->si_fhsm;
12237+ spin_lock(&fhsm->fhsm_spin);
12238+ if (!fhsm->fhsm_pid)
12239+ fhsm->fhsm_pid = current->pid;
12240+ else
12241+ err = -EBUSY;
12242+ spin_unlock(&fhsm->fhsm_spin);
12243+ if (unlikely(err))
12244+ goto out;
12245+
12246+ oflags |= O_RDONLY;
12247+ /* oflags |= FMODE_NONOTIFY; */
12248+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
12249+ err = fd;
12250+ if (unlikely(fd < 0))
12251+ goto out_pid;
12252+
12253+ /* succeed reglardless 'fhsm' status */
12254+ kobject_get(&sbinfo->si_kobj);
12255+ si_noflush_read_lock(sb);
12256+ if (au_ftest_si(sbinfo, FHSM))
12257+ au_fhsm_wrote_all(sb, /*force*/0);
12258+ si_read_unlock(sb);
12259+ goto out; /* success */
12260+
12261+out_pid:
12262+ spin_lock(&fhsm->fhsm_spin);
12263+ fhsm->fhsm_pid = 0;
12264+ spin_unlock(&fhsm->fhsm_spin);
12265+out:
12266+ AuTraceErr(err);
12267+ return err;
12268+}
12269+
12270+/* ---------------------------------------------------------------------- */
12271+
12272+int au_fhsm_br_alloc(struct au_branch *br)
12273+{
12274+ int err;
12275+
12276+ err = 0;
12277+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
12278+ if (br->br_fhsm)
12279+ au_br_fhsm_init(br->br_fhsm);
12280+ else
12281+ err = -ENOMEM;
12282+
12283+ return err;
12284+}
12285+
12286+/* ---------------------------------------------------------------------- */
12287+
12288+void au_fhsm_fin(struct super_block *sb)
12289+{
12290+ au_fhsm_notify(sb, /*val*/-1);
12291+}
12292+
12293+void au_fhsm_init(struct au_sbinfo *sbinfo)
12294+{
12295+ struct au_fhsm *fhsm;
12296+
12297+ fhsm = &sbinfo->si_fhsm;
12298+ spin_lock_init(&fhsm->fhsm_spin);
12299+ init_waitqueue_head(&fhsm->fhsm_wqh);
12300+ atomic_set(&fhsm->fhsm_readable, 0);
12301+ fhsm->fhsm_expire
12302+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
c1595e42 12303+ fhsm->fhsm_bottom = -1;
076b876e
AM
12304+}
12305+
12306+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
12307+{
12308+ sbinfo->si_fhsm.fhsm_expire
12309+ = msecs_to_jiffies(sec * MSEC_PER_SEC);
12310+}
12311+
12312+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
12313+{
12314+ unsigned int u;
12315+
12316+ if (!au_ftest_si(sbinfo, FHSM))
12317+ return;
12318+
12319+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
12320+ if (u != AUFS_FHSM_CACHE_DEF_SEC)
12321+ seq_printf(seq, ",fhsm_sec=%u", u);
12322+}
7f207e10
AM
12323diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
12324--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
12325+++ linux/fs/aufs/file.c 2017-07-29 12:14:25.903042072 +0200
12326@@ -0,0 +1,858 @@
1facf9fc 12327+/*
a2654f78 12328+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 12329+ *
12330+ * This program, aufs is free software; you can redistribute it and/or modify
12331+ * it under the terms of the GNU General Public License as published by
12332+ * the Free Software Foundation; either version 2 of the License, or
12333+ * (at your option) any later version.
dece6358
AM
12334+ *
12335+ * This program is distributed in the hope that it will be useful,
12336+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12337+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12338+ * GNU General Public License for more details.
12339+ *
12340+ * You should have received a copy of the GNU General Public License
523b37e3 12341+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 12342+ */
12343+
12344+/*
4a4d8108 12345+ * handling file/dir, and address_space operation
1facf9fc 12346+ */
12347+
7eafdf33
AM
12348+#ifdef CONFIG_AUFS_DEBUG
12349+#include <linux/migrate.h>
12350+#endif
4a4d8108 12351+#include <linux/pagemap.h>
1facf9fc 12352+#include "aufs.h"
12353+
4a4d8108
AM
12354+/* drop flags for writing */
12355+unsigned int au_file_roflags(unsigned int flags)
12356+{
12357+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
12358+ flags |= O_RDONLY | O_NOATIME;
12359+ return flags;
12360+}
12361+
12362+/* common functions to regular file and dir */
12363+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 12364+ struct file *file, int force_wr)
1facf9fc 12365+{
1308ab2a 12366+ struct file *h_file;
4a4d8108
AM
12367+ struct dentry *h_dentry;
12368+ struct inode *h_inode;
12369+ struct super_block *sb;
12370+ struct au_branch *br;
12371+ struct path h_path;
b912730e 12372+ int err;
1facf9fc 12373+
4a4d8108
AM
12374+ /* a race condition can happen between open and unlink/rmdir */
12375+ h_file = ERR_PTR(-ENOENT);
12376+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 12377+ if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry)))
4a4d8108 12378+ goto out;
5527c038 12379+ h_inode = d_inode(h_dentry);
027c5e7a
AM
12380+ spin_lock(&h_dentry->d_lock);
12381+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
5527c038 12382+ /* || !d_inode(dentry)->i_nlink */
027c5e7a
AM
12383+ ;
12384+ spin_unlock(&h_dentry->d_lock);
12385+ if (unlikely(err))
4a4d8108 12386+ goto out;
1facf9fc 12387+
4a4d8108
AM
12388+ sb = dentry->d_sb;
12389+ br = au_sbr(sb, bindex);
b912730e
AM
12390+ err = au_br_test_oflag(flags, br);
12391+ h_file = ERR_PTR(err);
12392+ if (unlikely(err))
027c5e7a 12393+ goto out;
1facf9fc 12394+
4a4d8108 12395+ /* drop flags for writing */
5527c038 12396+ if (au_test_ro(sb, bindex, d_inode(dentry))) {
392086de
AM
12397+ if (force_wr && !(flags & O_WRONLY))
12398+ force_wr = 0;
4a4d8108 12399+ flags = au_file_roflags(flags);
392086de
AM
12400+ if (force_wr) {
12401+ h_file = ERR_PTR(-EROFS);
12402+ flags = au_file_roflags(flags);
12403+ if (unlikely(vfsub_native_ro(h_inode)
12404+ || IS_APPEND(h_inode)))
12405+ goto out;
12406+ flags &= ~O_ACCMODE;
12407+ flags |= O_WRONLY;
12408+ }
12409+ }
4a4d8108 12410+ flags &= ~O_CREAT;
5afbbe0d 12411+ au_br_get(br);
4a4d8108 12412+ h_path.dentry = h_dentry;
86dc4139 12413+ h_path.mnt = au_br_mnt(br);
38d290e6 12414+ h_file = vfsub_dentry_open(&h_path, flags);
4a4d8108
AM
12415+ if (IS_ERR(h_file))
12416+ goto out_br;
dece6358 12417+
b912730e 12418+ if (flags & __FMODE_EXEC) {
4a4d8108
AM
12419+ err = deny_write_access(h_file);
12420+ if (unlikely(err)) {
12421+ fput(h_file);
12422+ h_file = ERR_PTR(err);
12423+ goto out_br;
12424+ }
12425+ }
953406b4 12426+ fsnotify_open(h_file);
4a4d8108 12427+ goto out; /* success */
1facf9fc 12428+
4f0767ce 12429+out_br:
5afbbe0d 12430+ au_br_put(br);
4f0767ce 12431+out:
4a4d8108
AM
12432+ return h_file;
12433+}
1308ab2a 12434+
076b876e
AM
12435+static int au_cmoo(struct dentry *dentry)
12436+{
12437+ int err, cmoo;
12438+ unsigned int udba;
12439+ struct path h_path;
12440+ struct au_pin pin;
12441+ struct au_cp_generic cpg = {
12442+ .dentry = dentry,
12443+ .bdst = -1,
12444+ .bsrc = -1,
12445+ .len = -1,
12446+ .pin = &pin,
12447+ .flags = AuCpup_DTIME | AuCpup_HOPEN
12448+ };
7e9cd9fe 12449+ struct inode *delegated;
076b876e
AM
12450+ struct super_block *sb;
12451+ struct au_sbinfo *sbinfo;
12452+ struct au_fhsm *fhsm;
12453+ pid_t pid;
12454+ struct au_branch *br;
12455+ struct dentry *parent;
12456+ struct au_hinode *hdir;
12457+
12458+ DiMustWriteLock(dentry);
5527c038 12459+ IiMustWriteLock(d_inode(dentry));
076b876e
AM
12460+
12461+ err = 0;
12462+ if (IS_ROOT(dentry))
12463+ goto out;
5afbbe0d 12464+ cpg.bsrc = au_dbtop(dentry);
076b876e
AM
12465+ if (!cpg.bsrc)
12466+ goto out;
12467+
12468+ sb = dentry->d_sb;
12469+ sbinfo = au_sbi(sb);
12470+ fhsm = &sbinfo->si_fhsm;
12471+ pid = au_fhsm_pid(fhsm);
12472+ if (pid
12473+ && (current->pid == pid
12474+ || current->real_parent->pid == pid))
12475+ goto out;
12476+
12477+ br = au_sbr(sb, cpg.bsrc);
12478+ cmoo = au_br_cmoo(br->br_perm);
12479+ if (!cmoo)
12480+ goto out;
7e9cd9fe 12481+ if (!d_is_reg(dentry))
076b876e
AM
12482+ cmoo &= AuBrAttr_COO_ALL;
12483+ if (!cmoo)
12484+ goto out;
12485+
12486+ parent = dget_parent(dentry);
12487+ di_write_lock_parent(parent);
12488+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
12489+ cpg.bdst = err;
12490+ if (unlikely(err < 0)) {
12491+ err = 0; /* there is no upper writable branch */
12492+ goto out_dgrade;
12493+ }
12494+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
12495+
12496+ /* do not respect the coo attrib for the target branch */
12497+ err = au_cpup_dirs(dentry, cpg.bdst);
12498+ if (unlikely(err))
12499+ goto out_dgrade;
12500+
12501+ di_downgrade_lock(parent, AuLock_IR);
12502+ udba = au_opt_udba(sb);
12503+ err = au_pin(&pin, dentry, cpg.bdst, udba,
12504+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12505+ if (unlikely(err))
12506+ goto out_parent;
12507+
12508+ err = au_sio_cpup_simple(&cpg);
12509+ au_unpin(&pin);
12510+ if (unlikely(err))
12511+ goto out_parent;
12512+ if (!(cmoo & AuBrWAttr_MOO))
12513+ goto out_parent; /* success */
12514+
12515+ err = au_pin(&pin, dentry, cpg.bsrc, udba,
12516+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12517+ if (unlikely(err))
12518+ goto out_parent;
12519+
12520+ h_path.mnt = au_br_mnt(br);
12521+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
5527c038 12522+ hdir = au_hi(d_inode(parent), cpg.bsrc);
076b876e
AM
12523+ delegated = NULL;
12524+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
12525+ au_unpin(&pin);
12526+ /* todo: keep h_dentry or not? */
12527+ if (unlikely(err == -EWOULDBLOCK)) {
12528+ pr_warn("cannot retry for NFSv4 delegation"
12529+ " for an internal unlink\n");
12530+ iput(delegated);
12531+ }
12532+ if (unlikely(err)) {
12533+ pr_err("unlink %pd after coo failed (%d), ignored\n",
12534+ dentry, err);
12535+ err = 0;
12536+ }
12537+ goto out_parent; /* success */
12538+
12539+out_dgrade:
12540+ di_downgrade_lock(parent, AuLock_IR);
12541+out_parent:
12542+ di_read_unlock(parent, AuLock_IR);
12543+ dput(parent);
12544+out:
12545+ AuTraceErr(err);
12546+ return err;
12547+}
12548+
b912730e 12549+int au_do_open(struct file *file, struct au_do_open_args *args)
1facf9fc 12550+{
b912730e 12551+ int err, no_lock = args->no_lock;
1facf9fc 12552+ struct dentry *dentry;
076b876e 12553+ struct au_finfo *finfo;
1308ab2a 12554+
b912730e
AM
12555+ if (!no_lock)
12556+ err = au_finfo_init(file, args->fidir);
12557+ else {
12558+ lockdep_off();
12559+ err = au_finfo_init(file, args->fidir);
12560+ lockdep_on();
12561+ }
4a4d8108
AM
12562+ if (unlikely(err))
12563+ goto out;
1facf9fc 12564+
2000de60 12565+ dentry = file->f_path.dentry;
b912730e
AM
12566+ AuDebugOn(IS_ERR_OR_NULL(dentry));
12567+ if (!no_lock) {
12568+ di_write_lock_child(dentry);
12569+ err = au_cmoo(dentry);
12570+ di_downgrade_lock(dentry, AuLock_IR);
12571+ if (!err)
12572+ err = args->open(file, vfsub_file_flags(file), NULL);
12573+ di_read_unlock(dentry, AuLock_IR);
12574+ } else {
12575+ err = au_cmoo(dentry);
12576+ if (!err)
12577+ err = args->open(file, vfsub_file_flags(file),
12578+ args->h_file);
5afbbe0d 12579+ if (!err && au_fbtop(file) != au_dbtop(dentry))
b912730e
AM
12580+ /*
12581+ * cmoo happens after h_file was opened.
12582+ * need to refresh file later.
12583+ */
12584+ atomic_dec(&au_fi(file)->fi_generation);
12585+ }
1facf9fc 12586+
076b876e
AM
12587+ finfo = au_fi(file);
12588+ if (!err) {
12589+ finfo->fi_file = file;
12590+ au_sphl_add(&finfo->fi_hlist,
2000de60 12591+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
076b876e 12592+ }
b912730e
AM
12593+ if (!no_lock)
12594+ fi_write_unlock(file);
12595+ else {
12596+ lockdep_off();
12597+ fi_write_unlock(file);
12598+ lockdep_on();
12599+ }
4a4d8108 12600+ if (unlikely(err)) {
076b876e 12601+ finfo->fi_hdir = NULL;
1c60b727 12602+ au_finfo_fin(file);
1308ab2a 12603+ }
4a4d8108 12604+
4f0767ce 12605+out:
1308ab2a 12606+ return err;
12607+}
dece6358 12608+
4a4d8108 12609+int au_reopen_nondir(struct file *file)
1308ab2a 12610+{
4a4d8108 12611+ int err;
5afbbe0d 12612+ aufs_bindex_t btop;
4a4d8108
AM
12613+ struct dentry *dentry;
12614+ struct file *h_file, *h_file_tmp;
1308ab2a 12615+
2000de60 12616+ dentry = file->f_path.dentry;
5afbbe0d 12617+ btop = au_dbtop(dentry);
4a4d8108 12618+ h_file_tmp = NULL;
5afbbe0d 12619+ if (au_fbtop(file) == btop) {
4a4d8108
AM
12620+ h_file = au_hf_top(file);
12621+ if (file->f_mode == h_file->f_mode)
12622+ return 0; /* success */
12623+ h_file_tmp = h_file;
12624+ get_file(h_file_tmp);
5afbbe0d 12625+ au_set_h_fptr(file, btop, NULL);
4a4d8108
AM
12626+ }
12627+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
12628+ /*
12629+ * it can happen
12630+ * file exists on both of rw and ro
5afbbe0d 12631+ * open --> dbtop and fbtop are both 0
86dc4139
AM
12632+ * prepend a branch as rw, "rw" become ro
12633+ * remove rw/file
12634+ * delete the top branch, "rw" becomes rw again
5afbbe0d
AM
12635+ * --> dbtop is 1, fbtop is still 0
12636+ * write --> fbtop is 0 but dbtop is 1
86dc4139 12637+ */
5afbbe0d 12638+ /* AuDebugOn(au_fbtop(file) < btop); */
1308ab2a 12639+
5afbbe0d 12640+ h_file = au_h_open(dentry, btop, vfsub_file_flags(file) & ~O_TRUNC,
392086de 12641+ file, /*force_wr*/0);
4a4d8108 12642+ err = PTR_ERR(h_file);
86dc4139
AM
12643+ if (IS_ERR(h_file)) {
12644+ if (h_file_tmp) {
5afbbe0d
AM
12645+ au_sbr_get(dentry->d_sb, btop);
12646+ au_set_h_fptr(file, btop, h_file_tmp);
86dc4139
AM
12647+ h_file_tmp = NULL;
12648+ }
4a4d8108 12649+ goto out; /* todo: close all? */
86dc4139 12650+ }
4a4d8108
AM
12651+
12652+ err = 0;
5afbbe0d
AM
12653+ au_set_fbtop(file, btop);
12654+ au_set_h_fptr(file, btop, h_file);
4a4d8108
AM
12655+ au_update_figen(file);
12656+ /* todo: necessary? */
12657+ /* file->f_ra = h_file->f_ra; */
12658+
4f0767ce 12659+out:
4a4d8108
AM
12660+ if (h_file_tmp)
12661+ fput(h_file_tmp);
12662+ return err;
1facf9fc 12663+}
12664+
1308ab2a 12665+/* ---------------------------------------------------------------------- */
12666+
4a4d8108
AM
12667+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
12668+ struct dentry *hi_wh)
1facf9fc 12669+{
4a4d8108 12670+ int err;
5afbbe0d 12671+ aufs_bindex_t btop;
4a4d8108
AM
12672+ struct au_dinfo *dinfo;
12673+ struct dentry *h_dentry;
12674+ struct au_hdentry *hdp;
1facf9fc 12675+
2000de60 12676+ dinfo = au_di(file->f_path.dentry);
4a4d8108 12677+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 12678+
5afbbe0d
AM
12679+ btop = dinfo->di_btop;
12680+ dinfo->di_btop = btgt;
12681+ hdp = au_hdentry(dinfo, btgt);
12682+ h_dentry = hdp->hd_dentry;
12683+ hdp->hd_dentry = hi_wh;
4a4d8108 12684+ err = au_reopen_nondir(file);
5afbbe0d
AM
12685+ hdp->hd_dentry = h_dentry;
12686+ dinfo->di_btop = btop;
1facf9fc 12687+
1facf9fc 12688+ return err;
12689+}
12690+
4a4d8108 12691+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 12692+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 12693+{
4a4d8108 12694+ int err;
027c5e7a 12695+ struct inode *inode, *h_inode;
c2b27bf2
AM
12696+ struct dentry *h_dentry, *hi_wh;
12697+ struct au_cp_generic cpg = {
2000de60 12698+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12699+ .bdst = bcpup,
12700+ .bsrc = -1,
12701+ .len = len,
12702+ .pin = pin
12703+ };
1facf9fc 12704+
5afbbe0d 12705+ au_update_dbtop(cpg.dentry);
5527c038 12706+ inode = d_inode(cpg.dentry);
027c5e7a 12707+ h_inode = NULL;
5afbbe0d
AM
12708+ if (au_dbtop(cpg.dentry) <= bcpup
12709+ && au_dbbot(cpg.dentry) >= bcpup) {
c2b27bf2 12710+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
5527c038
JR
12711+ if (h_dentry && d_is_positive(h_dentry))
12712+ h_inode = d_inode(h_dentry);
027c5e7a 12713+ }
4a4d8108 12714+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 12715+ if (!hi_wh && !h_inode)
c2b27bf2 12716+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
12717+ else
12718+ /* already copied-up after unlink */
12719+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 12720+
4a4d8108 12721+ if (!err
38d290e6
JR
12722+ && (inode->i_nlink > 1
12723+ || (inode->i_state & I_LINKABLE))
c2b27bf2
AM
12724+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
12725+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 12726+
dece6358 12727+ return err;
1facf9fc 12728+}
12729+
4a4d8108
AM
12730+/*
12731+ * prepare the @file for writing.
12732+ */
12733+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 12734+{
4a4d8108 12735+ int err;
5afbbe0d 12736+ aufs_bindex_t dbtop;
c1595e42 12737+ struct dentry *parent;
86dc4139 12738+ struct inode *inode;
1facf9fc 12739+ struct super_block *sb;
4a4d8108 12740+ struct file *h_file;
c2b27bf2 12741+ struct au_cp_generic cpg = {
2000de60 12742+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12743+ .bdst = -1,
12744+ .bsrc = -1,
12745+ .len = len,
12746+ .pin = pin,
12747+ .flags = AuCpup_DTIME
12748+ };
1facf9fc 12749+
c2b27bf2 12750+ sb = cpg.dentry->d_sb;
5527c038 12751+ inode = d_inode(cpg.dentry);
5afbbe0d 12752+ cpg.bsrc = au_fbtop(file);
c2b27bf2 12753+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 12754+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
12755+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
12756+ /*flags*/0);
1facf9fc 12757+ goto out;
4a4d8108 12758+ }
1facf9fc 12759+
027c5e7a 12760+ /* need to cpup or reopen */
c2b27bf2 12761+ parent = dget_parent(cpg.dentry);
4a4d8108 12762+ di_write_lock_parent(parent);
c2b27bf2
AM
12763+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12764+ cpg.bdst = err;
4a4d8108
AM
12765+ if (unlikely(err < 0))
12766+ goto out_dgrade;
12767+ err = 0;
12768+
c2b27bf2
AM
12769+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
12770+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 12771+ if (unlikely(err))
4a4d8108
AM
12772+ goto out_dgrade;
12773+ }
12774+
c2b27bf2 12775+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
12776+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12777+ if (unlikely(err))
12778+ goto out_dgrade;
12779+
5afbbe0d
AM
12780+ dbtop = au_dbtop(cpg.dentry);
12781+ if (dbtop <= cpg.bdst)
c2b27bf2 12782+ cpg.bsrc = cpg.bdst;
027c5e7a 12783+
5afbbe0d 12784+ if (dbtop <= cpg.bdst /* just reopen */
c2b27bf2 12785+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 12786+ ) {
392086de 12787+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 12788+ if (IS_ERR(h_file))
027c5e7a 12789+ err = PTR_ERR(h_file);
86dc4139 12790+ else {
027c5e7a 12791+ di_downgrade_lock(parent, AuLock_IR);
5afbbe0d 12792+ if (dbtop > cpg.bdst)
c2b27bf2 12793+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
12794+ if (!err)
12795+ err = au_reopen_nondir(file);
c2b27bf2 12796+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 12797+ }
027c5e7a
AM
12798+ } else { /* copyup as wh and reopen */
12799+ /*
12800+ * since writable hfsplus branch is not supported,
12801+ * h_open_pre/post() are unnecessary.
12802+ */
c2b27bf2 12803+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 12804+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 12805+ }
4a4d8108
AM
12806+
12807+ if (!err) {
12808+ au_pin_set_parent_lflag(pin, /*lflag*/0);
12809+ goto out_dput; /* success */
12810+ }
12811+ au_unpin(pin);
12812+ goto out_unlock;
1facf9fc 12813+
4f0767ce 12814+out_dgrade:
4a4d8108 12815+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 12816+out_unlock:
4a4d8108 12817+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12818+out_dput:
4a4d8108 12819+ dput(parent);
4f0767ce 12820+out:
1facf9fc 12821+ return err;
12822+}
12823+
4a4d8108
AM
12824+/* ---------------------------------------------------------------------- */
12825+
12826+int au_do_flush(struct file *file, fl_owner_t id,
12827+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 12828+{
4a4d8108 12829+ int err;
1facf9fc 12830+ struct super_block *sb;
4a4d8108 12831+ struct inode *inode;
1facf9fc 12832+
c06a8ce3
AM
12833+ inode = file_inode(file);
12834+ sb = inode->i_sb;
4a4d8108
AM
12835+ si_noflush_read_lock(sb);
12836+ fi_read_lock(file);
b752ccd1 12837+ ii_read_lock_child(inode);
1facf9fc 12838+
4a4d8108
AM
12839+ err = flush(file, id);
12840+ au_cpup_attr_timesizes(inode);
1facf9fc 12841+
b752ccd1 12842+ ii_read_unlock(inode);
4a4d8108 12843+ fi_read_unlock(file);
1308ab2a 12844+ si_read_unlock(sb);
dece6358 12845+ return err;
1facf9fc 12846+}
12847+
4a4d8108
AM
12848+/* ---------------------------------------------------------------------- */
12849+
12850+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 12851+{
4a4d8108 12852+ int err;
4a4d8108
AM
12853+ struct au_pin pin;
12854+ struct au_finfo *finfo;
c2b27bf2 12855+ struct dentry *parent, *hi_wh;
4a4d8108 12856+ struct inode *inode;
1facf9fc 12857+ struct super_block *sb;
c2b27bf2 12858+ struct au_cp_generic cpg = {
2000de60 12859+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12860+ .bdst = -1,
12861+ .bsrc = -1,
12862+ .len = -1,
12863+ .pin = &pin,
12864+ .flags = AuCpup_DTIME
12865+ };
1facf9fc 12866+
4a4d8108
AM
12867+ FiMustWriteLock(file);
12868+
12869+ err = 0;
12870+ finfo = au_fi(file);
c2b27bf2 12871+ sb = cpg.dentry->d_sb;
5527c038 12872+ inode = d_inode(cpg.dentry);
5afbbe0d 12873+ cpg.bdst = au_ibtop(inode);
c2b27bf2 12874+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 12875+ goto out;
dece6358 12876+
c2b27bf2
AM
12877+ parent = dget_parent(cpg.dentry);
12878+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 12879+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
12880+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12881+ cpg.bdst = err;
4a4d8108
AM
12882+ di_read_unlock(parent, !AuLock_IR);
12883+ if (unlikely(err < 0))
12884+ goto out_parent;
12885+ err = 0;
1facf9fc 12886+ }
1facf9fc 12887+
4a4d8108 12888+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 12889+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
12890+ if (!S_ISDIR(inode->i_mode)
12891+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 12892+ && au_plink_test(inode)
c2b27bf2 12893+ && !d_unhashed(cpg.dentry)
5afbbe0d 12894+ && cpg.bdst < au_dbtop(cpg.dentry)) {
c2b27bf2 12895+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
12896+ if (unlikely(err))
12897+ goto out_unlock;
12898+
12899+ /* always superio. */
c2b27bf2 12900+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 12901+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 12902+ if (!err) {
c2b27bf2 12903+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
12904+ au_unpin(&pin);
12905+ }
4a4d8108
AM
12906+ } else if (hi_wh) {
12907+ /* already copied-up after unlink */
c2b27bf2 12908+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
12909+ *need_reopen = 0;
12910+ }
1facf9fc 12911+
4f0767ce 12912+out_unlock:
4a4d8108 12913+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12914+out_parent:
4a4d8108 12915+ dput(parent);
4f0767ce 12916+out:
1308ab2a 12917+ return err;
dece6358 12918+}
1facf9fc 12919+
4a4d8108 12920+static void au_do_refresh_dir(struct file *file)
dece6358 12921+{
5afbbe0d 12922+ aufs_bindex_t bindex, bbot, new_bindex, brid;
4a4d8108
AM
12923+ struct au_hfile *p, tmp, *q;
12924+ struct au_finfo *finfo;
1308ab2a 12925+ struct super_block *sb;
4a4d8108 12926+ struct au_fidir *fidir;
1facf9fc 12927+
4a4d8108 12928+ FiMustWriteLock(file);
1facf9fc 12929+
2000de60 12930+ sb = file->f_path.dentry->d_sb;
4a4d8108
AM
12931+ finfo = au_fi(file);
12932+ fidir = finfo->fi_hdir;
12933+ AuDebugOn(!fidir);
12934+ p = fidir->fd_hfile + finfo->fi_btop;
12935+ brid = p->hf_br->br_id;
5afbbe0d
AM
12936+ bbot = fidir->fd_bbot;
12937+ for (bindex = finfo->fi_btop; bindex <= bbot; bindex++, p++) {
4a4d8108
AM
12938+ if (!p->hf_file)
12939+ continue;
1308ab2a 12940+
4a4d8108
AM
12941+ new_bindex = au_br_index(sb, p->hf_br->br_id);
12942+ if (new_bindex == bindex)
12943+ continue;
12944+ if (new_bindex < 0) {
12945+ au_set_h_fptr(file, bindex, NULL);
12946+ continue;
12947+ }
1308ab2a 12948+
4a4d8108
AM
12949+ /* swap two lower inode, and loop again */
12950+ q = fidir->fd_hfile + new_bindex;
12951+ tmp = *q;
12952+ *q = *p;
12953+ *p = tmp;
12954+ if (tmp.hf_file) {
12955+ bindex--;
12956+ p--;
12957+ }
12958+ }
1308ab2a 12959+
4a4d8108 12960+ p = fidir->fd_hfile;
2000de60 12961+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) {
5afbbe0d
AM
12962+ bbot = au_sbbot(sb);
12963+ for (finfo->fi_btop = 0; finfo->fi_btop <= bbot;
4a4d8108
AM
12964+ finfo->fi_btop++, p++)
12965+ if (p->hf_file) {
c06a8ce3 12966+ if (file_inode(p->hf_file))
4a4d8108 12967+ break;
1c60b727 12968+ au_hfput(p, /*execed*/0);
4a4d8108
AM
12969+ }
12970+ } else {
5afbbe0d
AM
12971+ bbot = au_br_index(sb, brid);
12972+ for (finfo->fi_btop = 0; finfo->fi_btop < bbot;
4a4d8108
AM
12973+ finfo->fi_btop++, p++)
12974+ if (p->hf_file)
1c60b727 12975+ au_hfput(p, /*execed*/0);
5afbbe0d 12976+ bbot = au_sbbot(sb);
4a4d8108 12977+ }
1308ab2a 12978+
5afbbe0d
AM
12979+ p = fidir->fd_hfile + bbot;
12980+ for (fidir->fd_bbot = bbot; fidir->fd_bbot >= finfo->fi_btop;
4a4d8108
AM
12981+ fidir->fd_bbot--, p--)
12982+ if (p->hf_file) {
c06a8ce3 12983+ if (file_inode(p->hf_file))
4a4d8108 12984+ break;
1c60b727 12985+ au_hfput(p, /*execed*/0);
4a4d8108
AM
12986+ }
12987+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 12988+}
12989+
4a4d8108
AM
12990+/*
12991+ * after branch manipulating, refresh the file.
12992+ */
12993+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 12994+{
e2f27e51 12995+ int err, need_reopen, nbr;
5afbbe0d 12996+ aufs_bindex_t bbot, bindex;
4a4d8108 12997+ struct dentry *dentry;
e2f27e51 12998+ struct super_block *sb;
1308ab2a 12999+ struct au_finfo *finfo;
4a4d8108 13000+ struct au_hfile *hfile;
1facf9fc 13001+
2000de60 13002+ dentry = file->f_path.dentry;
e2f27e51
AM
13003+ sb = dentry->d_sb;
13004+ nbr = au_sbbot(sb) + 1;
1308ab2a 13005+ finfo = au_fi(file);
4a4d8108
AM
13006+ if (!finfo->fi_hdir) {
13007+ hfile = &finfo->fi_htop;
13008+ AuDebugOn(!hfile->hf_file);
e2f27e51 13009+ bindex = au_br_index(sb, hfile->hf_br->br_id);
4a4d8108
AM
13010+ AuDebugOn(bindex < 0);
13011+ if (bindex != finfo->fi_btop)
5afbbe0d 13012+ au_set_fbtop(file, bindex);
4a4d8108 13013+ } else {
e2f27e51 13014+ err = au_fidir_realloc(finfo, nbr, /*may_shrink*/0);
4a4d8108
AM
13015+ if (unlikely(err))
13016+ goto out;
13017+ au_do_refresh_dir(file);
13018+ }
1facf9fc 13019+
4a4d8108
AM
13020+ err = 0;
13021+ need_reopen = 1;
13022+ if (!au_test_mmapped(file))
13023+ err = au_file_refresh_by_inode(file, &need_reopen);
e2f27e51
AM
13024+ if (finfo->fi_hdir)
13025+ /* harmless if err */
13026+ au_fidir_realloc(finfo, nbr, /*may_shrink*/1);
027c5e7a 13027+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
13028+ err = reopen(file);
13029+ if (!err) {
13030+ au_update_figen(file);
13031+ goto out; /* success */
13032+ }
13033+
13034+ /* error, close all lower files */
13035+ if (finfo->fi_hdir) {
5afbbe0d
AM
13036+ bbot = au_fbbot_dir(file);
13037+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++)
4a4d8108
AM
13038+ au_set_h_fptr(file, bindex, NULL);
13039+ }
1facf9fc 13040+
4f0767ce 13041+out:
1facf9fc 13042+ return err;
13043+}
13044+
4a4d8108
AM
13045+/* common function to regular file and dir */
13046+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
521ced18 13047+ int wlock, unsigned int fi_lsc)
dece6358 13048+{
1308ab2a 13049+ int err;
4a4d8108 13050+ unsigned int sigen, figen;
5afbbe0d 13051+ aufs_bindex_t btop;
4a4d8108
AM
13052+ unsigned char pseudo_link;
13053+ struct dentry *dentry;
13054+ struct inode *inode;
1facf9fc 13055+
4a4d8108 13056+ err = 0;
2000de60 13057+ dentry = file->f_path.dentry;
5527c038 13058+ inode = d_inode(dentry);
4a4d8108 13059+ sigen = au_sigen(dentry->d_sb);
521ced18 13060+ fi_write_lock_nested(file, fi_lsc);
4a4d8108 13061+ figen = au_figen(file);
521ced18
JR
13062+ if (!fi_lsc)
13063+ di_write_lock_child(dentry);
13064+ else
13065+ di_write_lock_child2(dentry);
5afbbe0d
AM
13066+ btop = au_dbtop(dentry);
13067+ pseudo_link = (btop != au_ibtop(inode));
13068+ if (sigen == figen && !pseudo_link && au_fbtop(file) == btop) {
4a4d8108
AM
13069+ if (!wlock) {
13070+ di_downgrade_lock(dentry, AuLock_IR);
13071+ fi_downgrade_lock(file);
13072+ }
13073+ goto out; /* success */
13074+ }
dece6358 13075+
4a4d8108 13076+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 13077+ if (au_digen_test(dentry, sigen)) {
4a4d8108 13078+ err = au_reval_dpath(dentry, sigen);
027c5e7a 13079+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 13080+ }
dece6358 13081+
027c5e7a
AM
13082+ if (!err)
13083+ err = refresh_file(file, reopen);
4a4d8108
AM
13084+ if (!err) {
13085+ if (!wlock) {
13086+ di_downgrade_lock(dentry, AuLock_IR);
13087+ fi_downgrade_lock(file);
13088+ }
13089+ } else {
13090+ di_write_unlock(dentry);
13091+ fi_write_unlock(file);
13092+ }
1facf9fc 13093+
4f0767ce 13094+out:
1308ab2a 13095+ return err;
13096+}
1facf9fc 13097+
4a4d8108
AM
13098+/* ---------------------------------------------------------------------- */
13099+
13100+/* cf. aufs_nopage() */
13101+/* for madvise(2) */
13102+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 13103+{
4a4d8108
AM
13104+ unlock_page(page);
13105+ return 0;
13106+}
1facf9fc 13107+
4a4d8108 13108+/* it will never be called, but necessary to support O_DIRECT */
5afbbe0d 13109+static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
4a4d8108 13110+{ BUG(); return 0; }
1facf9fc 13111+
4a4d8108
AM
13112+/* they will never be called. */
13113+#ifdef CONFIG_AUFS_DEBUG
13114+static int aufs_write_begin(struct file *file, struct address_space *mapping,
13115+ loff_t pos, unsigned len, unsigned flags,
13116+ struct page **pagep, void **fsdata)
13117+{ AuUnsupport(); return 0; }
13118+static int aufs_write_end(struct file *file, struct address_space *mapping,
13119+ loff_t pos, unsigned len, unsigned copied,
13120+ struct page *page, void *fsdata)
13121+{ AuUnsupport(); return 0; }
13122+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
13123+{ AuUnsupport(); return 0; }
1308ab2a 13124+
4a4d8108
AM
13125+static int aufs_set_page_dirty(struct page *page)
13126+{ AuUnsupport(); return 0; }
392086de
AM
13127+static void aufs_invalidatepage(struct page *page, unsigned int offset,
13128+ unsigned int length)
4a4d8108
AM
13129+{ AuUnsupport(); }
13130+static int aufs_releasepage(struct page *page, gfp_t gfp)
13131+{ AuUnsupport(); return 0; }
79b8bda9 13132+#if 0 /* called by memory compaction regardless file */
4a4d8108 13133+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 13134+ struct page *page, enum migrate_mode mode)
4a4d8108 13135+{ AuUnsupport(); return 0; }
79b8bda9 13136+#endif
e2f27e51
AM
13137+static bool aufs_isolate_page(struct page *page, isolate_mode_t mode)
13138+{ AuUnsupport(); return true; }
13139+static void aufs_putback_page(struct page *page)
13140+{ AuUnsupport(); }
4a4d8108
AM
13141+static int aufs_launder_page(struct page *page)
13142+{ AuUnsupport(); return 0; }
13143+static int aufs_is_partially_uptodate(struct page *page,
38d290e6
JR
13144+ unsigned long from,
13145+ unsigned long count)
4a4d8108 13146+{ AuUnsupport(); return 0; }
392086de
AM
13147+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
13148+ bool *writeback)
13149+{ AuUnsupport(); }
4a4d8108
AM
13150+static int aufs_error_remove_page(struct address_space *mapping,
13151+ struct page *page)
13152+{ AuUnsupport(); return 0; }
b4510431
AM
13153+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
13154+ sector_t *span)
13155+{ AuUnsupport(); return 0; }
13156+static void aufs_swap_deactivate(struct file *file)
13157+{ AuUnsupport(); }
4a4d8108
AM
13158+#endif /* CONFIG_AUFS_DEBUG */
13159+
13160+const struct address_space_operations aufs_aop = {
13161+ .readpage = aufs_readpage,
13162+ .direct_IO = aufs_direct_IO,
4a4d8108
AM
13163+#ifdef CONFIG_AUFS_DEBUG
13164+ .writepage = aufs_writepage,
4a4d8108
AM
13165+ /* no writepages, because of writepage */
13166+ .set_page_dirty = aufs_set_page_dirty,
13167+ /* no readpages, because of readpage */
13168+ .write_begin = aufs_write_begin,
13169+ .write_end = aufs_write_end,
13170+ /* no bmap, no block device */
13171+ .invalidatepage = aufs_invalidatepage,
13172+ .releasepage = aufs_releasepage,
79b8bda9
AM
13173+ /* is fallback_migrate_page ok? */
13174+ /* .migratepage = aufs_migratepage, */
e2f27e51
AM
13175+ .isolate_page = aufs_isolate_page,
13176+ .putback_page = aufs_putback_page,
4a4d8108
AM
13177+ .launder_page = aufs_launder_page,
13178+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 13179+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
13180+ .error_remove_page = aufs_error_remove_page,
13181+ .swap_activate = aufs_swap_activate,
13182+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 13183+#endif /* CONFIG_AUFS_DEBUG */
dece6358 13184+};
7f207e10
AM
13185diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
13186--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
3c1bdaff
AM
13187+++ linux/fs/aufs/file.h 2017-09-05 10:42:11.058755349 +0200
13188@@ -0,0 +1,331 @@
4a4d8108 13189+/*
a2654f78 13190+ * Copyright (C) 2005-2017 Junjiro R. Okajima
4a4d8108
AM
13191+ *
13192+ * This program, aufs is free software; you can redistribute it and/or modify
13193+ * it under the terms of the GNU General Public License as published by
13194+ * the Free Software Foundation; either version 2 of the License, or
13195+ * (at your option) any later version.
13196+ *
13197+ * This program is distributed in the hope that it will be useful,
13198+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13199+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13200+ * GNU General Public License for more details.
13201+ *
13202+ * You should have received a copy of the GNU General Public License
523b37e3 13203+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 13204+ */
1facf9fc 13205+
4a4d8108
AM
13206+/*
13207+ * file operations
13208+ */
1facf9fc 13209+
4a4d8108
AM
13210+#ifndef __AUFS_FILE_H__
13211+#define __AUFS_FILE_H__
1facf9fc 13212+
4a4d8108 13213+#ifdef __KERNEL__
1facf9fc 13214+
2cbb1c4b 13215+#include <linux/file.h>
4a4d8108 13216+#include <linux/fs.h>
3c1bdaff 13217+#include <linux/mm_types.h>
4a4d8108 13218+#include <linux/poll.h>
4a4d8108 13219+#include "rwsem.h"
1facf9fc 13220+
4a4d8108
AM
13221+struct au_branch;
13222+struct au_hfile {
13223+ struct file *hf_file;
13224+ struct au_branch *hf_br;
13225+};
1facf9fc 13226+
4a4d8108
AM
13227+struct au_vdir;
13228+struct au_fidir {
13229+ aufs_bindex_t fd_bbot;
13230+ aufs_bindex_t fd_nent;
13231+ struct au_vdir *fd_vdir_cache;
13232+ struct au_hfile fd_hfile[];
13233+};
1facf9fc 13234+
4a4d8108 13235+static inline int au_fidir_sz(int nent)
dece6358 13236+{
4f0767ce
JR
13237+ AuDebugOn(nent < 0);
13238+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 13239+}
1facf9fc 13240+
4a4d8108
AM
13241+struct au_finfo {
13242+ atomic_t fi_generation;
dece6358 13243+
4a4d8108
AM
13244+ struct au_rwsem fi_rwsem;
13245+ aufs_bindex_t fi_btop;
13246+
13247+ /* do not union them */
13248+ struct { /* for non-dir */
13249+ struct au_hfile fi_htop;
2cbb1c4b 13250+ atomic_t fi_mmapped;
4a4d8108
AM
13251+ };
13252+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3
AM
13253+
13254+ struct hlist_node fi_hlist;
1c60b727 13255+ struct file *fi_file; /* very ugly */
4a4d8108 13256+} ____cacheline_aligned_in_smp;
1facf9fc 13257+
4a4d8108 13258+/* ---------------------------------------------------------------------- */
1facf9fc 13259+
4a4d8108
AM
13260+/* file.c */
13261+extern const struct address_space_operations aufs_aop;
13262+unsigned int au_file_roflags(unsigned int flags);
13263+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 13264+ struct file *file, int force_wr);
b912730e
AM
13265+struct au_do_open_args {
13266+ int no_lock;
13267+ int (*open)(struct file *file, int flags,
13268+ struct file *h_file);
13269+ struct au_fidir *fidir;
13270+ struct file *h_file;
13271+};
13272+int au_do_open(struct file *file, struct au_do_open_args *args);
4a4d8108
AM
13273+int au_reopen_nondir(struct file *file);
13274+struct au_pin;
13275+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
13276+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
521ced18 13277+ int wlock, unsigned int fi_lsc);
4a4d8108
AM
13278+int au_do_flush(struct file *file, fl_owner_t id,
13279+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 13280+
4a4d8108
AM
13281+/* poll.c */
13282+#ifdef CONFIG_AUFS_POLL
13283+unsigned int aufs_poll(struct file *file, poll_table *wait);
13284+#endif
1facf9fc 13285+
4a4d8108
AM
13286+#ifdef CONFIG_AUFS_BR_HFSPLUS
13287+/* hfsplus.c */
392086de
AM
13288+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
13289+ int force_wr);
4a4d8108
AM
13290+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
13291+ struct file *h_file);
13292+#else
c1595e42
JR
13293+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
13294+ aufs_bindex_t bindex, int force_wr)
4a4d8108
AM
13295+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
13296+ struct file *h_file);
13297+#endif
1facf9fc 13298+
4a4d8108
AM
13299+/* f_op.c */
13300+extern const struct file_operations aufs_file_fop;
b912730e 13301+int au_do_open_nondir(struct file *file, int flags, struct file *h_file);
4a4d8108 13302+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
521ced18 13303+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc);
4a4d8108 13304+
4a4d8108 13305+/* finfo.c */
f0c0a007 13306+void au_hfput(struct au_hfile *hf, int execed);
4a4d8108
AM
13307+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
13308+ struct file *h_file);
1facf9fc 13309+
4a4d8108 13310+void au_update_figen(struct file *file);
4a4d8108 13311+struct au_fidir *au_fidir_alloc(struct super_block *sb);
e2f27e51 13312+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink);
1facf9fc 13313+
4a4d8108 13314+void au_fi_init_once(void *_fi);
1c60b727 13315+void au_finfo_fin(struct file *file);
4a4d8108 13316+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 13317+
4a4d8108
AM
13318+/* ioctl.c */
13319+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
13320+#ifdef CONFIG_COMPAT
13321+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
13322+ unsigned long arg);
c2b27bf2
AM
13323+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
13324+ unsigned long arg);
b752ccd1 13325+#endif
1facf9fc 13326+
4a4d8108 13327+/* ---------------------------------------------------------------------- */
1facf9fc 13328+
4a4d8108
AM
13329+static inline struct au_finfo *au_fi(struct file *file)
13330+{
38d290e6 13331+ return file->private_data;
4a4d8108 13332+}
1facf9fc 13333+
4a4d8108 13334+/* ---------------------------------------------------------------------- */
1facf9fc 13335+
4a4d8108
AM
13336+/*
13337+ * fi_read_lock, fi_write_lock,
13338+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
13339+ */
13340+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 13341+
521ced18
JR
13342+/* lock subclass for finfo */
13343+enum {
13344+ AuLsc_FI_1,
13345+ AuLsc_FI_2
13346+};
13347+
13348+static inline void fi_read_lock_nested(struct file *f, unsigned int lsc)
13349+{
13350+ au_rw_read_lock_nested(&au_fi(f)->fi_rwsem, lsc);
13351+}
13352+
13353+static inline void fi_write_lock_nested(struct file *f, unsigned int lsc)
13354+{
13355+ au_rw_write_lock_nested(&au_fi(f)->fi_rwsem, lsc);
13356+}
13357+
13358+/*
13359+ * fi_read_lock_1, fi_write_lock_1,
13360+ * fi_read_lock_2, fi_write_lock_2
13361+ */
13362+#define AuReadLockFunc(name) \
13363+static inline void fi_read_lock_##name(struct file *f) \
13364+{ fi_read_lock_nested(f, AuLsc_FI_##name); }
13365+
13366+#define AuWriteLockFunc(name) \
13367+static inline void fi_write_lock_##name(struct file *f) \
13368+{ fi_write_lock_nested(f, AuLsc_FI_##name); }
13369+
13370+#define AuRWLockFuncs(name) \
13371+ AuReadLockFunc(name) \
13372+ AuWriteLockFunc(name)
13373+
13374+AuRWLockFuncs(1);
13375+AuRWLockFuncs(2);
13376+
13377+#undef AuReadLockFunc
13378+#undef AuWriteLockFunc
13379+#undef AuRWLockFuncs
13380+
4a4d8108
AM
13381+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
13382+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
13383+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 13384+
1308ab2a 13385+/* ---------------------------------------------------------------------- */
13386+
4a4d8108 13387+/* todo: hard/soft set? */
5afbbe0d 13388+static inline aufs_bindex_t au_fbtop(struct file *file)
dece6358 13389+{
4a4d8108
AM
13390+ FiMustAnyLock(file);
13391+ return au_fi(file)->fi_btop;
13392+}
dece6358 13393+
5afbbe0d 13394+static inline aufs_bindex_t au_fbbot_dir(struct file *file)
4a4d8108
AM
13395+{
13396+ FiMustAnyLock(file);
13397+ AuDebugOn(!au_fi(file)->fi_hdir);
13398+ return au_fi(file)->fi_hdir->fd_bbot;
13399+}
1facf9fc 13400+
4a4d8108
AM
13401+static inline struct au_vdir *au_fvdir_cache(struct file *file)
13402+{
13403+ FiMustAnyLock(file);
13404+ AuDebugOn(!au_fi(file)->fi_hdir);
13405+ return au_fi(file)->fi_hdir->fd_vdir_cache;
13406+}
1facf9fc 13407+
5afbbe0d 13408+static inline void au_set_fbtop(struct file *file, aufs_bindex_t bindex)
4a4d8108
AM
13409+{
13410+ FiMustWriteLock(file);
13411+ au_fi(file)->fi_btop = bindex;
13412+}
1facf9fc 13413+
5afbbe0d 13414+static inline void au_set_fbbot_dir(struct file *file, aufs_bindex_t bindex)
4a4d8108
AM
13415+{
13416+ FiMustWriteLock(file);
13417+ AuDebugOn(!au_fi(file)->fi_hdir);
13418+ au_fi(file)->fi_hdir->fd_bbot = bindex;
13419+}
1308ab2a 13420+
4a4d8108
AM
13421+static inline void au_set_fvdir_cache(struct file *file,
13422+ struct au_vdir *vdir_cache)
13423+{
13424+ FiMustWriteLock(file);
13425+ AuDebugOn(!au_fi(file)->fi_hdir);
13426+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
13427+}
dece6358 13428+
4a4d8108
AM
13429+static inline struct file *au_hf_top(struct file *file)
13430+{
13431+ FiMustAnyLock(file);
13432+ AuDebugOn(au_fi(file)->fi_hdir);
13433+ return au_fi(file)->fi_htop.hf_file;
13434+}
1facf9fc 13435+
4a4d8108
AM
13436+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
13437+{
13438+ FiMustAnyLock(file);
13439+ AuDebugOn(!au_fi(file)->fi_hdir);
13440+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
13441+}
13442+
4a4d8108
AM
13443+/* todo: memory barrier? */
13444+static inline unsigned int au_figen(struct file *f)
dece6358 13445+{
4a4d8108
AM
13446+ return atomic_read(&au_fi(f)->fi_generation);
13447+}
dece6358 13448+
2cbb1c4b
JR
13449+static inline void au_set_mmapped(struct file *f)
13450+{
13451+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
13452+ return;
0c3ec466 13453+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
13454+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
13455+ ;
13456+}
13457+
13458+static inline void au_unset_mmapped(struct file *f)
13459+{
13460+ atomic_dec(&au_fi(f)->fi_mmapped);
13461+}
13462+
4a4d8108
AM
13463+static inline int au_test_mmapped(struct file *f)
13464+{
2cbb1c4b
JR
13465+ return atomic_read(&au_fi(f)->fi_mmapped);
13466+}
13467+
13468+/* customize vma->vm_file */
13469+
13470+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
13471+ struct file *file)
13472+{
53392da6
AM
13473+ struct file *f;
13474+
13475+ f = vma->vm_file;
2cbb1c4b
JR
13476+ get_file(file);
13477+ vma->vm_file = file;
53392da6 13478+ fput(f);
2cbb1c4b
JR
13479+}
13480+
13481+#ifdef CONFIG_MMU
13482+#define AuDbgVmRegion(file, vma) do {} while (0)
13483+
13484+static inline void au_vm_file_reset(struct vm_area_struct *vma,
13485+ struct file *file)
13486+{
13487+ au_do_vm_file_reset(vma, file);
13488+}
13489+#else
13490+#define AuDbgVmRegion(file, vma) \
13491+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
13492+
13493+static inline void au_vm_file_reset(struct vm_area_struct *vma,
13494+ struct file *file)
13495+{
53392da6
AM
13496+ struct file *f;
13497+
2cbb1c4b 13498+ au_do_vm_file_reset(vma, file);
53392da6 13499+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
13500+ get_file(file);
13501+ vma->vm_region->vm_file = file;
53392da6 13502+ fput(f);
2cbb1c4b
JR
13503+}
13504+#endif /* CONFIG_MMU */
13505+
13506+/* handle vma->vm_prfile */
fb47a38f 13507+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
13508+ struct file *file)
13509+{
2cbb1c4b
JR
13510+ get_file(file);
13511+ vma->vm_prfile = file;
13512+#ifndef CONFIG_MMU
13513+ get_file(file);
13514+ vma->vm_region->vm_prfile = file;
13515+#endif
fb47a38f 13516+}
1308ab2a 13517+
4a4d8108
AM
13518+#endif /* __KERNEL__ */
13519+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
13520diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
13521--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
13522+++ linux/fs/aufs/finfo.c 2017-07-29 12:14:25.903042072 +0200
13523@@ -0,0 +1,148 @@
4a4d8108 13524+/*
a2654f78 13525+ * Copyright (C) 2005-2017 Junjiro R. Okajima
4a4d8108
AM
13526+ *
13527+ * This program, aufs is free software; you can redistribute it and/or modify
13528+ * it under the terms of the GNU General Public License as published by
13529+ * the Free Software Foundation; either version 2 of the License, or
13530+ * (at your option) any later version.
13531+ *
13532+ * This program is distributed in the hope that it will be useful,
13533+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13534+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13535+ * GNU General Public License for more details.
13536+ *
13537+ * You should have received a copy of the GNU General Public License
523b37e3 13538+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 13539+ */
1308ab2a 13540+
4a4d8108
AM
13541+/*
13542+ * file private data
13543+ */
1facf9fc 13544+
4a4d8108 13545+#include "aufs.h"
1facf9fc 13546+
f0c0a007 13547+void au_hfput(struct au_hfile *hf, int execed)
4a4d8108 13548+{
f0c0a007 13549+ if (execed)
4a4d8108
AM
13550+ allow_write_access(hf->hf_file);
13551+ fput(hf->hf_file);
13552+ hf->hf_file = NULL;
5afbbe0d 13553+ au_br_put(hf->hf_br);
4a4d8108
AM
13554+ hf->hf_br = NULL;
13555+}
1facf9fc 13556+
4a4d8108
AM
13557+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
13558+{
13559+ struct au_finfo *finfo = au_fi(file);
13560+ struct au_hfile *hf;
13561+ struct au_fidir *fidir;
13562+
13563+ fidir = finfo->fi_hdir;
13564+ if (!fidir) {
13565+ AuDebugOn(finfo->fi_btop != bindex);
13566+ hf = &finfo->fi_htop;
13567+ } else
13568+ hf = fidir->fd_hfile + bindex;
13569+
13570+ if (hf && hf->hf_file)
f0c0a007 13571+ au_hfput(hf, vfsub_file_execed(file));
4a4d8108
AM
13572+ if (val) {
13573+ FiMustWriteLock(file);
b912730e 13574+ AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry));
4a4d8108 13575+ hf->hf_file = val;
2000de60 13576+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex);
1308ab2a 13577+ }
4a4d8108 13578+}
1facf9fc 13579+
4a4d8108
AM
13580+void au_update_figen(struct file *file)
13581+{
2000de60 13582+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry));
4a4d8108 13583+ /* smp_mb(); */ /* atomic_set */
1facf9fc 13584+}
13585+
4a4d8108
AM
13586+/* ---------------------------------------------------------------------- */
13587+
4a4d8108
AM
13588+struct au_fidir *au_fidir_alloc(struct super_block *sb)
13589+{
13590+ struct au_fidir *fidir;
13591+ int nbr;
13592+
5afbbe0d 13593+ nbr = au_sbbot(sb) + 1;
4a4d8108
AM
13594+ if (nbr < 2)
13595+ nbr = 2; /* initial allocate for 2 branches */
13596+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
13597+ if (fidir) {
13598+ fidir->fd_bbot = -1;
13599+ fidir->fd_nent = nbr;
4a4d8108
AM
13600+ }
13601+
13602+ return fidir;
13603+}
13604+
e2f27e51 13605+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink)
4a4d8108
AM
13606+{
13607+ int err;
13608+ struct au_fidir *fidir, *p;
13609+
13610+ AuRwMustWriteLock(&finfo->fi_rwsem);
13611+ fidir = finfo->fi_hdir;
13612+ AuDebugOn(!fidir);
13613+
13614+ err = -ENOMEM;
13615+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
e2f27e51 13616+ GFP_NOFS, may_shrink);
4a4d8108
AM
13617+ if (p) {
13618+ p->fd_nent = nbr;
13619+ finfo->fi_hdir = p;
13620+ err = 0;
13621+ }
1facf9fc 13622+
dece6358 13623+ return err;
1facf9fc 13624+}
1308ab2a 13625+
13626+/* ---------------------------------------------------------------------- */
13627+
1c60b727 13628+void au_finfo_fin(struct file *file)
1308ab2a 13629+{
4a4d8108
AM
13630+ struct au_finfo *finfo;
13631+
2000de60 13632+ au_nfiles_dec(file->f_path.dentry->d_sb);
7f207e10 13633+
4a4d8108
AM
13634+ finfo = au_fi(file);
13635+ AuDebugOn(finfo->fi_hdir);
13636+ AuRwDestroy(&finfo->fi_rwsem);
1c60b727 13637+ au_cache_free_finfo(finfo);
1308ab2a 13638+}
1308ab2a 13639+
e49829fe 13640+void au_fi_init_once(void *_finfo)
4a4d8108 13641+{
e49829fe 13642+ struct au_finfo *finfo = _finfo;
1308ab2a 13643+
e49829fe 13644+ au_rw_init(&finfo->fi_rwsem);
4a4d8108 13645+}
1308ab2a 13646+
4a4d8108
AM
13647+int au_finfo_init(struct file *file, struct au_fidir *fidir)
13648+{
1716fcea 13649+ int err;
4a4d8108
AM
13650+ struct au_finfo *finfo;
13651+ struct dentry *dentry;
13652+
13653+ err = -ENOMEM;
2000de60 13654+ dentry = file->f_path.dentry;
4a4d8108
AM
13655+ finfo = au_cache_alloc_finfo();
13656+ if (unlikely(!finfo))
13657+ goto out;
13658+
13659+ err = 0;
7f207e10 13660+ au_nfiles_inc(dentry->d_sb);
4a4d8108
AM
13661+ au_rw_write_lock(&finfo->fi_rwsem);
13662+ finfo->fi_btop = -1;
13663+ finfo->fi_hdir = fidir;
13664+ atomic_set(&finfo->fi_generation, au_digen(dentry));
13665+ /* smp_mb(); */ /* atomic_set */
13666+
13667+ file->private_data = finfo;
13668+
13669+out:
13670+ return err;
13671+}
7f207e10
AM
13672diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
13673--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
13674+++ linux/fs/aufs/f_op.c 2017-07-29 12:14:25.903042072 +0200
13675@@ -0,0 +1,817 @@
dece6358 13676+/*
a2654f78 13677+ * Copyright (C) 2005-2017 Junjiro R. Okajima
dece6358
AM
13678+ *
13679+ * This program, aufs is free software; you can redistribute it and/or modify
13680+ * it under the terms of the GNU General Public License as published by
13681+ * the Free Software Foundation; either version 2 of the License, or
13682+ * (at your option) any later version.
13683+ *
13684+ * This program is distributed in the hope that it will be useful,
13685+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13686+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13687+ * GNU General Public License for more details.
13688+ *
13689+ * You should have received a copy of the GNU General Public License
523b37e3 13690+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 13691+ */
1facf9fc 13692+
13693+/*
4a4d8108 13694+ * file and vm operations
1facf9fc 13695+ */
dece6358 13696+
86dc4139 13697+#include <linux/aio.h>
4a4d8108
AM
13698+#include <linux/fs_stack.h>
13699+#include <linux/mman.h>
4a4d8108 13700+#include <linux/security.h>
dece6358
AM
13701+#include "aufs.h"
13702+
b912730e 13703+int au_do_open_nondir(struct file *file, int flags, struct file *h_file)
1facf9fc 13704+{
4a4d8108
AM
13705+ int err;
13706+ aufs_bindex_t bindex;
8cdd5066 13707+ struct dentry *dentry, *h_dentry;
4a4d8108 13708+ struct au_finfo *finfo;
38d290e6 13709+ struct inode *h_inode;
4a4d8108
AM
13710+
13711+ FiMustWriteLock(file);
13712+
523b37e3 13713+ err = 0;
2000de60 13714+ dentry = file->f_path.dentry;
b912730e 13715+ AuDebugOn(IS_ERR_OR_NULL(dentry));
4a4d8108
AM
13716+ finfo = au_fi(file);
13717+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 13718+ atomic_set(&finfo->fi_mmapped, 0);
5afbbe0d 13719+ bindex = au_dbtop(dentry);
8cdd5066
JR
13720+ if (!h_file) {
13721+ h_dentry = au_h_dptr(dentry, bindex);
13722+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
13723+ if (unlikely(err))
13724+ goto out;
b912730e 13725+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
8cdd5066
JR
13726+ } else {
13727+ h_dentry = h_file->f_path.dentry;
13728+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb);
13729+ if (unlikely(err))
13730+ goto out;
b912730e 13731+ get_file(h_file);
8cdd5066 13732+ }
4a4d8108
AM
13733+ if (IS_ERR(h_file))
13734+ err = PTR_ERR(h_file);
13735+ else {
38d290e6
JR
13736+ if ((flags & __O_TMPFILE)
13737+ && !(flags & O_EXCL)) {
13738+ h_inode = file_inode(h_file);
13739+ spin_lock(&h_inode->i_lock);
13740+ h_inode->i_state |= I_LINKABLE;
13741+ spin_unlock(&h_inode->i_lock);
13742+ }
5afbbe0d 13743+ au_set_fbtop(file, bindex);
4a4d8108
AM
13744+ au_set_h_fptr(file, bindex, h_file);
13745+ au_update_figen(file);
13746+ /* todo: necessary? */
13747+ /* file->f_ra = h_file->f_ra; */
13748+ }
027c5e7a 13749+
8cdd5066 13750+out:
4a4d8108 13751+ return err;
1facf9fc 13752+}
13753+
4a4d8108
AM
13754+static int aufs_open_nondir(struct inode *inode __maybe_unused,
13755+ struct file *file)
1facf9fc 13756+{
4a4d8108 13757+ int err;
1308ab2a 13758+ struct super_block *sb;
b912730e
AM
13759+ struct au_do_open_args args = {
13760+ .open = au_do_open_nondir
13761+ };
1facf9fc 13762+
523b37e3
AM
13763+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
13764+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 13765+
2000de60 13766+ sb = file->f_path.dentry->d_sb;
4a4d8108 13767+ si_read_lock(sb, AuLock_FLUSH);
b912730e 13768+ err = au_do_open(file, &args);
4a4d8108
AM
13769+ si_read_unlock(sb);
13770+ return err;
13771+}
1facf9fc 13772+
4a4d8108
AM
13773+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
13774+{
13775+ struct au_finfo *finfo;
13776+ aufs_bindex_t bindex;
1facf9fc 13777+
4a4d8108 13778+ finfo = au_fi(file);
2000de60
JR
13779+ au_sphl_del(&finfo->fi_hlist,
13780+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108 13781+ bindex = finfo->fi_btop;
b4510431 13782+ if (bindex >= 0)
4a4d8108 13783+ au_set_h_fptr(file, bindex, NULL);
7f207e10 13784+
1c60b727 13785+ au_finfo_fin(file);
4a4d8108 13786+ return 0;
1facf9fc 13787+}
13788+
4a4d8108
AM
13789+/* ---------------------------------------------------------------------- */
13790+
13791+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 13792+{
1308ab2a 13793+ int err;
4a4d8108
AM
13794+ struct file *h_file;
13795+
13796+ err = 0;
13797+ h_file = au_hf_top(file);
13798+ if (h_file)
13799+ err = vfsub_flush(h_file, id);
13800+ return err;
13801+}
13802+
13803+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
13804+{
13805+ return au_do_flush(file, id, au_do_flush_nondir);
13806+}
13807+
13808+/* ---------------------------------------------------------------------- */
9dbd164d
AM
13809+/*
13810+ * read and write functions acquire [fdi]_rwsem once, but release before
13811+ * mmap_sem. This is because to stop a race condition between mmap(2).
13812+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
13813+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
13814+ * read functions after [fdi]_rwsem are released, but it should be harmless.
13815+ */
4a4d8108 13816+
b912730e 13817+/* Callers should call au_read_post() or fput() in the end */
521ced18 13818+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc)
4a4d8108 13819+{
4a4d8108 13820+ struct file *h_file;
b912730e 13821+ int err;
1facf9fc 13822+
521ced18 13823+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, lsc);
b912730e
AM
13824+ if (!err) {
13825+ di_read_unlock(file->f_path.dentry, AuLock_IR);
13826+ h_file = au_hf_top(file);
13827+ get_file(h_file);
13828+ if (!keep_fi)
13829+ fi_read_unlock(file);
13830+ } else
13831+ h_file = ERR_PTR(err);
13832+
13833+ return h_file;
13834+}
13835+
13836+static void au_read_post(struct inode *inode, struct file *h_file)
13837+{
13838+ /* update without lock, I don't think it a problem */
13839+ fsstack_copy_attr_atime(inode, file_inode(h_file));
13840+ fput(h_file);
13841+}
13842+
13843+struct au_write_pre {
521ced18
JR
13844+ /* input */
13845+ unsigned int lsc;
13846+
13847+ /* output */
b912730e 13848+ blkcnt_t blks;
5afbbe0d 13849+ aufs_bindex_t btop;
b912730e
AM
13850+};
13851+
13852+/*
13853+ * return with iinfo is write-locked
13854+ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the
13855+ * end
13856+ */
13857+static struct file *au_write_pre(struct file *file, int do_ready,
13858+ struct au_write_pre *wpre)
13859+{
13860+ struct file *h_file;
13861+ struct dentry *dentry;
13862+ int err;
521ced18 13863+ unsigned int lsc;
b912730e
AM
13864+ struct au_pin pin;
13865+
521ced18
JR
13866+ lsc = 0;
13867+ if (wpre)
13868+ lsc = wpre->lsc;
13869+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, lsc);
b912730e 13870+ h_file = ERR_PTR(err);
dece6358
AM
13871+ if (unlikely(err))
13872+ goto out;
1facf9fc 13873+
b912730e
AM
13874+ dentry = file->f_path.dentry;
13875+ if (do_ready) {
13876+ err = au_ready_to_write(file, -1, &pin);
13877+ if (unlikely(err)) {
13878+ h_file = ERR_PTR(err);
13879+ di_write_unlock(dentry);
13880+ goto out_fi;
13881+ }
13882+ }
13883+
13884+ di_downgrade_lock(dentry, /*flags*/0);
13885+ if (wpre)
5afbbe0d 13886+ wpre->btop = au_fbtop(file);
4a4d8108 13887+ h_file = au_hf_top(file);
9dbd164d 13888+ get_file(h_file);
b912730e
AM
13889+ if (wpre)
13890+ wpre->blks = file_inode(h_file)->i_blocks;
13891+ if (do_ready)
13892+ au_unpin(&pin);
13893+ di_read_unlock(dentry, /*flags*/0);
13894+
13895+out_fi:
13896+ fi_write_unlock(file);
13897+out:
13898+ return h_file;
13899+}
13900+
13901+static void au_write_post(struct inode *inode, struct file *h_file,
13902+ struct au_write_pre *wpre, ssize_t written)
13903+{
13904+ struct inode *h_inode;
13905+
13906+ au_cpup_attr_timesizes(inode);
5afbbe0d 13907+ AuDebugOn(au_ibtop(inode) != wpre->btop);
b912730e
AM
13908+ h_inode = file_inode(h_file);
13909+ inode->i_mode = h_inode->i_mode;
13910+ ii_write_unlock(inode);
b912730e
AM
13911+ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */
13912+ if (written > 0)
5afbbe0d 13913+ au_fhsm_wrote(inode->i_sb, wpre->btop,
b912730e 13914+ /*force*/h_inode->i_blocks > wpre->blks);
1c60b727 13915+ fput(h_file);
b912730e
AM
13916+}
13917+
13918+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
13919+ loff_t *ppos)
13920+{
13921+ ssize_t err;
13922+ struct inode *inode;
13923+ struct file *h_file;
13924+ struct super_block *sb;
13925+
13926+ inode = file_inode(file);
13927+ sb = inode->i_sb;
13928+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
13929+
521ced18 13930+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
13931+ err = PTR_ERR(h_file);
13932+ if (IS_ERR(h_file))
13933+ goto out;
9dbd164d
AM
13934+
13935+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
13936+ err = vfsub_read_u(h_file, buf, count, ppos);
13937+ /* todo: necessary? */
13938+ /* file->f_ra = h_file->f_ra; */
b912730e 13939+ au_read_post(inode, h_file);
1308ab2a 13940+
4f0767ce 13941+out:
dece6358
AM
13942+ si_read_unlock(sb);
13943+ return err;
13944+}
1facf9fc 13945+
e49829fe
JR
13946+/*
13947+ * todo: very ugly
13948+ * it locks both of i_mutex and si_rwsem for read in safe.
13949+ * if the plink maintenance mode continues forever (that is the problem),
13950+ * may loop forever.
13951+ */
13952+static void au_mtx_and_read_lock(struct inode *inode)
13953+{
13954+ int err;
13955+ struct super_block *sb = inode->i_sb;
13956+
13957+ while (1) {
febd17d6 13958+ inode_lock(inode);
e49829fe
JR
13959+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
13960+ if (!err)
13961+ break;
febd17d6 13962+ inode_unlock(inode);
e49829fe
JR
13963+ si_read_lock(sb, AuLock_NOPLMW);
13964+ si_read_unlock(sb);
13965+ }
13966+}
13967+
4a4d8108
AM
13968+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
13969+ size_t count, loff_t *ppos)
dece6358 13970+{
4a4d8108 13971+ ssize_t err;
b912730e
AM
13972+ struct au_write_pre wpre;
13973+ struct inode *inode;
4a4d8108
AM
13974+ struct file *h_file;
13975+ char __user *buf = (char __user *)ubuf;
1facf9fc 13976+
b912730e 13977+ inode = file_inode(file);
e49829fe 13978+ au_mtx_and_read_lock(inode);
1facf9fc 13979+
521ced18 13980+ wpre.lsc = 0;
b912730e
AM
13981+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
13982+ err = PTR_ERR(h_file);
13983+ if (IS_ERR(h_file))
9dbd164d 13984+ goto out;
9dbd164d 13985+
4a4d8108 13986+ err = vfsub_write_u(h_file, buf, count, ppos);
b912730e 13987+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 13988+
4f0767ce 13989+out:
b912730e 13990+ si_read_unlock(inode->i_sb);
febd17d6 13991+ inode_unlock(inode);
dece6358
AM
13992+ return err;
13993+}
1facf9fc 13994+
076b876e
AM
13995+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
13996+ struct iov_iter *iov_iter)
dece6358 13997+{
4a4d8108
AM
13998+ ssize_t err;
13999+ struct file *file;
076b876e 14000+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
1facf9fc 14001+
4a4d8108
AM
14002+ err = security_file_permission(h_file, rw);
14003+ if (unlikely(err))
14004+ goto out;
1facf9fc 14005+
4a4d8108 14006+ err = -ENOSYS;
076b876e 14007+ iter = NULL;
5527c038 14008+ if (rw == MAY_READ)
076b876e 14009+ iter = h_file->f_op->read_iter;
5527c038 14010+ else if (rw == MAY_WRITE)
076b876e 14011+ iter = h_file->f_op->write_iter;
076b876e
AM
14012+
14013+ file = kio->ki_filp;
14014+ kio->ki_filp = h_file;
14015+ if (iter) {
2cbb1c4b 14016+ lockdep_off();
076b876e
AM
14017+ err = iter(kio, iov_iter);
14018+ lockdep_on();
4a4d8108
AM
14019+ } else
14020+ /* currently there is no such fs */
14021+ WARN_ON_ONCE(1);
076b876e 14022+ kio->ki_filp = file;
1facf9fc 14023+
4f0767ce 14024+out:
dece6358
AM
14025+ return err;
14026+}
1facf9fc 14027+
076b876e 14028+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1facf9fc 14029+{
4a4d8108
AM
14030+ ssize_t err;
14031+ struct file *file, *h_file;
b912730e 14032+ struct inode *inode;
dece6358 14033+ struct super_block *sb;
1facf9fc 14034+
4a4d8108 14035+ file = kio->ki_filp;
b912730e
AM
14036+ inode = file_inode(file);
14037+ sb = inode->i_sb;
e49829fe 14038+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 14039+
521ced18 14040+ h_file = au_read_pre(file, /*keep_fi*/1, /*lsc*/0);
b912730e
AM
14041+ err = PTR_ERR(h_file);
14042+ if (IS_ERR(h_file))
14043+ goto out;
9dbd164d 14044+
5afbbe0d
AM
14045+ if (au_test_loopback_kthread()) {
14046+ au_warn_loopback(h_file->f_path.dentry->d_sb);
14047+ if (file->f_mapping != h_file->f_mapping) {
14048+ file->f_mapping = h_file->f_mapping;
14049+ smp_mb(); /* unnecessary? */
14050+ }
14051+ }
14052+ fi_read_unlock(file);
14053+
076b876e 14054+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
4a4d8108
AM
14055+ /* todo: necessary? */
14056+ /* file->f_ra = h_file->f_ra; */
b912730e 14057+ au_read_post(inode, h_file);
1facf9fc 14058+
4f0767ce 14059+out:
4a4d8108 14060+ si_read_unlock(sb);
1308ab2a 14061+ return err;
14062+}
1facf9fc 14063+
076b876e 14064+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1308ab2a 14065+{
4a4d8108 14066+ ssize_t err;
b912730e
AM
14067+ struct au_write_pre wpre;
14068+ struct inode *inode;
4a4d8108 14069+ struct file *file, *h_file;
1308ab2a 14070+
4a4d8108 14071+ file = kio->ki_filp;
b912730e 14072+ inode = file_inode(file);
e49829fe
JR
14073+ au_mtx_and_read_lock(inode);
14074+
521ced18 14075+ wpre.lsc = 0;
b912730e
AM
14076+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
14077+ err = PTR_ERR(h_file);
14078+ if (IS_ERR(h_file))
9dbd164d 14079+ goto out;
9dbd164d 14080+
076b876e 14081+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
b912730e 14082+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 14083+
4f0767ce 14084+out:
b912730e 14085+ si_read_unlock(inode->i_sb);
febd17d6 14086+ inode_unlock(inode);
dece6358 14087+ return err;
1facf9fc 14088+}
14089+
4a4d8108
AM
14090+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
14091+ struct pipe_inode_info *pipe, size_t len,
14092+ unsigned int flags)
1facf9fc 14093+{
4a4d8108
AM
14094+ ssize_t err;
14095+ struct file *h_file;
b912730e 14096+ struct inode *inode;
dece6358 14097+ struct super_block *sb;
1facf9fc 14098+
b912730e
AM
14099+ inode = file_inode(file);
14100+ sb = inode->i_sb;
e49829fe 14101+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 14102+
521ced18 14103+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
14104+ err = PTR_ERR(h_file);
14105+ if (IS_ERR(h_file))
dece6358 14106+ goto out;
1facf9fc 14107+
4a4d8108
AM
14108+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
14109+ /* todo: necessasry? */
14110+ /* file->f_ra = h_file->f_ra; */
b912730e 14111+ au_read_post(inode, h_file);
1facf9fc 14112+
4f0767ce 14113+out:
4a4d8108 14114+ si_read_unlock(sb);
dece6358 14115+ return err;
1facf9fc 14116+}
14117+
4a4d8108
AM
14118+static ssize_t
14119+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
14120+ size_t len, unsigned int flags)
1facf9fc 14121+{
4a4d8108 14122+ ssize_t err;
b912730e
AM
14123+ struct au_write_pre wpre;
14124+ struct inode *inode;
076b876e 14125+ struct file *h_file;
1facf9fc 14126+
b912730e 14127+ inode = file_inode(file);
e49829fe 14128+ au_mtx_and_read_lock(inode);
9dbd164d 14129+
521ced18 14130+ wpre.lsc = 0;
b912730e
AM
14131+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
14132+ err = PTR_ERR(h_file);
14133+ if (IS_ERR(h_file))
9dbd164d 14134+ goto out;
9dbd164d 14135+
4a4d8108 14136+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
b912730e 14137+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 14138+
4f0767ce 14139+out:
b912730e 14140+ si_read_unlock(inode->i_sb);
febd17d6 14141+ inode_unlock(inode);
4a4d8108
AM
14142+ return err;
14143+}
1facf9fc 14144+
38d290e6
JR
14145+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
14146+ loff_t len)
14147+{
14148+ long err;
b912730e 14149+ struct au_write_pre wpre;
38d290e6
JR
14150+ struct inode *inode;
14151+ struct file *h_file;
14152+
b912730e 14153+ inode = file_inode(file);
38d290e6
JR
14154+ au_mtx_and_read_lock(inode);
14155+
521ced18 14156+ wpre.lsc = 0;
b912730e
AM
14157+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
14158+ err = PTR_ERR(h_file);
14159+ if (IS_ERR(h_file))
38d290e6 14160+ goto out;
38d290e6
JR
14161+
14162+ lockdep_off();
03673fb0 14163+ err = vfs_fallocate(h_file, mode, offset, len);
38d290e6 14164+ lockdep_on();
b912730e 14165+ au_write_post(inode, h_file, &wpre, /*written*/1);
38d290e6
JR
14166+
14167+out:
b912730e 14168+ si_read_unlock(inode->i_sb);
febd17d6 14169+ inode_unlock(inode);
38d290e6
JR
14170+ return err;
14171+}
14172+
521ced18
JR
14173+static ssize_t aufs_copy_file_range(struct file *src, loff_t src_pos,
14174+ struct file *dst, loff_t dst_pos,
14175+ size_t len, unsigned int flags)
14176+{
14177+ ssize_t err;
14178+ struct au_write_pre wpre;
14179+ enum { SRC, DST };
14180+ struct {
14181+ struct inode *inode;
14182+ struct file *h_file;
14183+ struct super_block *h_sb;
14184+ } a[2];
14185+#define a_src a[SRC]
14186+#define a_dst a[DST]
14187+
14188+ err = -EINVAL;
14189+ a_src.inode = file_inode(src);
14190+ if (unlikely(!S_ISREG(a_src.inode->i_mode)))
14191+ goto out;
14192+ a_dst.inode = file_inode(dst);
14193+ if (unlikely(!S_ISREG(a_dst.inode->i_mode)))
14194+ goto out;
14195+
14196+ au_mtx_and_read_lock(a_dst.inode);
14197+ /*
14198+ * in order to match the order in di_write_lock2_{child,parent}(),
14199+ * use f_path.dentry for this comparision.
14200+ */
14201+ if (src->f_path.dentry < dst->f_path.dentry) {
14202+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_1);
14203+ err = PTR_ERR(a_src.h_file);
14204+ if (IS_ERR(a_src.h_file))
14205+ goto out_si;
14206+
14207+ wpre.lsc = AuLsc_FI_2;
14208+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre);
14209+ err = PTR_ERR(a_dst.h_file);
14210+ if (IS_ERR(a_dst.h_file)) {
14211+ au_read_post(a_src.inode, a_src.h_file);
14212+ goto out_si;
14213+ }
14214+ } else {
14215+ wpre.lsc = AuLsc_FI_1;
14216+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre);
14217+ err = PTR_ERR(a_dst.h_file);
14218+ if (IS_ERR(a_dst.h_file))
14219+ goto out_si;
14220+
14221+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_2);
14222+ err = PTR_ERR(a_src.h_file);
14223+ if (IS_ERR(a_src.h_file)) {
14224+ au_write_post(a_dst.inode, a_dst.h_file, &wpre,
14225+ /*written*/0);
14226+ goto out_si;
14227+ }
14228+ }
14229+
14230+ err = -EXDEV;
14231+ a_src.h_sb = file_inode(a_src.h_file)->i_sb;
14232+ a_dst.h_sb = file_inode(a_dst.h_file)->i_sb;
14233+ if (unlikely(a_src.h_sb != a_dst.h_sb)) {
14234+ AuDbgFile(src);
14235+ AuDbgFile(dst);
14236+ goto out_file;
14237+ }
14238+
14239+ err = vfsub_copy_file_range(a_src.h_file, src_pos, a_dst.h_file,
14240+ dst_pos, len, flags);
14241+
14242+out_file:
14243+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, err);
14244+ fi_read_unlock(src);
14245+ au_read_post(a_src.inode, a_src.h_file);
14246+out_si:
14247+ si_read_unlock(a_dst.inode->i_sb);
14248+ inode_unlock(a_dst.inode);
14249+out:
14250+ return err;
14251+#undef a_src
14252+#undef a_dst
14253+}
14254+
4a4d8108
AM
14255+/* ---------------------------------------------------------------------- */
14256+
9dbd164d
AM
14257+/*
14258+ * The locking order around current->mmap_sem.
14259+ * - in most and regular cases
14260+ * file I/O syscall -- aufs_read() or something
14261+ * -- si_rwsem for read -- mmap_sem
14262+ * (Note that [fdi]i_rwsem are released before mmap_sem).
14263+ * - in mmap case
14264+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
14265+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
14266+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
14267+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
14268+ * It means that when aufs acquires si_rwsem for write, the process should never
14269+ * acquire mmap_sem.
14270+ *
392086de 14271+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
14272+ * problem either since any directory is not able to be mmap-ed.
14273+ * The similar scenario is applied to aufs_readlink() too.
14274+ */
14275+
38d290e6 14276+#if 0 /* stop calling security_file_mmap() */
2dfbb274
AM
14277+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
14278+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
14279+
14280+static unsigned long au_arch_prot_conv(unsigned long flags)
14281+{
14282+ /* currently ppc64 only */
14283+#ifdef CONFIG_PPC64
14284+ /* cf. linux/arch/powerpc/include/asm/mman.h */
14285+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
14286+ return AuConv_VM_PROT(flags, SAO);
14287+#else
14288+ AuDebugOn(arch_calc_vm_prot_bits(-1));
14289+ return 0;
14290+#endif
14291+}
14292+
14293+static unsigned long au_prot_conv(unsigned long flags)
14294+{
14295+ return AuConv_VM_PROT(flags, READ)
14296+ | AuConv_VM_PROT(flags, WRITE)
14297+ | AuConv_VM_PROT(flags, EXEC)
14298+ | au_arch_prot_conv(flags);
14299+}
14300+
14301+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
14302+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
14303+
14304+static unsigned long au_flag_conv(unsigned long flags)
14305+{
14306+ return AuConv_VM_MAP(flags, GROWSDOWN)
14307+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
14308+ | AuConv_VM_MAP(flags, LOCKED);
14309+}
38d290e6 14310+#endif
2dfbb274 14311+
9dbd164d 14312+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 14313+{
4a4d8108 14314+ int err;
4a4d8108 14315+ const unsigned char wlock
9dbd164d 14316+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108 14317+ struct super_block *sb;
9dbd164d 14318+ struct file *h_file;
b912730e 14319+ struct inode *inode;
9dbd164d
AM
14320+
14321+ AuDbgVmRegion(file, vma);
1308ab2a 14322+
b912730e
AM
14323+ inode = file_inode(file);
14324+ sb = inode->i_sb;
9dbd164d 14325+ lockdep_off();
e49829fe 14326+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108 14327+
b912730e 14328+ h_file = au_write_pre(file, wlock, /*wpre*/NULL);
9dbd164d 14329+ lockdep_on();
b912730e
AM
14330+ err = PTR_ERR(h_file);
14331+ if (IS_ERR(h_file))
14332+ goto out;
1308ab2a 14333+
b912730e
AM
14334+ err = 0;
14335+ au_set_mmapped(file);
9dbd164d 14336+ au_vm_file_reset(vma, h_file);
38d290e6
JR
14337+ /*
14338+ * we cannot call security_mmap_file() here since it may acquire
14339+ * mmap_sem or i_mutex.
14340+ *
14341+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
14342+ * au_flag_conv(vma->vm_flags));
14343+ */
9dbd164d 14344+ if (!err)
521ced18 14345+ err = call_mmap(h_file, vma);
b912730e
AM
14346+ if (!err) {
14347+ au_vm_prfile_set(vma, file);
14348+ fsstack_copy_attr_atime(inode, file_inode(h_file));
14349+ goto out_fput; /* success */
14350+ }
2cbb1c4b
JR
14351+ au_unset_mmapped(file);
14352+ au_vm_file_reset(vma, file);
b912730e 14353+
2cbb1c4b 14354+out_fput:
9dbd164d 14355+ lockdep_off();
b912730e
AM
14356+ ii_write_unlock(inode);
14357+ lockdep_on();
14358+ fput(h_file);
4f0767ce 14359+out:
b912730e 14360+ lockdep_off();
9dbd164d
AM
14361+ si_read_unlock(sb);
14362+ lockdep_on();
14363+ AuTraceErr(err);
4a4d8108
AM
14364+ return err;
14365+}
14366+
14367+/* ---------------------------------------------------------------------- */
14368+
1e00d052
AM
14369+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
14370+ int datasync)
4a4d8108
AM
14371+{
14372+ int err;
b912730e 14373+ struct au_write_pre wpre;
4a4d8108
AM
14374+ struct inode *inode;
14375+ struct file *h_file;
4a4d8108
AM
14376+
14377+ err = 0; /* -EBADF; */ /* posix? */
14378+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
b912730e 14379+ goto out;
4a4d8108 14380+
b912730e
AM
14381+ inode = file_inode(file);
14382+ au_mtx_and_read_lock(inode);
14383+
521ced18 14384+ wpre.lsc = 0;
b912730e
AM
14385+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
14386+ err = PTR_ERR(h_file);
14387+ if (IS_ERR(h_file))
4a4d8108 14388+ goto out_unlock;
4a4d8108 14389+
53392da6 14390+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
b912730e 14391+ au_write_post(inode, h_file, &wpre, /*written*/0);
4a4d8108 14392+
4f0767ce 14393+out_unlock:
b912730e 14394+ si_read_unlock(inode->i_sb);
febd17d6 14395+ inode_unlock(inode);
b912730e 14396+out:
4a4d8108 14397+ return err;
dece6358
AM
14398+}
14399+
4a4d8108 14400+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 14401+{
4a4d8108
AM
14402+ int err;
14403+ struct file *h_file;
4a4d8108 14404+ struct super_block *sb;
1308ab2a 14405+
b912730e 14406+ sb = file->f_path.dentry->d_sb;
e49829fe 14407+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 14408+
521ced18 14409+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
14410+ err = PTR_ERR(h_file);
14411+ if (IS_ERR(h_file))
4a4d8108
AM
14412+ goto out;
14413+
523b37e3 14414+ if (h_file->f_op->fasync)
4a4d8108 14415+ err = h_file->f_op->fasync(fd, h_file, flag);
b912730e 14416+ fput(h_file); /* instead of au_read_post() */
1308ab2a 14417+
4f0767ce 14418+out:
4a4d8108 14419+ si_read_unlock(sb);
1308ab2a 14420+ return err;
dece6358 14421+}
4a4d8108 14422+
febd17d6
JR
14423+static int aufs_setfl(struct file *file, unsigned long arg)
14424+{
14425+ int err;
14426+ struct file *h_file;
14427+ struct super_block *sb;
14428+
14429+ sb = file->f_path.dentry->d_sb;
14430+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
14431+
521ced18 14432+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
febd17d6
JR
14433+ err = PTR_ERR(h_file);
14434+ if (IS_ERR(h_file))
14435+ goto out;
14436+
1c60b727
AM
14437+ /* stop calling h_file->fasync */
14438+ arg |= vfsub_file_flags(file) & FASYNC;
febd17d6
JR
14439+ err = setfl(/*unused fd*/-1, h_file, arg);
14440+ fput(h_file); /* instead of au_read_post() */
14441+
14442+out:
14443+ si_read_unlock(sb);
14444+ return err;
14445+}
14446+
4a4d8108
AM
14447+/* ---------------------------------------------------------------------- */
14448+
14449+/* no one supports this operation, currently */
14450+#if 0
14451+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
2000de60 14452+ size_t len, loff_t *pos, int more)
4a4d8108
AM
14453+{
14454+}
14455+#endif
14456+
14457+/* ---------------------------------------------------------------------- */
14458+
14459+const struct file_operations aufs_file_fop = {
14460+ .owner = THIS_MODULE,
2cbb1c4b 14461+
027c5e7a 14462+ .llseek = default_llseek,
4a4d8108
AM
14463+
14464+ .read = aufs_read,
14465+ .write = aufs_write,
076b876e
AM
14466+ .read_iter = aufs_read_iter,
14467+ .write_iter = aufs_write_iter,
14468+
4a4d8108
AM
14469+#ifdef CONFIG_AUFS_POLL
14470+ .poll = aufs_poll,
14471+#endif
14472+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 14473+#ifdef CONFIG_COMPAT
c2b27bf2 14474+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 14475+#endif
4a4d8108
AM
14476+ .mmap = aufs_mmap,
14477+ .open = aufs_open_nondir,
14478+ .flush = aufs_flush_nondir,
14479+ .release = aufs_release_nondir,
14480+ .fsync = aufs_fsync_nondir,
4a4d8108
AM
14481+ .fasync = aufs_fasync,
14482+ /* .sendpage = aufs_sendpage, */
febd17d6 14483+ .setfl = aufs_setfl,
4a4d8108
AM
14484+ .splice_write = aufs_splice_write,
14485+ .splice_read = aufs_splice_read,
14486+#if 0
14487+ .aio_splice_write = aufs_aio_splice_write,
38d290e6 14488+ .aio_splice_read = aufs_aio_splice_read,
4a4d8108 14489+#endif
521ced18
JR
14490+ .fallocate = aufs_fallocate,
14491+ .copy_file_range = aufs_copy_file_range
4a4d8108 14492+};
7f207e10
AM
14493diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
14494--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 14495+++ linux/fs/aufs/fstype.h 2017-07-29 12:14:25.903042072 +0200
b912730e 14496@@ -0,0 +1,400 @@
4a4d8108 14497+/*
a2654f78 14498+ * Copyright (C) 2005-2017 Junjiro R. Okajima
4a4d8108
AM
14499+ *
14500+ * This program, aufs is free software; you can redistribute it and/or modify
14501+ * it under the terms of the GNU General Public License as published by
14502+ * the Free Software Foundation; either version 2 of the License, or
14503+ * (at your option) any later version.
14504+ *
14505+ * This program is distributed in the hope that it will be useful,
14506+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14507+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14508+ * GNU General Public License for more details.
14509+ *
14510+ * You should have received a copy of the GNU General Public License
523b37e3 14511+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
14512+ */
14513+
14514+/*
14515+ * judging filesystem type
14516+ */
14517+
14518+#ifndef __AUFS_FSTYPE_H__
14519+#define __AUFS_FSTYPE_H__
14520+
14521+#ifdef __KERNEL__
14522+
14523+#include <linux/fs.h>
14524+#include <linux/magic.h>
b912730e 14525+#include <linux/nfs_fs.h>
b95c5147 14526+#include <linux/romfs_fs.h>
4a4d8108
AM
14527+
14528+static inline int au_test_aufs(struct super_block *sb)
14529+{
14530+ return sb->s_magic == AUFS_SUPER_MAGIC;
14531+}
14532+
14533+static inline const char *au_sbtype(struct super_block *sb)
14534+{
14535+ return sb->s_type->name;
14536+}
1308ab2a 14537+
14538+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
14539+{
f0c0a007 14540+#if IS_ENABLED(CONFIG_ISO9660_FS)
2000de60 14541+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
14542+#else
14543+ return 0;
14544+#endif
14545+}
14546+
1308ab2a 14547+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 14548+{
f0c0a007 14549+#if IS_ENABLED(CONFIG_ROMFS_FS)
2000de60 14550+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
14551+#else
14552+ return 0;
14553+#endif
14554+}
14555+
1308ab2a 14556+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 14557+{
f0c0a007 14558+#if IS_ENABLED(CONFIG_CRAMFS)
1308ab2a 14559+ return sb->s_magic == CRAMFS_MAGIC;
14560+#endif
14561+ return 0;
14562+}
14563+
14564+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
14565+{
f0c0a007 14566+#if IS_ENABLED(CONFIG_NFS_FS)
1308ab2a 14567+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
14568+#else
14569+ return 0;
14570+#endif
14571+}
14572+
1308ab2a 14573+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 14574+{
f0c0a007 14575+#if IS_ENABLED(CONFIG_FUSE_FS)
1308ab2a 14576+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
14577+#else
14578+ return 0;
14579+#endif
14580+}
14581+
1308ab2a 14582+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 14583+{
f0c0a007 14584+#if IS_ENABLED(CONFIG_XFS_FS)
1308ab2a 14585+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
14586+#else
14587+ return 0;
14588+#endif
14589+}
14590+
1308ab2a 14591+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 14592+{
1308ab2a 14593+#ifdef CONFIG_TMPFS
14594+ return sb->s_magic == TMPFS_MAGIC;
14595+#else
14596+ return 0;
dece6358 14597+#endif
dece6358
AM
14598+}
14599+
1308ab2a 14600+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 14601+{
f0c0a007 14602+#if IS_ENABLED(CONFIG_ECRYPT_FS)
1308ab2a 14603+ return !strcmp(au_sbtype(sb), "ecryptfs");
14604+#else
14605+ return 0;
14606+#endif
1facf9fc 14607+}
14608+
1308ab2a 14609+static inline int au_test_ramfs(struct super_block *sb)
14610+{
14611+ return sb->s_magic == RAMFS_MAGIC;
14612+}
14613+
14614+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
14615+{
f0c0a007 14616+#if IS_ENABLED(CONFIG_UBIFS_FS)
1308ab2a 14617+ return sb->s_magic == UBIFS_SUPER_MAGIC;
14618+#else
14619+ return 0;
14620+#endif
14621+}
14622+
14623+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
14624+{
14625+#ifdef CONFIG_PROC_FS
14626+ return sb->s_magic == PROC_SUPER_MAGIC;
14627+#else
14628+ return 0;
14629+#endif
14630+}
14631+
14632+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
14633+{
14634+#ifdef CONFIG_SYSFS
14635+ return sb->s_magic == SYSFS_MAGIC;
14636+#else
14637+ return 0;
14638+#endif
14639+}
14640+
14641+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
14642+{
f0c0a007 14643+#if IS_ENABLED(CONFIG_CONFIGFS_FS)
1308ab2a 14644+ return sb->s_magic == CONFIGFS_MAGIC;
14645+#else
14646+ return 0;
14647+#endif
14648+}
14649+
14650+static inline int au_test_minix(struct super_block *sb __maybe_unused)
14651+{
f0c0a007 14652+#if IS_ENABLED(CONFIG_MINIX_FS)
1308ab2a 14653+ return sb->s_magic == MINIX3_SUPER_MAGIC
14654+ || sb->s_magic == MINIX2_SUPER_MAGIC
14655+ || sb->s_magic == MINIX2_SUPER_MAGIC2
14656+ || sb->s_magic == MINIX_SUPER_MAGIC
14657+ || sb->s_magic == MINIX_SUPER_MAGIC2;
14658+#else
14659+ return 0;
14660+#endif
14661+}
14662+
1308ab2a 14663+static inline int au_test_fat(struct super_block *sb __maybe_unused)
14664+{
f0c0a007 14665+#if IS_ENABLED(CONFIG_FAT_FS)
1308ab2a 14666+ return sb->s_magic == MSDOS_SUPER_MAGIC;
14667+#else
14668+ return 0;
14669+#endif
14670+}
14671+
14672+static inline int au_test_msdos(struct super_block *sb)
14673+{
14674+ return au_test_fat(sb);
14675+}
14676+
14677+static inline int au_test_vfat(struct super_block *sb)
14678+{
14679+ return au_test_fat(sb);
14680+}
14681+
14682+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
14683+{
14684+#ifdef CONFIG_SECURITYFS
14685+ return sb->s_magic == SECURITYFS_MAGIC;
14686+#else
14687+ return 0;
14688+#endif
14689+}
14690+
14691+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
14692+{
f0c0a007 14693+#if IS_ENABLED(CONFIG_SQUASHFS)
1308ab2a 14694+ return sb->s_magic == SQUASHFS_MAGIC;
14695+#else
14696+ return 0;
14697+#endif
14698+}
14699+
14700+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
14701+{
f0c0a007 14702+#if IS_ENABLED(CONFIG_BTRFS_FS)
1308ab2a 14703+ return sb->s_magic == BTRFS_SUPER_MAGIC;
14704+#else
14705+ return 0;
14706+#endif
14707+}
14708+
14709+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
14710+{
f0c0a007 14711+#if IS_ENABLED(CONFIG_XENFS)
1308ab2a 14712+ return sb->s_magic == XENFS_SUPER_MAGIC;
14713+#else
14714+ return 0;
14715+#endif
14716+}
14717+
14718+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
14719+{
14720+#ifdef CONFIG_DEBUG_FS
14721+ return sb->s_magic == DEBUGFS_MAGIC;
14722+#else
14723+ return 0;
14724+#endif
14725+}
14726+
14727+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
14728+{
f0c0a007 14729+#if IS_ENABLED(CONFIG_NILFS)
1308ab2a 14730+ return sb->s_magic == NILFS_SUPER_MAGIC;
14731+#else
14732+ return 0;
14733+#endif
14734+}
14735+
4a4d8108
AM
14736+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
14737+{
f0c0a007 14738+#if IS_ENABLED(CONFIG_HFSPLUS_FS)
4a4d8108
AM
14739+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
14740+#else
14741+ return 0;
14742+#endif
14743+}
14744+
1308ab2a 14745+/* ---------------------------------------------------------------------- */
14746+/*
14747+ * they can't be an aufs branch.
14748+ */
14749+static inline int au_test_fs_unsuppoted(struct super_block *sb)
14750+{
14751+ return
14752+#ifndef CONFIG_AUFS_BR_RAMFS
14753+ au_test_ramfs(sb) ||
14754+#endif
14755+ au_test_procfs(sb)
14756+ || au_test_sysfs(sb)
14757+ || au_test_configfs(sb)
14758+ || au_test_debugfs(sb)
14759+ || au_test_securityfs(sb)
14760+ || au_test_xenfs(sb)
14761+ || au_test_ecryptfs(sb)
14762+ /* || !strcmp(au_sbtype(sb), "unionfs") */
14763+ || au_test_aufs(sb); /* will be supported in next version */
14764+}
14765+
1308ab2a 14766+static inline int au_test_fs_remote(struct super_block *sb)
14767+{
14768+ return !au_test_tmpfs(sb)
14769+#ifdef CONFIG_AUFS_BR_RAMFS
14770+ && !au_test_ramfs(sb)
14771+#endif
14772+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
14773+}
14774+
14775+/* ---------------------------------------------------------------------- */
14776+
14777+/*
14778+ * Note: these functions (below) are created after reading ->getattr() in all
14779+ * filesystems under linux/fs. it means we have to do so in every update...
14780+ */
14781+
14782+/*
14783+ * some filesystems require getattr to refresh the inode attributes before
14784+ * referencing.
14785+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
14786+ * and leave the work for d_revalidate()
14787+ */
14788+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
14789+{
14790+ return au_test_nfs(sb)
14791+ || au_test_fuse(sb)
1308ab2a 14792+ /* || au_test_btrfs(sb) */ /* untested */
1308ab2a 14793+ ;
14794+}
14795+
14796+/*
14797+ * filesystems which don't maintain i_size or i_blocks.
14798+ */
14799+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
14800+{
14801+ return au_test_xfs(sb)
4a4d8108
AM
14802+ || au_test_btrfs(sb)
14803+ || au_test_ubifs(sb)
14804+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 14805+ /* || au_test_minix(sb) */ /* untested */
14806+ ;
14807+}
14808+
14809+/*
14810+ * filesystems which don't store the correct value in some of their inode
14811+ * attributes.
14812+ */
14813+static inline int au_test_fs_bad_iattr(struct super_block *sb)
14814+{
14815+ return au_test_fs_bad_iattr_size(sb)
1308ab2a 14816+ || au_test_fat(sb)
14817+ || au_test_msdos(sb)
14818+ || au_test_vfat(sb);
1facf9fc 14819+}
14820+
14821+/* they don't check i_nlink in link(2) */
14822+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
14823+{
14824+ return au_test_tmpfs(sb)
14825+#ifdef CONFIG_AUFS_BR_RAMFS
14826+ || au_test_ramfs(sb)
14827+#endif
4a4d8108 14828+ || au_test_ubifs(sb)
4a4d8108 14829+ || au_test_hfsplus(sb);
1facf9fc 14830+}
14831+
14832+/*
14833+ * filesystems which sets S_NOATIME and S_NOCMTIME.
14834+ */
14835+static inline int au_test_fs_notime(struct super_block *sb)
14836+{
14837+ return au_test_nfs(sb)
14838+ || au_test_fuse(sb)
dece6358 14839+ || au_test_ubifs(sb)
1facf9fc 14840+ ;
14841+}
14842+
1facf9fc 14843+/* temporary support for i#1 in cramfs */
14844+static inline int au_test_fs_unique_ino(struct inode *inode)
14845+{
14846+ if (au_test_cramfs(inode->i_sb))
14847+ return inode->i_ino != 1;
14848+ return 1;
14849+}
14850+
14851+/* ---------------------------------------------------------------------- */
14852+
14853+/*
14854+ * the filesystem where the xino files placed must support i/o after unlink and
14855+ * maintain i_size and i_blocks.
14856+ */
14857+static inline int au_test_fs_bad_xino(struct super_block *sb)
14858+{
14859+ return au_test_fs_remote(sb)
14860+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 14861+ /* don't want unnecessary work for xino */
14862+ || au_test_aufs(sb)
1308ab2a 14863+ || au_test_ecryptfs(sb)
14864+ || au_test_nilfs(sb);
1facf9fc 14865+}
14866+
14867+static inline int au_test_fs_trunc_xino(struct super_block *sb)
14868+{
14869+ return au_test_tmpfs(sb)
14870+ || au_test_ramfs(sb);
14871+}
14872+
14873+/*
14874+ * test if the @sb is real-readonly.
14875+ */
14876+static inline int au_test_fs_rr(struct super_block *sb)
14877+{
14878+ return au_test_squashfs(sb)
14879+ || au_test_iso9660(sb)
14880+ || au_test_cramfs(sb)
14881+ || au_test_romfs(sb);
14882+}
14883+
b912730e
AM
14884+/*
14885+ * test if the @inode is nfs with 'noacl' option
14886+ * NFS always sets MS_POSIXACL regardless its mount option 'noacl.'
14887+ */
14888+static inline int au_test_nfs_noacl(struct inode *inode)
14889+{
14890+ return au_test_nfs(inode->i_sb)
14891+ /* && IS_POSIXACL(inode) */
14892+ && !nfs_server_capable(inode, NFS_CAP_ACLS);
14893+}
14894+
1facf9fc 14895+#endif /* __KERNEL__ */
14896+#endif /* __AUFS_FSTYPE_H__ */
7f207e10
AM
14897diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
14898--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
ffa93bbd
AM
14899+++ linux/fs/aufs/hfsnotify.c 2017-07-31 10:27:18.853311720 +0200
14900@@ -0,0 +1,289 @@
1facf9fc 14901+/*
a2654f78 14902+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 14903+ *
14904+ * This program, aufs is free software; you can redistribute it and/or modify
14905+ * it under the terms of the GNU General Public License as published by
14906+ * the Free Software Foundation; either version 2 of the License, or
14907+ * (at your option) any later version.
dece6358
AM
14908+ *
14909+ * This program is distributed in the hope that it will be useful,
14910+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14911+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14912+ * GNU General Public License for more details.
14913+ *
14914+ * You should have received a copy of the GNU General Public License
523b37e3 14915+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 14916+ */
14917+
14918+/*
4a4d8108 14919+ * fsnotify for the lower directories
1facf9fc 14920+ */
14921+
14922+#include "aufs.h"
14923+
4a4d8108
AM
14924+/* FS_IN_IGNORED is unnecessary */
14925+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
14926+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 14927+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 14928+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 14929+
0c5527e5 14930+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 14931+{
0c5527e5
AM
14932+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
14933+ hn_mark);
5afbbe0d 14934+ /* AuDbg("here\n"); */
1c60b727 14935+ au_cache_free_hnotify(hn);
076b876e 14936+ smp_mb__before_atomic();
1716fcea
AM
14937+ if (atomic64_dec_and_test(&au_hfsn_ifree))
14938+ wake_up(&au_hfsn_wq);
4a4d8108 14939+}
1facf9fc 14940+
027c5e7a 14941+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 14942+{
1716fcea 14943+ int err;
027c5e7a
AM
14944+ struct au_hnotify *hn;
14945+ struct super_block *sb;
14946+ struct au_branch *br;
0c5527e5 14947+ struct fsnotify_mark *mark;
027c5e7a 14948+ aufs_bindex_t bindex;
1facf9fc 14949+
027c5e7a
AM
14950+ hn = hinode->hi_notify;
14951+ sb = hn->hn_aufs_inode->i_sb;
14952+ bindex = au_br_index(sb, hinode->hi_id);
14953+ br = au_sbr(sb, bindex);
1716fcea
AM
14954+ AuDebugOn(!br->br_hfsn);
14955+
0c5527e5 14956+ mark = &hn->hn_mark;
ffa93bbd 14957+ fsnotify_init_mark(mark, br->br_hfsn->hfsn_group);
0c5527e5 14958+ mark->mask = AuHfsnMask;
7f207e10
AM
14959+ /*
14960+ * by udba rename or rmdir, aufs assign a new inode to the known
14961+ * h_inode, so specify 1 to allow dups.
14962+ */
c1595e42 14963+ lockdep_off();
ffa93bbd
AM
14964+ err = fsnotify_add_mark(mark, hinode->hi_inode, /*mnt*/NULL,
14965+ /*allow_dups*/1);
c1595e42 14966+ lockdep_on();
1716fcea
AM
14967+
14968+ return err;
1facf9fc 14969+}
14970+
7eafdf33 14971+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 14972+{
0c5527e5 14973+ struct fsnotify_mark *mark;
7eafdf33 14974+ unsigned long long ull;
1716fcea 14975+ struct fsnotify_group *group;
7eafdf33
AM
14976+
14977+ ull = atomic64_inc_return(&au_hfsn_ifree);
14978+ BUG_ON(!ull);
953406b4 14979+
0c5527e5 14980+ mark = &hn->hn_mark;
1716fcea
AM
14981+ spin_lock(&mark->lock);
14982+ group = mark->group;
14983+ fsnotify_get_group(group);
14984+ spin_unlock(&mark->lock);
c1595e42 14985+ lockdep_off();
1716fcea 14986+ fsnotify_destroy_mark(mark, group);
5afbbe0d 14987+ fsnotify_put_mark(mark);
1716fcea 14988+ fsnotify_put_group(group);
c1595e42 14989+ lockdep_on();
7f207e10 14990+
7eafdf33
AM
14991+ /* free hn by myself */
14992+ return 0;
1facf9fc 14993+}
14994+
14995+/* ---------------------------------------------------------------------- */
14996+
4a4d8108 14997+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 14998+{
0c5527e5 14999+ struct fsnotify_mark *mark;
1facf9fc 15000+
0c5527e5
AM
15001+ mark = &hinode->hi_notify->hn_mark;
15002+ spin_lock(&mark->lock);
1facf9fc 15003+ if (do_set) {
0c5527e5
AM
15004+ AuDebugOn(mark->mask & AuHfsnMask);
15005+ mark->mask |= AuHfsnMask;
1facf9fc 15006+ } else {
0c5527e5
AM
15007+ AuDebugOn(!(mark->mask & AuHfsnMask));
15008+ mark->mask &= ~AuHfsnMask;
1facf9fc 15009+ }
0c5527e5 15010+ spin_unlock(&mark->lock);
4a4d8108 15011+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 15012+}
15013+
4a4d8108 15014+/* ---------------------------------------------------------------------- */
1facf9fc 15015+
4a4d8108
AM
15016+/* #define AuDbgHnotify */
15017+#ifdef AuDbgHnotify
15018+static char *au_hfsn_name(u32 mask)
15019+{
15020+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
15021+#define test_ret(flag) \
15022+ do { \
15023+ if (mask & flag) \
15024+ return #flag; \
15025+ } while (0)
4a4d8108
AM
15026+ test_ret(FS_ACCESS);
15027+ test_ret(FS_MODIFY);
15028+ test_ret(FS_ATTRIB);
15029+ test_ret(FS_CLOSE_WRITE);
15030+ test_ret(FS_CLOSE_NOWRITE);
15031+ test_ret(FS_OPEN);
15032+ test_ret(FS_MOVED_FROM);
15033+ test_ret(FS_MOVED_TO);
15034+ test_ret(FS_CREATE);
15035+ test_ret(FS_DELETE);
15036+ test_ret(FS_DELETE_SELF);
15037+ test_ret(FS_MOVE_SELF);
15038+ test_ret(FS_UNMOUNT);
15039+ test_ret(FS_Q_OVERFLOW);
15040+ test_ret(FS_IN_IGNORED);
b912730e 15041+ test_ret(FS_ISDIR);
4a4d8108
AM
15042+ test_ret(FS_IN_ONESHOT);
15043+ test_ret(FS_EVENT_ON_CHILD);
15044+ return "";
15045+#undef test_ret
15046+#else
15047+ return "??";
15048+#endif
1facf9fc 15049+}
4a4d8108 15050+#endif
1facf9fc 15051+
15052+/* ---------------------------------------------------------------------- */
15053+
1716fcea
AM
15054+static void au_hfsn_free_group(struct fsnotify_group *group)
15055+{
15056+ struct au_br_hfsnotify *hfsn = group->private;
15057+
5afbbe0d 15058+ /* AuDbg("here\n"); */
1c60b727 15059+ kfree(hfsn);
1716fcea
AM
15060+}
15061+
4a4d8108 15062+static int au_hfsn_handle_event(struct fsnotify_group *group,
fb47a38f 15063+ struct inode *inode,
0c5527e5
AM
15064+ struct fsnotify_mark *inode_mark,
15065+ struct fsnotify_mark *vfsmount_mark,
a2654f78 15066+ u32 mask, const void *data, int data_type,
ffa93bbd
AM
15067+ const unsigned char *file_name, u32 cookie,
15068+ struct fsnotify_iter_info *iter_info)
1facf9fc 15069+{
15070+ int err;
4a4d8108
AM
15071+ struct au_hnotify *hnotify;
15072+ struct inode *h_dir, *h_inode;
fb47a38f 15073+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
4a4d8108 15074+
fb47a38f 15075+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 15076+
15077+ err = 0;
0c5527e5 15078+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108 15079+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 15080+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 15081+ goto out;
1facf9fc 15082+
fb47a38f
JR
15083+ h_dir = inode;
15084+ h_inode = NULL;
4a4d8108 15085+#ifdef AuDbgHnotify
392086de 15086+ au_debug_on();
4a4d8108
AM
15087+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
15088+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
15089+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
15090+ h_dir->i_ino, mask, au_hfsn_name(mask),
15091+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
15092+ /* WARN_ON(1); */
1facf9fc 15093+ }
392086de 15094+ au_debug_off();
1facf9fc 15095+#endif
4a4d8108 15096+
0c5527e5
AM
15097+ AuDebugOn(!inode_mark);
15098+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
15099+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 15100+
4a4d8108
AM
15101+out:
15102+ return err;
15103+}
1facf9fc 15104+
4a4d8108 15105+static struct fsnotify_ops au_hfsn_ops = {
1716fcea 15106+ .handle_event = au_hfsn_handle_event,
ffa93bbd
AM
15107+ .free_group_priv = au_hfsn_free_group,
15108+ .free_mark = au_hfsn_free_mark
4a4d8108
AM
15109+};
15110+
15111+/* ---------------------------------------------------------------------- */
15112+
027c5e7a
AM
15113+static void au_hfsn_fin_br(struct au_branch *br)
15114+{
1716fcea 15115+ struct au_br_hfsnotify *hfsn;
027c5e7a 15116+
1716fcea 15117+ hfsn = br->br_hfsn;
c1595e42
JR
15118+ if (hfsn) {
15119+ lockdep_off();
1716fcea 15120+ fsnotify_put_group(hfsn->hfsn_group);
c1595e42
JR
15121+ lockdep_on();
15122+ }
027c5e7a
AM
15123+}
15124+
1716fcea 15125+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
15126+{
15127+ int err;
1716fcea
AM
15128+ struct fsnotify_group *group;
15129+ struct au_br_hfsnotify *hfsn;
1facf9fc 15130+
4a4d8108 15131+ err = 0;
1716fcea
AM
15132+ br->br_hfsn = NULL;
15133+ if (!au_br_hnotifyable(perm))
027c5e7a 15134+ goto out;
027c5e7a 15135+
1716fcea
AM
15136+ err = -ENOMEM;
15137+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
15138+ if (unlikely(!hfsn))
027c5e7a
AM
15139+ goto out;
15140+
1716fcea
AM
15141+ err = 0;
15142+ group = fsnotify_alloc_group(&au_hfsn_ops);
15143+ if (IS_ERR(group)) {
15144+ err = PTR_ERR(group);
0c5527e5 15145+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 15146+ goto out_hfsn;
4a4d8108 15147+ }
1facf9fc 15148+
1716fcea
AM
15149+ group->private = hfsn;
15150+ hfsn->hfsn_group = group;
15151+ br->br_hfsn = hfsn;
15152+ goto out; /* success */
15153+
15154+out_hfsn:
1c60b727 15155+ kfree(hfsn);
027c5e7a 15156+out:
1716fcea
AM
15157+ return err;
15158+}
15159+
15160+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
15161+{
15162+ int err;
15163+
15164+ err = 0;
15165+ if (!br->br_hfsn)
15166+ err = au_hfsn_init_br(br, perm);
15167+
1facf9fc 15168+ return err;
15169+}
15170+
7eafdf33
AM
15171+/* ---------------------------------------------------------------------- */
15172+
15173+static void au_hfsn_fin(void)
15174+{
15175+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
15176+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
15177+}
15178+
4a4d8108
AM
15179+const struct au_hnotify_op au_hnotify_op = {
15180+ .ctl = au_hfsn_ctl,
15181+ .alloc = au_hfsn_alloc,
15182+ .free = au_hfsn_free,
1facf9fc 15183+
7eafdf33
AM
15184+ .fin = au_hfsn_fin,
15185+
027c5e7a
AM
15186+ .reset_br = au_hfsn_reset_br,
15187+ .fin_br = au_hfsn_fin_br,
15188+ .init_br = au_hfsn_init_br
4a4d8108 15189+};
7f207e10
AM
15190diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
15191--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 15192+++ linux/fs/aufs/hfsplus.c 2017-07-29 12:14:25.903042072 +0200
523b37e3 15193@@ -0,0 +1,56 @@
4a4d8108 15194+/*
a2654f78 15195+ * Copyright (C) 2010-2017 Junjiro R. Okajima
4a4d8108
AM
15196+ *
15197+ * This program, aufs is free software; you can redistribute it and/or modify
15198+ * it under the terms of the GNU General Public License as published by
15199+ * the Free Software Foundation; either version 2 of the License, or
15200+ * (at your option) any later version.
15201+ *
15202+ * This program is distributed in the hope that it will be useful,
15203+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15204+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15205+ * GNU General Public License for more details.
15206+ *
15207+ * You should have received a copy of the GNU General Public License
523b37e3 15208+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15209+ */
1facf9fc 15210+
4a4d8108
AM
15211+/*
15212+ * special support for filesystems which aqucires an inode mutex
15213+ * at final closing a file, eg, hfsplus.
15214+ *
15215+ * This trick is very simple and stupid, just to open the file before really
15216+ * neceeary open to tell hfsplus that this is not the final closing.
15217+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
15218+ * and au_h_open_post() after releasing it.
15219+ */
1facf9fc 15220+
4a4d8108 15221+#include "aufs.h"
1facf9fc 15222+
392086de
AM
15223+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
15224+ int force_wr)
4a4d8108
AM
15225+{
15226+ struct file *h_file;
15227+ struct dentry *h_dentry;
1facf9fc 15228+
4a4d8108
AM
15229+ h_dentry = au_h_dptr(dentry, bindex);
15230+ AuDebugOn(!h_dentry);
5527c038 15231+ AuDebugOn(d_is_negative(h_dentry));
4a4d8108
AM
15232+
15233+ h_file = NULL;
15234+ if (au_test_hfsplus(h_dentry->d_sb)
7e9cd9fe 15235+ && d_is_reg(h_dentry))
4a4d8108
AM
15236+ h_file = au_h_open(dentry, bindex,
15237+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 15238+ /*file*/NULL, force_wr);
4a4d8108 15239+ return h_file;
1facf9fc 15240+}
15241+
4a4d8108
AM
15242+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
15243+ struct file *h_file)
15244+{
15245+ if (h_file) {
15246+ fput(h_file);
15247+ au_sbr_put(dentry->d_sb, bindex);
15248+ }
15249+}
7f207e10
AM
15250diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
15251--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
3c1bdaff 15252+++ linux/fs/aufs/hnotify.c 2017-09-05 10:42:11.058755349 +0200
1c60b727 15253@@ -0,0 +1,711 @@
e49829fe 15254+/*
a2654f78 15255+ * Copyright (C) 2005-2017 Junjiro R. Okajima
e49829fe
JR
15256+ *
15257+ * This program, aufs is free software; you can redistribute it and/or modify
15258+ * it under the terms of the GNU General Public License as published by
15259+ * the Free Software Foundation; either version 2 of the License, or
15260+ * (at your option) any later version.
15261+ *
15262+ * This program is distributed in the hope that it will be useful,
15263+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15264+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15265+ * GNU General Public License for more details.
15266+ *
15267+ * You should have received a copy of the GNU General Public License
523b37e3 15268+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
15269+ */
15270+
15271+/*
7f207e10 15272+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
15273+ */
15274+
15275+#include "aufs.h"
15276+
027c5e7a 15277+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
15278+{
15279+ int err;
7f207e10 15280+ struct au_hnotify *hn;
1facf9fc 15281+
4a4d8108
AM
15282+ err = -ENOMEM;
15283+ hn = au_cache_alloc_hnotify();
15284+ if (hn) {
15285+ hn->hn_aufs_inode = inode;
027c5e7a
AM
15286+ hinode->hi_notify = hn;
15287+ err = au_hnotify_op.alloc(hinode);
15288+ AuTraceErr(err);
15289+ if (unlikely(err)) {
15290+ hinode->hi_notify = NULL;
1c60b727 15291+ au_cache_free_hnotify(hn);
4a4d8108
AM
15292+ /*
15293+ * The upper dir was removed by udba, but the same named
15294+ * dir left. In this case, aufs assignes a new inode
15295+ * number and set the monitor again.
15296+ * For the lower dir, the old monitnor is still left.
15297+ */
15298+ if (err == -EEXIST)
15299+ err = 0;
15300+ }
1308ab2a 15301+ }
1308ab2a 15302+
027c5e7a 15303+ AuTraceErr(err);
1308ab2a 15304+ return err;
dece6358 15305+}
1facf9fc 15306+
4a4d8108 15307+void au_hn_free(struct au_hinode *hinode)
dece6358 15308+{
4a4d8108 15309+ struct au_hnotify *hn;
1facf9fc 15310+
4a4d8108
AM
15311+ hn = hinode->hi_notify;
15312+ if (hn) {
4a4d8108 15313+ hinode->hi_notify = NULL;
7eafdf33 15314+ if (au_hnotify_op.free(hinode, hn))
1c60b727 15315+ au_cache_free_hnotify(hn);
4a4d8108
AM
15316+ }
15317+}
dece6358 15318+
4a4d8108 15319+/* ---------------------------------------------------------------------- */
dece6358 15320+
4a4d8108
AM
15321+void au_hn_ctl(struct au_hinode *hinode, int do_set)
15322+{
15323+ if (hinode->hi_notify)
15324+ au_hnotify_op.ctl(hinode, do_set);
15325+}
15326+
15327+void au_hn_reset(struct inode *inode, unsigned int flags)
15328+{
5afbbe0d 15329+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
15330+ struct inode *hi;
15331+ struct dentry *iwhdentry;
1facf9fc 15332+
5afbbe0d
AM
15333+ bbot = au_ibbot(inode);
15334+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
4a4d8108
AM
15335+ hi = au_h_iptr(inode, bindex);
15336+ if (!hi)
15337+ continue;
1308ab2a 15338+
febd17d6 15339+ /* inode_lock_nested(hi, AuLsc_I_CHILD); */
4a4d8108
AM
15340+ iwhdentry = au_hi_wh(inode, bindex);
15341+ if (iwhdentry)
15342+ dget(iwhdentry);
15343+ au_igrab(hi);
15344+ au_set_h_iptr(inode, bindex, NULL, 0);
15345+ au_set_h_iptr(inode, bindex, au_igrab(hi),
15346+ flags & ~AuHi_XINO);
15347+ iput(hi);
15348+ dput(iwhdentry);
febd17d6 15349+ /* inode_unlock(hi); */
1facf9fc 15350+ }
1facf9fc 15351+}
15352+
1308ab2a 15353+/* ---------------------------------------------------------------------- */
1facf9fc 15354+
4a4d8108 15355+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 15356+{
4a4d8108 15357+ int err;
5afbbe0d 15358+ aufs_bindex_t bindex, bbot, bfound, btop;
4a4d8108 15359+ struct inode *h_i;
1facf9fc 15360+
4a4d8108
AM
15361+ err = 0;
15362+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 15363+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
15364+ goto out;
15365+ }
1facf9fc 15366+
4a4d8108 15367+ bfound = -1;
5afbbe0d
AM
15368+ bbot = au_ibbot(inode);
15369+ btop = au_ibtop(inode);
4a4d8108 15370+#if 0 /* reserved for future use */
5afbbe0d 15371+ if (bindex == bbot) {
4a4d8108
AM
15372+ /* keep this ino in rename case */
15373+ goto out;
15374+ }
15375+#endif
5afbbe0d 15376+ for (bindex = btop; bindex <= bbot; bindex++)
4a4d8108
AM
15377+ if (au_h_iptr(inode, bindex) == h_inode) {
15378+ bfound = bindex;
15379+ break;
15380+ }
15381+ if (bfound < 0)
1308ab2a 15382+ goto out;
1facf9fc 15383+
5afbbe0d 15384+ for (bindex = btop; bindex <= bbot; bindex++) {
4a4d8108
AM
15385+ h_i = au_h_iptr(inode, bindex);
15386+ if (!h_i)
15387+ continue;
1facf9fc 15388+
4a4d8108
AM
15389+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
15390+ /* ignore this error */
15391+ /* bad action? */
1facf9fc 15392+ }
1facf9fc 15393+
4a4d8108 15394+ /* children inode number will be broken */
1facf9fc 15395+
4f0767ce 15396+out:
4a4d8108
AM
15397+ AuTraceErr(err);
15398+ return err;
1facf9fc 15399+}
15400+
4a4d8108 15401+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 15402+{
4a4d8108
AM
15403+ int err, i, j, ndentry;
15404+ struct au_dcsub_pages dpages;
15405+ struct au_dpage *dpage;
15406+ struct dentry **dentries;
1facf9fc 15407+
4a4d8108
AM
15408+ err = au_dpages_init(&dpages, GFP_NOFS);
15409+ if (unlikely(err))
15410+ goto out;
15411+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
15412+ if (unlikely(err))
15413+ goto out_dpages;
1facf9fc 15414+
4a4d8108
AM
15415+ for (i = 0; i < dpages.ndpage; i++) {
15416+ dpage = dpages.dpages + i;
15417+ dentries = dpage->dentries;
15418+ ndentry = dpage->ndentry;
15419+ for (j = 0; j < ndentry; j++) {
15420+ struct dentry *d;
15421+
15422+ d = dentries[j];
15423+ if (IS_ROOT(d))
15424+ continue;
15425+
4a4d8108 15426+ au_digen_dec(d);
5527c038 15427+ if (d_really_is_positive(d))
4a4d8108
AM
15428+ /* todo: reset children xino?
15429+ cached children only? */
5527c038 15430+ au_iigen_dec(d_inode(d));
1308ab2a 15431+ }
dece6358 15432+ }
1facf9fc 15433+
4f0767ce 15434+out_dpages:
4a4d8108 15435+ au_dpages_free(&dpages);
dece6358 15436+
027c5e7a 15437+#if 0
4a4d8108
AM
15438+ /* discard children */
15439+ dentry_unhash(dentry);
15440+ dput(dentry);
027c5e7a 15441+#endif
4f0767ce 15442+out:
dece6358
AM
15443+ return err;
15444+}
15445+
1308ab2a 15446+/*
4a4d8108 15447+ * return 0 if processed.
1308ab2a 15448+ */
4a4d8108
AM
15449+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
15450+ const unsigned int isdir)
dece6358 15451+{
1308ab2a 15452+ int err;
4a4d8108
AM
15453+ struct dentry *d;
15454+ struct qstr *dname;
1facf9fc 15455+
4a4d8108
AM
15456+ err = 1;
15457+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 15458+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
15459+ err = 0;
15460+ goto out;
15461+ }
dece6358 15462+
4a4d8108
AM
15463+ if (!isdir) {
15464+ AuDebugOn(!name);
15465+ au_iigen_dec(inode);
027c5e7a 15466+ spin_lock(&inode->i_lock);
c1595e42 15467+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 15468+ spin_lock(&d->d_lock);
4a4d8108
AM
15469+ dname = &d->d_name;
15470+ if (dname->len != nlen
027c5e7a
AM
15471+ && memcmp(dname->name, name, nlen)) {
15472+ spin_unlock(&d->d_lock);
4a4d8108 15473+ continue;
027c5e7a 15474+ }
4a4d8108 15475+ err = 0;
4a4d8108
AM
15476+ au_digen_dec(d);
15477+ spin_unlock(&d->d_lock);
15478+ break;
1facf9fc 15479+ }
027c5e7a 15480+ spin_unlock(&inode->i_lock);
1308ab2a 15481+ } else {
027c5e7a 15482+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
c1595e42 15483+ d = d_find_any_alias(inode);
4a4d8108
AM
15484+ if (!d) {
15485+ au_iigen_dec(inode);
15486+ goto out;
15487+ }
1facf9fc 15488+
027c5e7a 15489+ spin_lock(&d->d_lock);
4a4d8108 15490+ dname = &d->d_name;
027c5e7a
AM
15491+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
15492+ spin_unlock(&d->d_lock);
4a4d8108 15493+ err = hn_gen_tree(d);
027c5e7a
AM
15494+ spin_lock(&d->d_lock);
15495+ }
15496+ spin_unlock(&d->d_lock);
4a4d8108
AM
15497+ dput(d);
15498+ }
1facf9fc 15499+
4f0767ce 15500+out:
4a4d8108 15501+ AuTraceErr(err);
1308ab2a 15502+ return err;
15503+}
dece6358 15504+
4a4d8108 15505+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 15506+{
4a4d8108 15507+ int err;
1facf9fc 15508+
5527c038 15509+ if (IS_ROOT(dentry)) {
0c3ec466 15510+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
15511+ return 0;
15512+ }
1308ab2a 15513+
4a4d8108
AM
15514+ err = 0;
15515+ if (!isdir) {
4a4d8108 15516+ au_digen_dec(dentry);
5527c038
JR
15517+ if (d_really_is_positive(dentry))
15518+ au_iigen_dec(d_inode(dentry));
4a4d8108 15519+ } else {
027c5e7a 15520+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
5527c038 15521+ if (d_really_is_positive(dentry))
4a4d8108
AM
15522+ err = hn_gen_tree(dentry);
15523+ }
15524+
15525+ AuTraceErr(err);
15526+ return err;
1facf9fc 15527+}
15528+
4a4d8108 15529+/* ---------------------------------------------------------------------- */
1facf9fc 15530+
4a4d8108
AM
15531+/* hnotify job flags */
15532+#define AuHnJob_XINO0 1
15533+#define AuHnJob_GEN (1 << 1)
15534+#define AuHnJob_DIRENT (1 << 2)
15535+#define AuHnJob_ISDIR (1 << 3)
15536+#define AuHnJob_TRYXINO0 (1 << 4)
15537+#define AuHnJob_MNTPNT (1 << 5)
15538+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
15539+#define au_fset_hnjob(flags, name) \
15540+ do { (flags) |= AuHnJob_##name; } while (0)
15541+#define au_fclr_hnjob(flags, name) \
15542+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 15543+
4a4d8108
AM
15544+enum {
15545+ AuHn_CHILD,
15546+ AuHn_PARENT,
15547+ AuHnLast
15548+};
1facf9fc 15549+
4a4d8108
AM
15550+struct au_hnotify_args {
15551+ struct inode *h_dir, *dir, *h_child_inode;
15552+ u32 mask;
15553+ unsigned int flags[AuHnLast];
15554+ unsigned int h_child_nlen;
15555+ char h_child_name[];
15556+};
1facf9fc 15557+
4a4d8108
AM
15558+struct hn_job_args {
15559+ unsigned int flags;
15560+ struct inode *inode, *h_inode, *dir, *h_dir;
15561+ struct dentry *dentry;
15562+ char *h_name;
15563+ int h_nlen;
15564+};
1308ab2a 15565+
4a4d8108
AM
15566+static int hn_job(struct hn_job_args *a)
15567+{
15568+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
076b876e 15569+ int e;
1308ab2a 15570+
4a4d8108
AM
15571+ /* reset xino */
15572+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
15573+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 15574+
4a4d8108
AM
15575+ if (au_ftest_hnjob(a->flags, TRYXINO0)
15576+ && a->inode
15577+ && a->h_inode) {
3c1bdaff 15578+ vfsub_inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
38d290e6
JR
15579+ if (!a->h_inode->i_nlink
15580+ && !(a->h_inode->i_state & I_LINKABLE))
4a4d8108 15581+ hn_xino(a->inode, a->h_inode); /* ignore this error */
3c1bdaff 15582+ inode_unlock_shared(a->h_inode);
1308ab2a 15583+ }
1facf9fc 15584+
4a4d8108
AM
15585+ /* make the generation obsolete */
15586+ if (au_ftest_hnjob(a->flags, GEN)) {
076b876e 15587+ e = -1;
4a4d8108 15588+ if (a->inode)
076b876e 15589+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
4a4d8108 15590+ isdir);
076b876e 15591+ if (e && a->dentry)
4a4d8108
AM
15592+ hn_gen_by_name(a->dentry, isdir);
15593+ /* ignore this error */
1facf9fc 15594+ }
1facf9fc 15595+
4a4d8108
AM
15596+ /* make dir entries obsolete */
15597+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
15598+ struct au_vdir *vdir;
1facf9fc 15599+
4a4d8108
AM
15600+ vdir = au_ivdir(a->inode);
15601+ if (vdir)
15602+ vdir->vd_jiffy = 0;
15603+ /* IMustLock(a->inode); */
15604+ /* a->inode->i_version++; */
15605+ }
1facf9fc 15606+
4a4d8108
AM
15607+ /* can do nothing but warn */
15608+ if (au_ftest_hnjob(a->flags, MNTPNT)
15609+ && a->dentry
15610+ && d_mountpoint(a->dentry))
523b37e3 15611+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 15612+
4a4d8108 15613+ return 0;
1308ab2a 15614+}
1facf9fc 15615+
1308ab2a 15616+/* ---------------------------------------------------------------------- */
1facf9fc 15617+
4a4d8108
AM
15618+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
15619+ struct inode *dir)
1308ab2a 15620+{
4a4d8108
AM
15621+ struct dentry *dentry, *d, *parent;
15622+ struct qstr *dname;
1308ab2a 15623+
c1595e42 15624+ parent = d_find_any_alias(dir);
4a4d8108
AM
15625+ if (!parent)
15626+ return NULL;
1308ab2a 15627+
4a4d8108 15628+ dentry = NULL;
027c5e7a 15629+ spin_lock(&parent->d_lock);
c1595e42 15630+ list_for_each_entry(d, &parent->d_subdirs, d_child) {
523b37e3 15631+ /* AuDbg("%pd\n", d); */
027c5e7a 15632+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
15633+ dname = &d->d_name;
15634+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
15635+ goto cont_unlock;
15636+ if (au_di(d))
15637+ au_digen_dec(d);
15638+ else
15639+ goto cont_unlock;
c1595e42 15640+ if (au_dcount(d) > 0) {
027c5e7a 15641+ dentry = dget_dlock(d);
4a4d8108 15642+ spin_unlock(&d->d_lock);
027c5e7a 15643+ break;
dece6358 15644+ }
1facf9fc 15645+
f6b6e03d 15646+cont_unlock:
027c5e7a 15647+ spin_unlock(&d->d_lock);
1308ab2a 15648+ }
027c5e7a 15649+ spin_unlock(&parent->d_lock);
4a4d8108 15650+ dput(parent);
1facf9fc 15651+
4a4d8108
AM
15652+ if (dentry)
15653+ di_write_lock_child(dentry);
1308ab2a 15654+
4a4d8108
AM
15655+ return dentry;
15656+}
dece6358 15657+
4a4d8108
AM
15658+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
15659+ aufs_bindex_t bindex, ino_t h_ino)
15660+{
15661+ struct inode *inode;
15662+ ino_t ino;
15663+ int err;
15664+
15665+ inode = NULL;
15666+ err = au_xino_read(sb, bindex, h_ino, &ino);
15667+ if (!err && ino)
15668+ inode = ilookup(sb, ino);
15669+ if (!inode)
15670+ goto out;
15671+
15672+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 15673+ pr_warn("wrong root branch\n");
4a4d8108
AM
15674+ iput(inode);
15675+ inode = NULL;
15676+ goto out;
1308ab2a 15677+ }
15678+
4a4d8108 15679+ ii_write_lock_child(inode);
1308ab2a 15680+
4f0767ce 15681+out:
4a4d8108 15682+ return inode;
dece6358
AM
15683+}
15684+
4a4d8108 15685+static void au_hn_bh(void *_args)
1facf9fc 15686+{
4a4d8108
AM
15687+ struct au_hnotify_args *a = _args;
15688+ struct super_block *sb;
5afbbe0d 15689+ aufs_bindex_t bindex, bbot, bfound;
4a4d8108 15690+ unsigned char xino, try_iput;
1facf9fc 15691+ int err;
1308ab2a 15692+ struct inode *inode;
4a4d8108
AM
15693+ ino_t h_ino;
15694+ struct hn_job_args args;
15695+ struct dentry *dentry;
15696+ struct au_sbinfo *sbinfo;
1facf9fc 15697+
4a4d8108
AM
15698+ AuDebugOn(!_args);
15699+ AuDebugOn(!a->h_dir);
15700+ AuDebugOn(!a->dir);
15701+ AuDebugOn(!a->mask);
15702+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
15703+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
15704+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 15705+
4a4d8108
AM
15706+ inode = NULL;
15707+ dentry = NULL;
15708+ /*
15709+ * do not lock a->dir->i_mutex here
15710+ * because of d_revalidate() may cause a deadlock.
15711+ */
15712+ sb = a->dir->i_sb;
15713+ AuDebugOn(!sb);
15714+ sbinfo = au_sbi(sb);
15715+ AuDebugOn(!sbinfo);
7f207e10 15716+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 15717+
4a4d8108
AM
15718+ ii_read_lock_parent(a->dir);
15719+ bfound = -1;
5afbbe0d
AM
15720+ bbot = au_ibbot(a->dir);
15721+ for (bindex = au_ibtop(a->dir); bindex <= bbot; bindex++)
4a4d8108
AM
15722+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
15723+ bfound = bindex;
15724+ break;
15725+ }
15726+ ii_read_unlock(a->dir);
15727+ if (unlikely(bfound < 0))
15728+ goto out;
1facf9fc 15729+
4a4d8108
AM
15730+ xino = !!au_opt_test(au_mntflags(sb), XINO);
15731+ h_ino = 0;
15732+ if (a->h_child_inode)
15733+ h_ino = a->h_child_inode->i_ino;
1facf9fc 15734+
4a4d8108
AM
15735+ if (a->h_child_nlen
15736+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
15737+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
15738+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
15739+ a->dir);
15740+ try_iput = 0;
5527c038
JR
15741+ if (dentry && d_really_is_positive(dentry))
15742+ inode = d_inode(dentry);
4a4d8108
AM
15743+ if (xino && !inode && h_ino
15744+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
15745+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
15746+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
15747+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
15748+ try_iput = 1;
f0c0a007 15749+ }
1facf9fc 15750+
4a4d8108
AM
15751+ args.flags = a->flags[AuHn_CHILD];
15752+ args.dentry = dentry;
15753+ args.inode = inode;
15754+ args.h_inode = a->h_child_inode;
15755+ args.dir = a->dir;
15756+ args.h_dir = a->h_dir;
15757+ args.h_name = a->h_child_name;
15758+ args.h_nlen = a->h_child_nlen;
15759+ err = hn_job(&args);
15760+ if (dentry) {
027c5e7a 15761+ if (au_di(dentry))
4a4d8108
AM
15762+ di_write_unlock(dentry);
15763+ dput(dentry);
15764+ }
15765+ if (inode && try_iput) {
15766+ ii_write_unlock(inode);
15767+ iput(inode);
15768+ }
1facf9fc 15769+
4a4d8108
AM
15770+ ii_write_lock_parent(a->dir);
15771+ args.flags = a->flags[AuHn_PARENT];
15772+ args.dentry = NULL;
15773+ args.inode = a->dir;
15774+ args.h_inode = a->h_dir;
15775+ args.dir = NULL;
15776+ args.h_dir = NULL;
15777+ args.h_name = NULL;
15778+ args.h_nlen = 0;
15779+ err = hn_job(&args);
15780+ ii_write_unlock(a->dir);
1facf9fc 15781+
4f0767ce 15782+out:
4a4d8108
AM
15783+ iput(a->h_child_inode);
15784+ iput(a->h_dir);
15785+ iput(a->dir);
027c5e7a
AM
15786+ si_write_unlock(sb);
15787+ au_nwt_done(&sbinfo->si_nowait);
1c60b727 15788+ kfree(a);
dece6358 15789+}
1facf9fc 15790+
4a4d8108
AM
15791+/* ---------------------------------------------------------------------- */
15792+
15793+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15794+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 15795+{
4a4d8108 15796+ int err, len;
53392da6 15797+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
15798+ unsigned char isdir, isroot, wh;
15799+ struct inode *dir;
15800+ struct au_hnotify_args *args;
15801+ char *p, *h_child_name;
dece6358 15802+
1308ab2a 15803+ err = 0;
4a4d8108
AM
15804+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
15805+ dir = igrab(hnotify->hn_aufs_inode);
15806+ if (!dir)
15807+ goto out;
1facf9fc 15808+
4a4d8108
AM
15809+ isroot = (dir->i_ino == AUFS_ROOT_INO);
15810+ wh = 0;
15811+ h_child_name = (void *)h_child_qstr->name;
15812+ len = h_child_qstr->len;
15813+ if (h_child_name) {
15814+ if (len > AUFS_WH_PFX_LEN
15815+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
15816+ h_child_name += AUFS_WH_PFX_LEN;
15817+ len -= AUFS_WH_PFX_LEN;
15818+ wh = 1;
15819+ }
1facf9fc 15820+ }
dece6358 15821+
4a4d8108
AM
15822+ isdir = 0;
15823+ if (h_child_inode)
15824+ isdir = !!S_ISDIR(h_child_inode->i_mode);
15825+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
15826+ flags[AuHn_CHILD] = 0;
15827+ if (isdir)
15828+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
15829+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
15830+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
15831+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
15832+ case FS_MOVED_FROM:
15833+ case FS_MOVED_TO:
15834+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
15835+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15836+ /*FALLTHROUGH*/
15837+ case FS_CREATE:
fb47a38f 15838+ AuDebugOn(!h_child_name);
4a4d8108 15839+ break;
1facf9fc 15840+
4a4d8108
AM
15841+ case FS_DELETE:
15842+ /*
15843+ * aufs never be able to get this child inode.
15844+ * revalidation should be in d_revalidate()
15845+ * by checking i_nlink, i_generation or d_unhashed().
15846+ */
15847+ AuDebugOn(!h_child_name);
15848+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
15849+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15850+ break;
dece6358 15851+
4a4d8108
AM
15852+ default:
15853+ AuDebugOn(1);
15854+ }
1308ab2a 15855+
4a4d8108
AM
15856+ if (wh)
15857+ h_child_inode = NULL;
1308ab2a 15858+
4a4d8108
AM
15859+ err = -ENOMEM;
15860+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 15861+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
15862+ if (unlikely(!args)) {
15863+ AuErr1("no memory\n");
15864+ iput(dir);
15865+ goto out;
15866+ }
15867+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
15868+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
15869+ args->mask = mask;
15870+ args->dir = dir;
15871+ args->h_dir = igrab(h_dir);
15872+ if (h_child_inode)
15873+ h_child_inode = igrab(h_child_inode); /* can be NULL */
15874+ args->h_child_inode = h_child_inode;
15875+ args->h_child_nlen = len;
15876+ if (len) {
15877+ p = (void *)args;
15878+ p += sizeof(*args);
15879+ memcpy(p, h_child_name, len);
15880+ p[len] = 0;
1308ab2a 15881+ }
1308ab2a 15882+
38d290e6 15883+ /* NFS fires the event for silly-renamed one from kworker */
53392da6 15884+ f = 0;
38d290e6
JR
15885+ if (!dir->i_nlink
15886+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
53392da6
AM
15887+ f = AuWkq_NEST;
15888+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
15889+ if (unlikely(err)) {
15890+ pr_err("wkq %d\n", err);
15891+ iput(args->h_child_inode);
15892+ iput(args->h_dir);
15893+ iput(args->dir);
1c60b727 15894+ kfree(args);
1facf9fc 15895+ }
1facf9fc 15896+
4a4d8108 15897+out:
1facf9fc 15898+ return err;
15899+}
15900+
027c5e7a
AM
15901+/* ---------------------------------------------------------------------- */
15902+
15903+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
15904+{
15905+ int err;
15906+
15907+ AuDebugOn(!(udba & AuOptMask_UDBA));
15908+
15909+ err = 0;
15910+ if (au_hnotify_op.reset_br)
15911+ err = au_hnotify_op.reset_br(udba, br, perm);
15912+
15913+ return err;
15914+}
15915+
15916+int au_hnotify_init_br(struct au_branch *br, int perm)
15917+{
15918+ int err;
15919+
15920+ err = 0;
15921+ if (au_hnotify_op.init_br)
15922+ err = au_hnotify_op.init_br(br, perm);
15923+
15924+ return err;
15925+}
15926+
15927+void au_hnotify_fin_br(struct au_branch *br)
15928+{
15929+ if (au_hnotify_op.fin_br)
15930+ au_hnotify_op.fin_br(br);
15931+}
15932+
4a4d8108
AM
15933+static void au_hn_destroy_cache(void)
15934+{
1c60b727
AM
15935+ kmem_cache_destroy(au_cache[AuCache_HNOTIFY]);
15936+ au_cache[AuCache_HNOTIFY] = NULL;
4a4d8108 15937+}
1308ab2a 15938+
4a4d8108 15939+int __init au_hnotify_init(void)
1facf9fc 15940+{
1308ab2a 15941+ int err;
1308ab2a 15942+
4a4d8108 15943+ err = -ENOMEM;
1c60b727
AM
15944+ au_cache[AuCache_HNOTIFY] = AuCache(au_hnotify);
15945+ if (au_cache[AuCache_HNOTIFY]) {
027c5e7a
AM
15946+ err = 0;
15947+ if (au_hnotify_op.init)
15948+ err = au_hnotify_op.init();
4a4d8108
AM
15949+ if (unlikely(err))
15950+ au_hn_destroy_cache();
1308ab2a 15951+ }
1308ab2a 15952+ AuTraceErr(err);
4a4d8108 15953+ return err;
1308ab2a 15954+}
15955+
4a4d8108 15956+void au_hnotify_fin(void)
1308ab2a 15957+{
027c5e7a
AM
15958+ if (au_hnotify_op.fin)
15959+ au_hnotify_op.fin();
f0c0a007 15960+
4a4d8108 15961+ /* cf. au_cache_fin() */
1c60b727 15962+ if (au_cache[AuCache_HNOTIFY])
4a4d8108 15963+ au_hn_destroy_cache();
dece6358 15964+}
7f207e10
AM
15965diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
15966--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 15967+++ linux/fs/aufs/iinfo.c 2017-07-29 12:14:25.903042072 +0200
e2f27e51 15968@@ -0,0 +1,285 @@
dece6358 15969+/*
a2654f78 15970+ * Copyright (C) 2005-2017 Junjiro R. Okajima
dece6358
AM
15971+ *
15972+ * This program, aufs is free software; you can redistribute it and/or modify
15973+ * it under the terms of the GNU General Public License as published by
15974+ * the Free Software Foundation; either version 2 of the License, or
15975+ * (at your option) any later version.
15976+ *
15977+ * This program is distributed in the hope that it will be useful,
15978+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15979+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15980+ * GNU General Public License for more details.
15981+ *
15982+ * You should have received a copy of the GNU General Public License
523b37e3 15983+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 15984+ */
1facf9fc 15985+
dece6358 15986+/*
4a4d8108 15987+ * inode private data
dece6358 15988+ */
1facf9fc 15989+
1308ab2a 15990+#include "aufs.h"
1facf9fc 15991+
4a4d8108 15992+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15993+{
4a4d8108 15994+ struct inode *h_inode;
5afbbe0d 15995+ struct au_hinode *hinode;
1facf9fc 15996+
4a4d8108 15997+ IiMustAnyLock(inode);
1facf9fc 15998+
5afbbe0d
AM
15999+ hinode = au_hinode(au_ii(inode), bindex);
16000+ h_inode = hinode->hi_inode;
4a4d8108
AM
16001+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
16002+ return h_inode;
16003+}
1facf9fc 16004+
4a4d8108
AM
16005+/* todo: hard/soft set? */
16006+void au_hiput(struct au_hinode *hinode)
16007+{
16008+ au_hn_free(hinode);
16009+ dput(hinode->hi_whdentry);
16010+ iput(hinode->hi_inode);
16011+}
1facf9fc 16012+
4a4d8108
AM
16013+unsigned int au_hi_flags(struct inode *inode, int isdir)
16014+{
16015+ unsigned int flags;
16016+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 16017+
4a4d8108
AM
16018+ flags = 0;
16019+ if (au_opt_test(mnt_flags, XINO))
16020+ au_fset_hi(flags, XINO);
16021+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
16022+ au_fset_hi(flags, HNOTIFY);
16023+ return flags;
1facf9fc 16024+}
16025+
4a4d8108
AM
16026+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
16027+ struct inode *h_inode, unsigned int flags)
1308ab2a 16028+{
4a4d8108
AM
16029+ struct au_hinode *hinode;
16030+ struct inode *hi;
16031+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 16032+
4a4d8108 16033+ IiMustWriteLock(inode);
dece6358 16034+
5afbbe0d 16035+ hinode = au_hinode(iinfo, bindex);
4a4d8108
AM
16036+ hi = hinode->hi_inode;
16037+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
16038+
16039+ if (hi)
16040+ au_hiput(hinode);
16041+ hinode->hi_inode = h_inode;
16042+ if (h_inode) {
16043+ int err;
16044+ struct super_block *sb = inode->i_sb;
16045+ struct au_branch *br;
16046+
027c5e7a
AM
16047+ AuDebugOn(inode->i_mode
16048+ && (h_inode->i_mode & S_IFMT)
16049+ != (inode->i_mode & S_IFMT));
5afbbe0d 16050+ if (bindex == iinfo->ii_btop)
4a4d8108
AM
16051+ au_cpup_igen(inode, h_inode);
16052+ br = au_sbr(sb, bindex);
16053+ hinode->hi_id = br->br_id;
16054+ if (au_ftest_hi(flags, XINO)) {
16055+ err = au_xino_write(sb, bindex, h_inode->i_ino,
16056+ inode->i_ino);
16057+ if (unlikely(err))
16058+ AuIOErr1("failed au_xino_write() %d\n", err);
16059+ }
16060+
16061+ if (au_ftest_hi(flags, HNOTIFY)
16062+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 16063+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
16064+ if (unlikely(err))
16065+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 16066+ }
16067+ }
4a4d8108 16068+}
dece6358 16069+
4a4d8108
AM
16070+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
16071+ struct dentry *h_wh)
16072+{
16073+ struct au_hinode *hinode;
dece6358 16074+
4a4d8108
AM
16075+ IiMustWriteLock(inode);
16076+
5afbbe0d 16077+ hinode = au_hinode(au_ii(inode), bindex);
4a4d8108
AM
16078+ AuDebugOn(hinode->hi_whdentry);
16079+ hinode->hi_whdentry = h_wh;
1facf9fc 16080+}
16081+
537831f9 16082+void au_update_iigen(struct inode *inode, int half)
1308ab2a 16083+{
537831f9
AM
16084+ struct au_iinfo *iinfo;
16085+ struct au_iigen *iigen;
16086+ unsigned int sigen;
16087+
16088+ sigen = au_sigen(inode->i_sb);
16089+ iinfo = au_ii(inode);
16090+ iigen = &iinfo->ii_generation;
be52b249 16091+ spin_lock(&iigen->ig_spin);
537831f9
AM
16092+ iigen->ig_generation = sigen;
16093+ if (half)
16094+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
16095+ else
16096+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
be52b249 16097+ spin_unlock(&iigen->ig_spin);
4a4d8108 16098+}
1facf9fc 16099+
4a4d8108
AM
16100+/* it may be called at remount time, too */
16101+void au_update_ibrange(struct inode *inode, int do_put_zero)
16102+{
16103+ struct au_iinfo *iinfo;
5afbbe0d 16104+ aufs_bindex_t bindex, bbot;
1facf9fc 16105+
5afbbe0d 16106+ AuDebugOn(au_is_bad_inode(inode));
4a4d8108 16107+ IiMustWriteLock(inode);
1facf9fc 16108+
5afbbe0d
AM
16109+ iinfo = au_ii(inode);
16110+ if (do_put_zero && iinfo->ii_btop >= 0) {
16111+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot;
4a4d8108
AM
16112+ bindex++) {
16113+ struct inode *h_i;
1facf9fc 16114+
5afbbe0d 16115+ h_i = au_hinode(iinfo, bindex)->hi_inode;
38d290e6
JR
16116+ if (h_i
16117+ && !h_i->i_nlink
16118+ && !(h_i->i_state & I_LINKABLE))
027c5e7a
AM
16119+ au_set_h_iptr(inode, bindex, NULL, 0);
16120+ }
4a4d8108
AM
16121+ }
16122+
5afbbe0d
AM
16123+ iinfo->ii_btop = -1;
16124+ iinfo->ii_bbot = -1;
16125+ bbot = au_sbbot(inode->i_sb);
16126+ for (bindex = 0; bindex <= bbot; bindex++)
16127+ if (au_hinode(iinfo, bindex)->hi_inode) {
16128+ iinfo->ii_btop = bindex;
4a4d8108 16129+ break;
027c5e7a 16130+ }
5afbbe0d
AM
16131+ if (iinfo->ii_btop >= 0)
16132+ for (bindex = bbot; bindex >= iinfo->ii_btop; bindex--)
16133+ if (au_hinode(iinfo, bindex)->hi_inode) {
16134+ iinfo->ii_bbot = bindex;
027c5e7a
AM
16135+ break;
16136+ }
5afbbe0d 16137+ AuDebugOn(iinfo->ii_btop > iinfo->ii_bbot);
1308ab2a 16138+}
1facf9fc 16139+
dece6358 16140+/* ---------------------------------------------------------------------- */
1facf9fc 16141+
4a4d8108 16142+void au_icntnr_init_once(void *_c)
dece6358 16143+{
4a4d8108
AM
16144+ struct au_icntnr *c = _c;
16145+ struct au_iinfo *iinfo = &c->iinfo;
1facf9fc 16146+
be52b249 16147+ spin_lock_init(&iinfo->ii_generation.ig_spin);
4a4d8108
AM
16148+ au_rw_init(&iinfo->ii_rwsem);
16149+ inode_init_once(&c->vfs_inode);
16150+}
1facf9fc 16151+
5afbbe0d
AM
16152+void au_hinode_init(struct au_hinode *hinode)
16153+{
16154+ hinode->hi_inode = NULL;
16155+ hinode->hi_id = -1;
16156+ au_hn_init(hinode);
16157+ hinode->hi_whdentry = NULL;
16158+}
16159+
4a4d8108
AM
16160+int au_iinfo_init(struct inode *inode)
16161+{
16162+ struct au_iinfo *iinfo;
16163+ struct super_block *sb;
5afbbe0d 16164+ struct au_hinode *hi;
4a4d8108 16165+ int nbr, i;
1facf9fc 16166+
4a4d8108
AM
16167+ sb = inode->i_sb;
16168+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
5afbbe0d 16169+ nbr = au_sbbot(sb) + 1;
4a4d8108
AM
16170+ if (unlikely(nbr <= 0))
16171+ nbr = 1;
5afbbe0d
AM
16172+ hi = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
16173+ if (hi) {
7f207e10 16174+ au_ninodes_inc(sb);
5afbbe0d
AM
16175+
16176+ iinfo->ii_hinode = hi;
16177+ for (i = 0; i < nbr; i++, hi++)
16178+ au_hinode_init(hi);
1facf9fc 16179+
537831f9 16180+ iinfo->ii_generation.ig_generation = au_sigen(sb);
5afbbe0d
AM
16181+ iinfo->ii_btop = -1;
16182+ iinfo->ii_bbot = -1;
4a4d8108
AM
16183+ iinfo->ii_vdir = NULL;
16184+ return 0;
1308ab2a 16185+ }
4a4d8108
AM
16186+ return -ENOMEM;
16187+}
1facf9fc 16188+
e2f27e51 16189+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink)
4a4d8108 16190+{
5afbbe0d 16191+ int err, i;
4a4d8108 16192+ struct au_hinode *hip;
1facf9fc 16193+
4a4d8108
AM
16194+ AuRwMustWriteLock(&iinfo->ii_rwsem);
16195+
16196+ err = -ENOMEM;
e2f27e51
AM
16197+ hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS,
16198+ may_shrink);
4a4d8108
AM
16199+ if (hip) {
16200+ iinfo->ii_hinode = hip;
5afbbe0d
AM
16201+ i = iinfo->ii_bbot + 1;
16202+ hip += i;
16203+ for (; i < nbr; i++, hip++)
16204+ au_hinode_init(hip);
4a4d8108 16205+ err = 0;
1308ab2a 16206+ }
4a4d8108 16207+
1308ab2a 16208+ return err;
1facf9fc 16209+}
16210+
4a4d8108 16211+void au_iinfo_fin(struct inode *inode)
1facf9fc 16212+{
4a4d8108
AM
16213+ struct au_iinfo *iinfo;
16214+ struct au_hinode *hi;
16215+ struct super_block *sb;
5afbbe0d 16216+ aufs_bindex_t bindex, bbot;
b752ccd1 16217+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 16218+
5afbbe0d 16219+ AuDebugOn(au_is_bad_inode(inode));
1308ab2a 16220+
b752ccd1 16221+ sb = inode->i_sb;
7f207e10 16222+ au_ninodes_dec(sb);
b752ccd1
AM
16223+ if (si_pid_test(sb))
16224+ au_xino_delete_inode(inode, unlinked);
16225+ else {
16226+ /*
16227+ * it is safe to hide the dependency between sbinfo and
16228+ * sb->s_umount.
16229+ */
16230+ lockdep_off();
16231+ si_noflush_read_lock(sb);
16232+ au_xino_delete_inode(inode, unlinked);
16233+ si_read_unlock(sb);
16234+ lockdep_on();
16235+ }
16236+
5afbbe0d 16237+ iinfo = au_ii(inode);
4a4d8108 16238+ if (iinfo->ii_vdir)
1c60b727 16239+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 16240+
5afbbe0d 16241+ bindex = iinfo->ii_btop;
b752ccd1 16242+ if (bindex >= 0) {
5afbbe0d
AM
16243+ hi = au_hinode(iinfo, bindex);
16244+ bbot = iinfo->ii_bbot;
16245+ while (bindex++ <= bbot) {
b752ccd1 16246+ if (hi->hi_inode)
4a4d8108 16247+ au_hiput(hi);
4a4d8108
AM
16248+ hi++;
16249+ }
16250+ }
1c60b727 16251+ kfree(iinfo->ii_hinode);
4a4d8108 16252+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 16253+}
7f207e10
AM
16254diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
16255--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 16256+++ linux/fs/aufs/inode.c 2017-07-29 12:14:25.903042072 +0200
521ced18 16257@@ -0,0 +1,527 @@
4a4d8108 16258+/*
a2654f78 16259+ * Copyright (C) 2005-2017 Junjiro R. Okajima
4a4d8108
AM
16260+ *
16261+ * This program, aufs is free software; you can redistribute it and/or modify
16262+ * it under the terms of the GNU General Public License as published by
16263+ * the Free Software Foundation; either version 2 of the License, or
16264+ * (at your option) any later version.
16265+ *
16266+ * This program is distributed in the hope that it will be useful,
16267+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16268+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16269+ * GNU General Public License for more details.
16270+ *
16271+ * You should have received a copy of the GNU General Public License
523b37e3 16272+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 16273+ */
1facf9fc 16274+
4a4d8108
AM
16275+/*
16276+ * inode functions
16277+ */
1facf9fc 16278+
4a4d8108 16279+#include "aufs.h"
1308ab2a 16280+
4a4d8108
AM
16281+struct inode *au_igrab(struct inode *inode)
16282+{
16283+ if (inode) {
16284+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 16285+ ihold(inode);
1facf9fc 16286+ }
4a4d8108
AM
16287+ return inode;
16288+}
1facf9fc 16289+
4a4d8108
AM
16290+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
16291+{
16292+ au_cpup_attr_all(inode, /*force*/0);
537831f9 16293+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
16294+ if (do_version)
16295+ inode->i_version++;
dece6358 16296+}
1facf9fc 16297+
027c5e7a 16298+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 16299+{
e2f27e51 16300+ int err, e, nbr;
027c5e7a 16301+ umode_t type;
4a4d8108 16302+ aufs_bindex_t bindex, new_bindex;
1308ab2a 16303+ struct super_block *sb;
4a4d8108 16304+ struct au_iinfo *iinfo;
027c5e7a 16305+ struct au_hinode *p, *q, tmp;
1facf9fc 16306+
5afbbe0d 16307+ AuDebugOn(au_is_bad_inode(inode));
4a4d8108 16308+ IiMustWriteLock(inode);
1facf9fc 16309+
027c5e7a 16310+ *update = 0;
4a4d8108 16311+ sb = inode->i_sb;
e2f27e51 16312+ nbr = au_sbbot(sb) + 1;
027c5e7a 16313+ type = inode->i_mode & S_IFMT;
4a4d8108 16314+ iinfo = au_ii(inode);
e2f27e51 16315+ err = au_hinode_realloc(iinfo, nbr, /*may_shrink*/0);
4a4d8108 16316+ if (unlikely(err))
1308ab2a 16317+ goto out;
1facf9fc 16318+
5afbbe0d
AM
16319+ AuDebugOn(iinfo->ii_btop < 0);
16320+ p = au_hinode(iinfo, iinfo->ii_btop);
16321+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot;
4a4d8108
AM
16322+ bindex++, p++) {
16323+ if (!p->hi_inode)
16324+ continue;
1facf9fc 16325+
027c5e7a 16326+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
16327+ new_bindex = au_br_index(sb, p->hi_id);
16328+ if (new_bindex == bindex)
16329+ continue;
1facf9fc 16330+
4a4d8108 16331+ if (new_bindex < 0) {
027c5e7a 16332+ *update = 1;
4a4d8108
AM
16333+ au_hiput(p);
16334+ p->hi_inode = NULL;
16335+ continue;
1308ab2a 16336+ }
4a4d8108 16337+
5afbbe0d
AM
16338+ if (new_bindex < iinfo->ii_btop)
16339+ iinfo->ii_btop = new_bindex;
16340+ if (iinfo->ii_bbot < new_bindex)
16341+ iinfo->ii_bbot = new_bindex;
4a4d8108 16342+ /* swap two lower inode, and loop again */
5afbbe0d 16343+ q = au_hinode(iinfo, new_bindex);
4a4d8108
AM
16344+ tmp = *q;
16345+ *q = *p;
16346+ *p = tmp;
16347+ if (tmp.hi_inode) {
16348+ bindex--;
16349+ p--;
1308ab2a 16350+ }
16351+ }
4a4d8108 16352+ au_update_ibrange(inode, /*do_put_zero*/0);
e2f27e51 16353+ au_hinode_realloc(iinfo, nbr, /*may_shrink*/1); /* harmless if err */
4a4d8108
AM
16354+ e = au_dy_irefresh(inode);
16355+ if (unlikely(e && !err))
16356+ err = e;
1facf9fc 16357+
4f0767ce 16358+out:
027c5e7a
AM
16359+ AuTraceErr(err);
16360+ return err;
16361+}
16362+
b95c5147
AM
16363+void au_refresh_iop(struct inode *inode, int force_getattr)
16364+{
16365+ int type;
16366+ struct au_sbinfo *sbi = au_sbi(inode->i_sb);
16367+ const struct inode_operations *iop
16368+ = force_getattr ? aufs_iop : sbi->si_iop_array;
16369+
16370+ if (inode->i_op == iop)
16371+ return;
16372+
16373+ switch (inode->i_mode & S_IFMT) {
16374+ case S_IFDIR:
16375+ type = AuIop_DIR;
16376+ break;
16377+ case S_IFLNK:
16378+ type = AuIop_SYMLINK;
16379+ break;
16380+ default:
16381+ type = AuIop_OTHER;
16382+ break;
16383+ }
16384+
16385+ inode->i_op = iop + type;
16386+ /* unnecessary smp_wmb() */
16387+}
16388+
027c5e7a
AM
16389+int au_refresh_hinode_self(struct inode *inode)
16390+{
16391+ int err, update;
16392+
16393+ err = au_ii_refresh(inode, &update);
16394+ if (!err)
16395+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
16396+
16397+ AuTraceErr(err);
4a4d8108
AM
16398+ return err;
16399+}
1facf9fc 16400+
4a4d8108
AM
16401+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
16402+{
027c5e7a 16403+ int err, e, update;
4a4d8108 16404+ unsigned int flags;
027c5e7a 16405+ umode_t mode;
5afbbe0d 16406+ aufs_bindex_t bindex, bbot;
027c5e7a 16407+ unsigned char isdir;
4a4d8108
AM
16408+ struct au_hinode *p;
16409+ struct au_iinfo *iinfo;
1facf9fc 16410+
027c5e7a 16411+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
16412+ if (unlikely(err))
16413+ goto out;
16414+
16415+ update = 0;
16416+ iinfo = au_ii(inode);
5afbbe0d 16417+ p = au_hinode(iinfo, iinfo->ii_btop);
027c5e7a
AM
16418+ mode = (inode->i_mode & S_IFMT);
16419+ isdir = S_ISDIR(mode);
4a4d8108 16420+ flags = au_hi_flags(inode, isdir);
5afbbe0d
AM
16421+ bbot = au_dbbot(dentry);
16422+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) {
5527c038 16423+ struct inode *h_i, *h_inode;
4a4d8108
AM
16424+ struct dentry *h_d;
16425+
16426+ h_d = au_h_dptr(dentry, bindex);
5527c038 16427+ if (!h_d || d_is_negative(h_d))
4a4d8108
AM
16428+ continue;
16429+
5527c038
JR
16430+ h_inode = d_inode(h_d);
16431+ AuDebugOn(mode != (h_inode->i_mode & S_IFMT));
5afbbe0d 16432+ if (iinfo->ii_btop <= bindex && bindex <= iinfo->ii_bbot) {
4a4d8108
AM
16433+ h_i = au_h_iptr(inode, bindex);
16434+ if (h_i) {
5527c038 16435+ if (h_i == h_inode)
4a4d8108
AM
16436+ continue;
16437+ err = -EIO;
16438+ break;
16439+ }
16440+ }
5afbbe0d
AM
16441+ if (bindex < iinfo->ii_btop)
16442+ iinfo->ii_btop = bindex;
16443+ if (iinfo->ii_bbot < bindex)
16444+ iinfo->ii_bbot = bindex;
5527c038 16445+ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags);
4a4d8108 16446+ update = 1;
1308ab2a 16447+ }
4a4d8108
AM
16448+ au_update_ibrange(inode, /*do_put_zero*/0);
16449+ e = au_dy_irefresh(inode);
16450+ if (unlikely(e && !err))
16451+ err = e;
027c5e7a
AM
16452+ if (!err)
16453+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 16454+
4f0767ce 16455+out:
4a4d8108 16456+ AuTraceErr(err);
1308ab2a 16457+ return err;
dece6358
AM
16458+}
16459+
4a4d8108 16460+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 16461+{
4a4d8108
AM
16462+ int err;
16463+ unsigned int flags;
16464+ umode_t mode;
5afbbe0d 16465+ aufs_bindex_t bindex, btop, btail;
4a4d8108
AM
16466+ unsigned char isdir;
16467+ struct dentry *h_dentry;
16468+ struct inode *h_inode;
16469+ struct au_iinfo *iinfo;
b95c5147 16470+ struct inode_operations *iop;
dece6358 16471+
4a4d8108 16472+ IiMustWriteLock(inode);
dece6358 16473+
4a4d8108
AM
16474+ err = 0;
16475+ isdir = 0;
b95c5147 16476+ iop = au_sbi(inode->i_sb)->si_iop_array;
5afbbe0d
AM
16477+ btop = au_dbtop(dentry);
16478+ h_dentry = au_h_dptr(dentry, btop);
5527c038 16479+ h_inode = d_inode(h_dentry);
4a4d8108
AM
16480+ mode = h_inode->i_mode;
16481+ switch (mode & S_IFMT) {
16482+ case S_IFREG:
16483+ btail = au_dbtail(dentry);
b95c5147 16484+ inode->i_op = iop + AuIop_OTHER;
4a4d8108 16485+ inode->i_fop = &aufs_file_fop;
5afbbe0d 16486+ err = au_dy_iaop(inode, btop, h_inode);
4a4d8108
AM
16487+ if (unlikely(err))
16488+ goto out;
16489+ break;
16490+ case S_IFDIR:
16491+ isdir = 1;
16492+ btail = au_dbtaildir(dentry);
b95c5147 16493+ inode->i_op = iop + AuIop_DIR;
4a4d8108
AM
16494+ inode->i_fop = &aufs_dir_fop;
16495+ break;
16496+ case S_IFLNK:
16497+ btail = au_dbtail(dentry);
b95c5147 16498+ inode->i_op = iop + AuIop_SYMLINK;
4a4d8108
AM
16499+ break;
16500+ case S_IFBLK:
16501+ case S_IFCHR:
16502+ case S_IFIFO:
16503+ case S_IFSOCK:
16504+ btail = au_dbtail(dentry);
b95c5147 16505+ inode->i_op = iop + AuIop_OTHER;
38d290e6 16506+ init_special_inode(inode, mode, h_inode->i_rdev);
4a4d8108
AM
16507+ break;
16508+ default:
16509+ AuIOErr("Unknown file type 0%o\n", mode);
16510+ err = -EIO;
1308ab2a 16511+ goto out;
4a4d8108 16512+ }
dece6358 16513+
4a4d8108
AM
16514+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
16515+ flags = au_hi_flags(inode, isdir);
16516+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
16517+ && au_ftest_hi(flags, HNOTIFY)
16518+ && dentry->d_name.len > AUFS_WH_PFX_LEN
16519+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
16520+ au_fclr_hi(flags, HNOTIFY);
16521+ iinfo = au_ii(inode);
5afbbe0d
AM
16522+ iinfo->ii_btop = btop;
16523+ iinfo->ii_bbot = btail;
16524+ for (bindex = btop; bindex <= btail; bindex++) {
4a4d8108
AM
16525+ h_dentry = au_h_dptr(dentry, bindex);
16526+ if (h_dentry)
16527+ au_set_h_iptr(inode, bindex,
5527c038 16528+ au_igrab(d_inode(h_dentry)), flags);
4a4d8108
AM
16529+ }
16530+ au_cpup_attr_all(inode, /*force*/1);
c1595e42
JR
16531+ /*
16532+ * to force calling aufs_get_acl() every time,
16533+ * do not call cache_no_acl() for aufs inode.
16534+ */
dece6358 16535+
4f0767ce 16536+out:
4a4d8108
AM
16537+ return err;
16538+}
dece6358 16539+
027c5e7a
AM
16540+/*
16541+ * successful returns with iinfo write_locked
16542+ * minus: errno
16543+ * zero: success, matched
16544+ * plus: no error, but unmatched
16545+ */
16546+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
16547+{
16548+ int err;
cfc41e69 16549+ unsigned int gen, igflags;
5afbbe0d 16550+ aufs_bindex_t bindex, bbot;
4a4d8108 16551+ struct inode *h_inode, *h_dinode;
5527c038 16552+ struct dentry *h_dentry;
dece6358 16553+
4a4d8108
AM
16554+ /*
16555+ * before this function, if aufs got any iinfo lock, it must be only
16556+ * one, the parent dir.
16557+ * it can happen by UDBA and the obsoleted inode number.
16558+ */
16559+ err = -EIO;
16560+ if (unlikely(inode->i_ino == parent_ino(dentry)))
16561+ goto out;
16562+
027c5e7a 16563+ err = 1;
4a4d8108 16564+ ii_write_lock_new_child(inode);
5afbbe0d 16565+ h_dentry = au_h_dptr(dentry, au_dbtop(dentry));
5527c038 16566+ h_dinode = d_inode(h_dentry);
5afbbe0d
AM
16567+ bbot = au_ibbot(inode);
16568+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) {
4a4d8108 16569+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
16570+ if (!h_inode || h_inode != h_dinode)
16571+ continue;
16572+
16573+ err = 0;
cfc41e69 16574+ gen = au_iigen(inode, &igflags);
537831f9 16575+ if (gen == au_digen(dentry)
cfc41e69 16576+ && !au_ig_ftest(igflags, HALF_REFRESHED))
4a4d8108 16577+ break;
537831f9
AM
16578+
16579+ /* fully refresh inode using dentry */
16580+ err = au_refresh_hinode(inode, dentry);
16581+ if (!err)
16582+ au_update_iigen(inode, /*half*/0);
16583+ break;
1facf9fc 16584+ }
dece6358 16585+
4a4d8108
AM
16586+ if (unlikely(err))
16587+ ii_write_unlock(inode);
4f0767ce 16588+out:
1facf9fc 16589+ return err;
16590+}
1facf9fc 16591+
4a4d8108
AM
16592+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
16593+ unsigned int d_type, ino_t *ino)
1facf9fc 16594+{
521ced18
JR
16595+ int err, idx;
16596+ const int isnondir = d_type != DT_DIR;
1facf9fc 16597+
b752ccd1 16598+ /* prevent hardlinked inode number from race condition */
521ced18
JR
16599+ if (isnondir) {
16600+ err = au_xinondir_enter(sb, bindex, h_ino, &idx);
16601+ if (unlikely(err))
16602+ goto out;
4a4d8108 16603+ }
521ced18 16604+
4a4d8108
AM
16605+ err = au_xino_read(sb, bindex, h_ino, ino);
16606+ if (unlikely(err))
521ced18 16607+ goto out_xinondir;
1308ab2a 16608+
4a4d8108
AM
16609+ if (!*ino) {
16610+ err = -EIO;
16611+ *ino = au_xino_new_ino(sb);
16612+ if (unlikely(!*ino))
521ced18 16613+ goto out_xinondir;
4a4d8108
AM
16614+ err = au_xino_write(sb, bindex, h_ino, *ino);
16615+ if (unlikely(err))
521ced18 16616+ goto out_xinondir;
1308ab2a 16617+ }
1facf9fc 16618+
521ced18
JR
16619+out_xinondir:
16620+ if (isnondir && idx >= 0)
16621+ au_xinondir_leave(sb, bindex, h_ino, idx);
4f0767ce 16622+out:
1facf9fc 16623+ return err;
16624+}
16625+
4a4d8108
AM
16626+/* successful returns with iinfo write_locked */
16627+/* todo: return with unlocked? */
16628+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 16629+{
5527c038 16630+ struct inode *inode, *h_inode;
4a4d8108
AM
16631+ struct dentry *h_dentry;
16632+ struct super_block *sb;
16633+ ino_t h_ino, ino;
521ced18 16634+ int err, idx, hlinked;
5afbbe0d 16635+ aufs_bindex_t btop;
1facf9fc 16636+
4a4d8108 16637+ sb = dentry->d_sb;
5afbbe0d
AM
16638+ btop = au_dbtop(dentry);
16639+ h_dentry = au_h_dptr(dentry, btop);
5527c038
JR
16640+ h_inode = d_inode(h_dentry);
16641+ h_ino = h_inode->i_ino;
521ced18 16642+ hlinked = !d_is_dir(h_dentry) && h_inode->i_nlink > 1;
b752ccd1 16643+
521ced18 16644+new_ino:
b752ccd1
AM
16645+ /*
16646+ * stop 'race'-ing between hardlinks under different
16647+ * parents.
16648+ */
521ced18
JR
16649+ if (hlinked) {
16650+ err = au_xinondir_enter(sb, btop, h_ino, &idx);
16651+ inode = ERR_PTR(err);
16652+ if (unlikely(err))
16653+ goto out;
16654+ }
b752ccd1 16655+
5afbbe0d 16656+ err = au_xino_read(sb, btop, h_ino, &ino);
4a4d8108
AM
16657+ inode = ERR_PTR(err);
16658+ if (unlikely(err))
521ced18 16659+ goto out_xinondir;
b752ccd1 16660+
4a4d8108
AM
16661+ if (!ino) {
16662+ ino = au_xino_new_ino(sb);
16663+ if (unlikely(!ino)) {
16664+ inode = ERR_PTR(-EIO);
521ced18 16665+ goto out_xinondir;
dece6358
AM
16666+ }
16667+ }
1facf9fc 16668+
4a4d8108
AM
16669+ AuDbg("i%lu\n", (unsigned long)ino);
16670+ inode = au_iget_locked(sb, ino);
16671+ err = PTR_ERR(inode);
16672+ if (IS_ERR(inode))
521ced18 16673+ goto out_xinondir;
1facf9fc 16674+
4a4d8108
AM
16675+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
16676+ if (inode->i_state & I_NEW) {
16677+ ii_write_lock_new_child(inode);
16678+ err = set_inode(inode, dentry);
16679+ if (!err) {
16680+ unlock_new_inode(inode);
521ced18 16681+ goto out_xinondir; /* success */
4a4d8108 16682+ }
1308ab2a 16683+
027c5e7a
AM
16684+ /*
16685+ * iget_failed() calls iput(), but we need to call
16686+ * ii_write_unlock() after iget_failed(). so dirty hack for
16687+ * i_count.
16688+ */
16689+ atomic_inc(&inode->i_count);
4a4d8108 16690+ iget_failed(inode);
027c5e7a 16691+ ii_write_unlock(inode);
5afbbe0d 16692+ au_xino_write(sb, btop, h_ino, /*ino*/0);
027c5e7a
AM
16693+ /* ignore this error */
16694+ goto out_iput;
16695+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
16696+ /*
16697+ * horrible race condition between lookup, readdir and copyup
16698+ * (or something).
16699+ */
521ced18
JR
16700+ if (hlinked && idx >= 0)
16701+ au_xinondir_leave(sb, btop, h_ino, idx);
027c5e7a
AM
16702+ err = reval_inode(inode, dentry);
16703+ if (unlikely(err < 0)) {
521ced18 16704+ hlinked = 0;
027c5e7a
AM
16705+ goto out_iput;
16706+ }
521ced18 16707+ if (!err)
4a4d8108 16708+ goto out; /* success */
521ced18
JR
16709+ else if (hlinked && idx >= 0) {
16710+ err = au_xinondir_enter(sb, btop, h_ino, &idx);
16711+ if (unlikely(err)) {
16712+ iput(inode);
16713+ inode = ERR_PTR(err);
16714+ goto out;
16715+ }
16716+ }
4a4d8108
AM
16717+ }
16718+
5527c038 16719+ if (unlikely(au_test_fs_unique_ino(h_inode)))
4a4d8108 16720+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3 16721+ " b%d, %s, %pd, hi%lu, i%lu.\n",
5afbbe0d 16722+ btop, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
16723+ (unsigned long)h_ino, (unsigned long)ino);
16724+ ino = 0;
5afbbe0d 16725+ err = au_xino_write(sb, btop, h_ino, /*ino*/0);
4a4d8108
AM
16726+ if (!err) {
16727+ iput(inode);
521ced18
JR
16728+ if (hlinked && idx >= 0)
16729+ au_xinondir_leave(sb, btop, h_ino, idx);
4a4d8108
AM
16730+ goto new_ino;
16731+ }
1308ab2a 16732+
4f0767ce 16733+out_iput:
4a4d8108 16734+ iput(inode);
4a4d8108 16735+ inode = ERR_PTR(err);
521ced18
JR
16736+out_xinondir:
16737+ if (hlinked && idx >= 0)
16738+ au_xinondir_leave(sb, btop, h_ino, idx);
4f0767ce 16739+out:
4a4d8108 16740+ return inode;
1facf9fc 16741+}
16742+
4a4d8108 16743+/* ---------------------------------------------------------------------- */
1facf9fc 16744+
4a4d8108
AM
16745+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16746+ struct inode *inode)
16747+{
16748+ int err;
076b876e 16749+ struct inode *hi;
1facf9fc 16750+
4a4d8108 16751+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 16752+
4a4d8108
AM
16753+ /* pseudo-link after flushed may happen out of bounds */
16754+ if (!err
16755+ && inode
5afbbe0d
AM
16756+ && au_ibtop(inode) <= bindex
16757+ && bindex <= au_ibbot(inode)) {
4a4d8108
AM
16758+ /*
16759+ * permission check is unnecessary since vfsub routine
16760+ * will be called later
16761+ */
076b876e 16762+ hi = au_h_iptr(inode, bindex);
4a4d8108
AM
16763+ if (hi)
16764+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 16765+ }
16766+
4a4d8108
AM
16767+ return err;
16768+}
dece6358 16769+
4a4d8108
AM
16770+int au_test_h_perm(struct inode *h_inode, int mask)
16771+{
2dfbb274 16772+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
16773+ return 0;
16774+ return inode_permission(h_inode, mask);
16775+}
1facf9fc 16776+
4a4d8108
AM
16777+int au_test_h_perm_sio(struct inode *h_inode, int mask)
16778+{
16779+ if (au_test_nfs(h_inode->i_sb)
16780+ && (mask & MAY_WRITE)
16781+ && S_ISDIR(h_inode->i_mode))
16782+ mask |= MAY_READ; /* force permission check */
16783+ return au_test_h_perm(h_inode, mask);
1facf9fc 16784+}
7f207e10
AM
16785diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
16786--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
3c1bdaff
AM
16787+++ linux/fs/aufs/inode.h 2017-09-05 10:42:11.058755349 +0200
16788@@ -0,0 +1,694 @@
4a4d8108 16789+/*
a2654f78 16790+ * Copyright (C) 2005-2017 Junjiro R. Okajima
4a4d8108
AM
16791+ *
16792+ * This program, aufs is free software; you can redistribute it and/or modify
16793+ * it under the terms of the GNU General Public License as published by
16794+ * the Free Software Foundation; either version 2 of the License, or
16795+ * (at your option) any later version.
16796+ *
16797+ * This program is distributed in the hope that it will be useful,
16798+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16799+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16800+ * GNU General Public License for more details.
16801+ *
16802+ * You should have received a copy of the GNU General Public License
523b37e3 16803+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 16804+ */
1facf9fc 16805+
1308ab2a 16806+/*
4a4d8108 16807+ * inode operations
1308ab2a 16808+ */
dece6358 16809+
4a4d8108
AM
16810+#ifndef __AUFS_INODE_H__
16811+#define __AUFS_INODE_H__
dece6358 16812+
4a4d8108 16813+#ifdef __KERNEL__
1308ab2a 16814+
4a4d8108 16815+#include <linux/fsnotify.h>
4a4d8108 16816+#include "rwsem.h"
3c1bdaff 16817+#include "vfsub.h"
1308ab2a 16818+
4a4d8108 16819+struct vfsmount;
1facf9fc 16820+
4a4d8108
AM
16821+struct au_hnotify {
16822+#ifdef CONFIG_AUFS_HNOTIFY
16823+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 16824+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 16825+ struct fsnotify_mark hn_mark;
4a4d8108 16826+#endif
1c60b727 16827+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
16828+#endif
16829+} ____cacheline_aligned_in_smp;
1facf9fc 16830+
4a4d8108
AM
16831+struct au_hinode {
16832+ struct inode *hi_inode;
16833+ aufs_bindex_t hi_id;
16834+#ifdef CONFIG_AUFS_HNOTIFY
16835+ struct au_hnotify *hi_notify;
16836+#endif
dece6358 16837+
4a4d8108
AM
16838+ /* reference to the copied-up whiteout with get/put */
16839+ struct dentry *hi_whdentry;
16840+};
dece6358 16841+
537831f9
AM
16842+/* ig_flags */
16843+#define AuIG_HALF_REFRESHED 1
16844+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
16845+#define au_ig_fset(flags, name) \
16846+ do { (flags) |= AuIG_##name; } while (0)
16847+#define au_ig_fclr(flags, name) \
16848+ do { (flags) &= ~AuIG_##name; } while (0)
16849+
16850+struct au_iigen {
be52b249 16851+ spinlock_t ig_spin;
537831f9
AM
16852+ __u32 ig_generation, ig_flags;
16853+};
16854+
4a4d8108
AM
16855+struct au_vdir;
16856+struct au_iinfo {
7a9e40b8 16857+ struct au_iigen ii_generation;
4a4d8108 16858+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 16859+
4a4d8108 16860+ struct au_rwsem ii_rwsem;
5afbbe0d 16861+ aufs_bindex_t ii_btop, ii_bbot;
4a4d8108
AM
16862+ __u32 ii_higen;
16863+ struct au_hinode *ii_hinode;
16864+ struct au_vdir *ii_vdir;
16865+};
1facf9fc 16866+
4a4d8108
AM
16867+struct au_icntnr {
16868+ struct au_iinfo iinfo;
16869+ struct inode vfs_inode;
1c60b727 16870+ struct hlist_node plink;
4a4d8108 16871+} ____cacheline_aligned_in_smp;
1308ab2a 16872+
4a4d8108
AM
16873+/* au_pin flags */
16874+#define AuPin_DI_LOCKED 1
16875+#define AuPin_MNT_WRITE (1 << 1)
16876+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
16877+#define au_fset_pin(flags, name) \
16878+ do { (flags) |= AuPin_##name; } while (0)
16879+#define au_fclr_pin(flags, name) \
16880+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
16881+
16882+struct au_pin {
16883+ /* input */
16884+ struct dentry *dentry;
16885+ unsigned int udba;
16886+ unsigned char lsc_di, lsc_hi, flags;
16887+ aufs_bindex_t bindex;
16888+
16889+ /* output */
16890+ struct dentry *parent;
16891+ struct au_hinode *hdir;
16892+ struct vfsmount *h_mnt;
86dc4139
AM
16893+
16894+ /* temporary unlock/relock for copyup */
16895+ struct dentry *h_dentry, *h_parent;
16896+ struct au_branch *br;
16897+ struct task_struct *task;
4a4d8108 16898+};
1facf9fc 16899+
86dc4139 16900+void au_pin_hdir_unlock(struct au_pin *p);
c1595e42 16901+int au_pin_hdir_lock(struct au_pin *p);
86dc4139 16902+int au_pin_hdir_relock(struct au_pin *p);
86dc4139
AM
16903+void au_pin_hdir_acquire_nest(struct au_pin *p);
16904+void au_pin_hdir_release(struct au_pin *p);
16905+
1308ab2a 16906+/* ---------------------------------------------------------------------- */
16907+
4a4d8108 16908+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 16909+{
5afbbe0d
AM
16910+ BUG_ON(is_bad_inode(inode));
16911+ return &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
4a4d8108 16912+}
1facf9fc 16913+
4a4d8108 16914+/* ---------------------------------------------------------------------- */
1facf9fc 16915+
4a4d8108
AM
16916+/* inode.c */
16917+struct inode *au_igrab(struct inode *inode);
b95c5147 16918+void au_refresh_iop(struct inode *inode, int force_getattr);
027c5e7a 16919+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
16920+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
16921+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
16922+ unsigned int d_type, ino_t *ino);
16923+struct inode *au_new_inode(struct dentry *dentry, int must_new);
16924+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16925+ struct inode *inode);
16926+int au_test_h_perm(struct inode *h_inode, int mask);
16927+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 16928+
4a4d8108
AM
16929+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
16930+ ino_t h_ino, unsigned int d_type, ino_t *ino)
16931+{
16932+#ifdef CONFIG_AUFS_SHWH
16933+ return au_ino(sb, bindex, h_ino, d_type, ino);
16934+#else
16935+ return 0;
16936+#endif
16937+}
1facf9fc 16938+
4a4d8108 16939+/* i_op.c */
b95c5147
AM
16940+enum {
16941+ AuIop_SYMLINK,
16942+ AuIop_DIR,
16943+ AuIop_OTHER,
16944+ AuIop_Last
16945+};
16946+extern struct inode_operations aufs_iop[AuIop_Last],
16947+ aufs_iop_nogetattr[AuIop_Last];
1308ab2a 16948+
4a4d8108
AM
16949+/* au_wr_dir flags */
16950+#define AuWrDir_ADD_ENTRY 1
7e9cd9fe
AM
16951+#define AuWrDir_ISDIR (1 << 1)
16952+#define AuWrDir_TMPFILE (1 << 2)
4a4d8108 16953+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
16954+#define au_fset_wrdir(flags, name) \
16955+ do { (flags) |= AuWrDir_##name; } while (0)
16956+#define au_fclr_wrdir(flags, name) \
16957+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 16958+
4a4d8108
AM
16959+struct au_wr_dir_args {
16960+ aufs_bindex_t force_btgt;
16961+ unsigned char flags;
16962+};
16963+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16964+ struct au_wr_dir_args *args);
dece6358 16965+
4a4d8108
AM
16966+struct dentry *au_pinned_h_parent(struct au_pin *pin);
16967+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
16968+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
16969+ unsigned int udba, unsigned char flags);
16970+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
16971+ unsigned int udba, unsigned char flags) __must_check;
16972+int au_do_pin(struct au_pin *pin) __must_check;
16973+void au_unpin(struct au_pin *pin);
c1595e42
JR
16974+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
16975+
16976+#define AuIcpup_DID_CPUP 1
16977+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
16978+#define au_fset_icpup(flags, name) \
16979+ do { (flags) |= AuIcpup_##name; } while (0)
16980+#define au_fclr_icpup(flags, name) \
16981+ do { (flags) &= ~AuIcpup_##name; } while (0)
16982+
16983+struct au_icpup_args {
16984+ unsigned char flags;
16985+ unsigned char pin_flags;
16986+ aufs_bindex_t btgt;
16987+ unsigned int udba;
16988+ struct au_pin pin;
16989+ struct path h_path;
16990+ struct inode *h_inode;
16991+};
16992+
16993+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
16994+ struct au_icpup_args *a);
16995+
a2654f78
AM
16996+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
16997+ int locked);
1facf9fc 16998+
4a4d8108
AM
16999+/* i_op_add.c */
17000+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
17001+ struct dentry *h_parent, int isdir);
7eafdf33
AM
17002+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
17003+ dev_t dev);
4a4d8108 17004+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 17005+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 17006+ bool want_excl);
b912730e
AM
17007+struct vfsub_aopen_args;
17008+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
17009+ struct vfsub_aopen_args *args);
38d290e6 17010+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
4a4d8108
AM
17011+int aufs_link(struct dentry *src_dentry, struct inode *dir,
17012+ struct dentry *dentry);
7eafdf33 17013+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 17014+
4a4d8108
AM
17015+/* i_op_del.c */
17016+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
17017+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
17018+ struct dentry *h_parent, int isdir);
17019+int aufs_unlink(struct inode *dir, struct dentry *dentry);
17020+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 17021+
4a4d8108
AM
17022+/* i_op_ren.c */
17023+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
17024+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
f2c43d5f
AM
17025+ struct inode *dir, struct dentry *dentry,
17026+ unsigned int flags);
1facf9fc 17027+
4a4d8108
AM
17028+/* iinfo.c */
17029+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
17030+void au_hiput(struct au_hinode *hinode);
17031+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
17032+ struct dentry *h_wh);
17033+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 17034+
4a4d8108
AM
17035+/* hinode flags */
17036+#define AuHi_XINO 1
17037+#define AuHi_HNOTIFY (1 << 1)
17038+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
17039+#define au_fset_hi(flags, name) \
17040+ do { (flags) |= AuHi_##name; } while (0)
17041+#define au_fclr_hi(flags, name) \
17042+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 17043+
4a4d8108
AM
17044+#ifndef CONFIG_AUFS_HNOTIFY
17045+#undef AuHi_HNOTIFY
17046+#define AuHi_HNOTIFY 0
17047+#endif
1facf9fc 17048+
4a4d8108
AM
17049+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
17050+ struct inode *h_inode, unsigned int flags);
1facf9fc 17051+
537831f9 17052+void au_update_iigen(struct inode *inode, int half);
4a4d8108 17053+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 17054+
4a4d8108 17055+void au_icntnr_init_once(void *_c);
5afbbe0d 17056+void au_hinode_init(struct au_hinode *hinode);
4a4d8108
AM
17057+int au_iinfo_init(struct inode *inode);
17058+void au_iinfo_fin(struct inode *inode);
e2f27e51 17059+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink);
1308ab2a 17060+
e49829fe 17061+#ifdef CONFIG_PROC_FS
4a4d8108 17062+/* plink.c */
e49829fe 17063+int au_plink_maint(struct super_block *sb, int flags);
7e9cd9fe 17064+struct au_sbinfo;
e49829fe
JR
17065+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
17066+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
17067+#ifdef CONFIG_AUFS_DEBUG
17068+void au_plink_list(struct super_block *sb);
17069+#else
17070+AuStubVoid(au_plink_list, struct super_block *sb)
17071+#endif
17072+int au_plink_test(struct inode *inode);
17073+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
17074+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
17075+ struct dentry *h_dentry);
e49829fe
JR
17076+void au_plink_put(struct super_block *sb, int verbose);
17077+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 17078+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
17079+#else
17080+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
17081+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
17082+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
17083+AuStubVoid(au_plink_list, struct super_block *sb);
17084+AuStubInt0(au_plink_test, struct inode *inode);
17085+AuStub(struct dentry *, au_plink_lkup, return NULL,
17086+ struct inode *inode, aufs_bindex_t bindex);
17087+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
17088+ struct dentry *h_dentry);
17089+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
17090+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
17091+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
17092+#endif /* CONFIG_PROC_FS */
1facf9fc 17093+
c1595e42
JR
17094+#ifdef CONFIG_AUFS_XATTR
17095+/* xattr.c */
7e9cd9fe
AM
17096+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
17097+ unsigned int verbose);
c1595e42 17098+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
f2c43d5f 17099+void au_xattr_init(struct super_block *sb);
c1595e42
JR
17100+#else
17101+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe 17102+ int ignore_flags, unsigned int verbose);
f2c43d5f 17103+AuStubVoid(au_xattr_init, struct super_block *sb);
c1595e42
JR
17104+#endif
17105+
17106+#ifdef CONFIG_FS_POSIX_ACL
17107+struct posix_acl *aufs_get_acl(struct inode *inode, int type);
17108+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
17109+#endif
17110+
17111+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
17112+enum {
17113+ AU_XATTR_SET,
c1595e42
JR
17114+ AU_ACL_SET
17115+};
17116+
f2c43d5f 17117+struct au_sxattr {
c1595e42
JR
17118+ int type;
17119+ union {
17120+ struct {
17121+ const char *name;
17122+ const void *value;
17123+ size_t size;
17124+ int flags;
17125+ } set;
17126+ struct {
c1595e42
JR
17127+ struct posix_acl *acl;
17128+ int type;
17129+ } acl_set;
17130+ } u;
17131+};
f2c43d5f
AM
17132+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
17133+ struct au_sxattr *arg);
c1595e42
JR
17134+#endif
17135+
4a4d8108 17136+/* ---------------------------------------------------------------------- */
1308ab2a 17137+
4a4d8108
AM
17138+/* lock subclass for iinfo */
17139+enum {
17140+ AuLsc_II_CHILD, /* child first */
17141+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
17142+ AuLsc_II_CHILD3, /* copyup dirs */
17143+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
17144+ AuLsc_II_PARENT2,
17145+ AuLsc_II_PARENT3, /* copyup dirs */
17146+ AuLsc_II_NEW_CHILD
17147+};
1308ab2a 17148+
1facf9fc 17149+/*
4a4d8108
AM
17150+ * ii_read_lock_child, ii_write_lock_child,
17151+ * ii_read_lock_child2, ii_write_lock_child2,
17152+ * ii_read_lock_child3, ii_write_lock_child3,
17153+ * ii_read_lock_parent, ii_write_lock_parent,
17154+ * ii_read_lock_parent2, ii_write_lock_parent2,
17155+ * ii_read_lock_parent3, ii_write_lock_parent3,
17156+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 17157+ */
4a4d8108
AM
17158+#define AuReadLockFunc(name, lsc) \
17159+static inline void ii_read_lock_##name(struct inode *i) \
17160+{ \
17161+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
17162+}
17163+
17164+#define AuWriteLockFunc(name, lsc) \
17165+static inline void ii_write_lock_##name(struct inode *i) \
17166+{ \
17167+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
17168+}
17169+
17170+#define AuRWLockFuncs(name, lsc) \
17171+ AuReadLockFunc(name, lsc) \
17172+ AuWriteLockFunc(name, lsc)
17173+
17174+AuRWLockFuncs(child, CHILD);
17175+AuRWLockFuncs(child2, CHILD2);
17176+AuRWLockFuncs(child3, CHILD3);
17177+AuRWLockFuncs(parent, PARENT);
17178+AuRWLockFuncs(parent2, PARENT2);
17179+AuRWLockFuncs(parent3, PARENT3);
17180+AuRWLockFuncs(new_child, NEW_CHILD);
17181+
17182+#undef AuReadLockFunc
17183+#undef AuWriteLockFunc
17184+#undef AuRWLockFuncs
1facf9fc 17185+
17186+/*
4a4d8108 17187+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 17188+ */
4a4d8108 17189+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 17190+
4a4d8108
AM
17191+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
17192+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
17193+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 17194+
4a4d8108 17195+/* ---------------------------------------------------------------------- */
1308ab2a 17196+
027c5e7a
AM
17197+static inline void au_icntnr_init(struct au_icntnr *c)
17198+{
17199+#ifdef CONFIG_AUFS_DEBUG
17200+ c->vfs_inode.i_mode = 0;
17201+#endif
17202+}
17203+
cfc41e69 17204+static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags)
4a4d8108 17205+{
537831f9
AM
17206+ unsigned int gen;
17207+ struct au_iinfo *iinfo;
be52b249 17208+ struct au_iigen *iigen;
537831f9
AM
17209+
17210+ iinfo = au_ii(inode);
be52b249
AM
17211+ iigen = &iinfo->ii_generation;
17212+ spin_lock(&iigen->ig_spin);
cfc41e69
AM
17213+ if (igflags)
17214+ *igflags = iigen->ig_flags;
be52b249
AM
17215+ gen = iigen->ig_generation;
17216+ spin_unlock(&iigen->ig_spin);
537831f9
AM
17217+
17218+ return gen;
4a4d8108 17219+}
1308ab2a 17220+
4a4d8108
AM
17221+/* tiny test for inode number */
17222+/* tmpfs generation is too rough */
17223+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
17224+{
17225+ struct au_iinfo *iinfo;
1308ab2a 17226+
4a4d8108
AM
17227+ iinfo = au_ii(inode);
17228+ AuRwMustAnyLock(&iinfo->ii_rwsem);
17229+ return !(iinfo->ii_hsb1 == h_inode->i_sb
17230+ && iinfo->ii_higen == h_inode->i_generation);
17231+}
1308ab2a 17232+
4a4d8108
AM
17233+static inline void au_iigen_dec(struct inode *inode)
17234+{
537831f9 17235+ struct au_iinfo *iinfo;
be52b249 17236+ struct au_iigen *iigen;
537831f9
AM
17237+
17238+ iinfo = au_ii(inode);
be52b249
AM
17239+ iigen = &iinfo->ii_generation;
17240+ spin_lock(&iigen->ig_spin);
17241+ iigen->ig_generation--;
17242+ spin_unlock(&iigen->ig_spin);
027c5e7a
AM
17243+}
17244+
17245+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
17246+{
17247+ int err;
17248+
17249+ err = 0;
537831f9 17250+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
17251+ err = -EIO;
17252+
17253+ return err;
4a4d8108 17254+}
1308ab2a 17255+
4a4d8108 17256+/* ---------------------------------------------------------------------- */
1308ab2a 17257+
5afbbe0d
AM
17258+static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo,
17259+ aufs_bindex_t bindex)
17260+{
17261+ return iinfo->ii_hinode + bindex;
17262+}
17263+
17264+static inline int au_is_bad_inode(struct inode *inode)
17265+{
17266+ return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0));
17267+}
17268+
4a4d8108
AM
17269+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
17270+ aufs_bindex_t bindex)
17271+{
17272+ IiMustAnyLock(inode);
5afbbe0d 17273+ return au_hinode(au_ii(inode), bindex)->hi_id;
4a4d8108 17274+}
1308ab2a 17275+
5afbbe0d 17276+static inline aufs_bindex_t au_ibtop(struct inode *inode)
4a4d8108
AM
17277+{
17278+ IiMustAnyLock(inode);
5afbbe0d 17279+ return au_ii(inode)->ii_btop;
4a4d8108 17280+}
1308ab2a 17281+
5afbbe0d 17282+static inline aufs_bindex_t au_ibbot(struct inode *inode)
4a4d8108
AM
17283+{
17284+ IiMustAnyLock(inode);
5afbbe0d 17285+ return au_ii(inode)->ii_bbot;
4a4d8108 17286+}
1308ab2a 17287+
4a4d8108
AM
17288+static inline struct au_vdir *au_ivdir(struct inode *inode)
17289+{
17290+ IiMustAnyLock(inode);
17291+ return au_ii(inode)->ii_vdir;
17292+}
1308ab2a 17293+
4a4d8108
AM
17294+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
17295+{
17296+ IiMustAnyLock(inode);
5afbbe0d 17297+ return au_hinode(au_ii(inode), bindex)->hi_whdentry;
4a4d8108 17298+}
1308ab2a 17299+
5afbbe0d 17300+static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 17301+{
4a4d8108 17302+ IiMustWriteLock(inode);
5afbbe0d 17303+ au_ii(inode)->ii_btop = bindex;
4a4d8108 17304+}
1308ab2a 17305+
5afbbe0d 17306+static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex)
4a4d8108
AM
17307+{
17308+ IiMustWriteLock(inode);
5afbbe0d 17309+ au_ii(inode)->ii_bbot = bindex;
1308ab2a 17310+}
17311+
4a4d8108
AM
17312+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
17313+{
17314+ IiMustWriteLock(inode);
17315+ au_ii(inode)->ii_vdir = vdir;
17316+}
1facf9fc 17317+
4a4d8108 17318+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 17319+{
4a4d8108 17320+ IiMustAnyLock(inode);
5afbbe0d 17321+ return au_hinode(au_ii(inode), bindex);
4a4d8108 17322+}
dece6358 17323+
4a4d8108 17324+/* ---------------------------------------------------------------------- */
1facf9fc 17325+
4a4d8108
AM
17326+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
17327+{
17328+ if (pin)
17329+ return pin->parent;
17330+ return NULL;
1facf9fc 17331+}
17332+
4a4d8108 17333+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 17334+{
4a4d8108
AM
17335+ if (pin && pin->hdir)
17336+ return pin->hdir->hi_inode;
17337+ return NULL;
1308ab2a 17338+}
1facf9fc 17339+
4a4d8108
AM
17340+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
17341+{
17342+ if (pin)
17343+ return pin->hdir;
17344+ return NULL;
17345+}
1facf9fc 17346+
4a4d8108 17347+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 17348+{
4a4d8108
AM
17349+ if (pin)
17350+ pin->dentry = dentry;
17351+}
1308ab2a 17352+
4a4d8108
AM
17353+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
17354+ unsigned char lflag)
17355+{
17356+ if (pin) {
7f207e10 17357+ if (lflag)
4a4d8108 17358+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 17359+ else
4a4d8108 17360+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 17361+ }
4a4d8108
AM
17362+}
17363+
7e9cd9fe 17364+#if 0 /* reserved */
4a4d8108
AM
17365+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
17366+{
17367+ if (pin) {
17368+ dput(pin->parent);
17369+ pin->parent = dget(parent);
1facf9fc 17370+ }
4a4d8108 17371+}
7e9cd9fe 17372+#endif
1facf9fc 17373+
4a4d8108
AM
17374+/* ---------------------------------------------------------------------- */
17375+
027c5e7a 17376+struct au_branch;
4a4d8108
AM
17377+#ifdef CONFIG_AUFS_HNOTIFY
17378+struct au_hnotify_op {
17379+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 17380+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
17381+
17382+ /*
17383+ * if it returns true, the the caller should free hinode->hi_notify,
17384+ * otherwise ->free() frees it.
17385+ */
17386+ int (*free)(struct au_hinode *hinode,
17387+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
17388+
17389+ void (*fin)(void);
17390+ int (*init)(void);
027c5e7a
AM
17391+
17392+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
17393+ void (*fin_br)(struct au_branch *br);
17394+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
17395+};
17396+
17397+/* hnotify.c */
027c5e7a 17398+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
17399+void au_hn_free(struct au_hinode *hinode);
17400+void au_hn_ctl(struct au_hinode *hinode, int do_set);
17401+void au_hn_reset(struct inode *inode, unsigned int flags);
17402+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
17403+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
17404+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
17405+int au_hnotify_init_br(struct au_branch *br, int perm);
17406+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
17407+int __init au_hnotify_init(void);
17408+void au_hnotify_fin(void);
17409+
7f207e10 17410+/* hfsnotify.c */
4a4d8108
AM
17411+extern const struct au_hnotify_op au_hnotify_op;
17412+
17413+static inline
17414+void au_hn_init(struct au_hinode *hinode)
17415+{
17416+ hinode->hi_notify = NULL;
1308ab2a 17417+}
17418+
53392da6
AM
17419+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
17420+{
17421+ return hinode->hi_notify;
17422+}
17423+
4a4d8108 17424+#else
c1595e42
JR
17425+AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
17426+ struct au_hinode *hinode __maybe_unused,
17427+ struct inode *inode __maybe_unused)
17428+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
4a4d8108
AM
17429+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
17430+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
17431+ int do_set __maybe_unused)
17432+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
17433+ unsigned int flags __maybe_unused)
027c5e7a
AM
17434+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
17435+ struct au_branch *br __maybe_unused,
17436+ int perm __maybe_unused)
17437+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
17438+ int perm __maybe_unused)
17439+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
17440+AuStubInt0(__init au_hnotify_init, void)
17441+AuStubVoid(au_hnotify_fin, void)
17442+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
17443+#endif /* CONFIG_AUFS_HNOTIFY */
17444+
17445+static inline void au_hn_suspend(struct au_hinode *hdir)
17446+{
17447+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 17448+}
17449+
4a4d8108 17450+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 17451+{
4a4d8108
AM
17452+ au_hn_ctl(hdir, /*do_set*/1);
17453+}
1308ab2a 17454+
5afbbe0d 17455+static inline void au_hn_inode_lock(struct au_hinode *hdir)
4a4d8108 17456+{
febd17d6 17457+ inode_lock(hdir->hi_inode);
4a4d8108
AM
17458+ au_hn_suspend(hdir);
17459+}
dece6358 17460+
5afbbe0d 17461+static inline void au_hn_inode_lock_nested(struct au_hinode *hdir,
4a4d8108
AM
17462+ unsigned int sc __maybe_unused)
17463+{
febd17d6 17464+ inode_lock_nested(hdir->hi_inode, sc);
4a4d8108 17465+ au_hn_suspend(hdir);
1facf9fc 17466+}
1facf9fc 17467+
3c1bdaff
AM
17468+static inline void au_hn_inode_lock_shared_nested(struct au_hinode *hdir,
17469+ unsigned int sc)
17470+{
17471+ vfsub_inode_lock_shared_nested(hdir->hi_inode, sc);
17472+ au_hn_suspend(hdir);
17473+}
17474+
5afbbe0d 17475+static inline void au_hn_inode_unlock(struct au_hinode *hdir)
4a4d8108
AM
17476+{
17477+ au_hn_resume(hdir);
febd17d6 17478+ inode_unlock(hdir->hi_inode);
4a4d8108
AM
17479+}
17480+
17481+#endif /* __KERNEL__ */
17482+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
17483diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
17484--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 17485+++ linux/fs/aufs/ioctl.c 2017-07-29 12:14:25.903042072 +0200
c1595e42 17486@@ -0,0 +1,219 @@
4a4d8108 17487+/*
a2654f78 17488+ * Copyright (C) 2005-2017 Junjiro R. Okajima
4a4d8108
AM
17489+ *
17490+ * This program, aufs is free software; you can redistribute it and/or modify
17491+ * it under the terms of the GNU General Public License as published by
17492+ * the Free Software Foundation; either version 2 of the License, or
17493+ * (at your option) any later version.
17494+ *
17495+ * This program is distributed in the hope that it will be useful,
17496+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17497+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17498+ * GNU General Public License for more details.
17499+ *
17500+ * You should have received a copy of the GNU General Public License
523b37e3 17501+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
17502+ */
17503+
17504+/*
17505+ * ioctl
17506+ * plink-management and readdir in userspace.
17507+ * assist the pathconf(3) wrapper library.
c2b27bf2 17508+ * move-down
076b876e 17509+ * File-based Hierarchical Storage Management.
4a4d8108
AM
17510+ */
17511+
c2b27bf2
AM
17512+#include <linux/compat.h>
17513+#include <linux/file.h>
4a4d8108
AM
17514+#include "aufs.h"
17515+
1e00d052 17516+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
17517+{
17518+ int err, fd;
5afbbe0d 17519+ aufs_bindex_t wbi, bindex, bbot;
4a4d8108
AM
17520+ struct file *h_file;
17521+ struct super_block *sb;
17522+ struct dentry *root;
1e00d052
AM
17523+ struct au_branch *br;
17524+ struct aufs_wbr_fd wbrfd = {
17525+ .oflags = au_dir_roflags,
17526+ .brid = -1
17527+ };
17528+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
17529+ | O_NOATIME | O_CLOEXEC;
4a4d8108 17530+
1e00d052
AM
17531+ AuDebugOn(wbrfd.oflags & ~valid);
17532+
17533+ if (arg) {
17534+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
17535+ if (unlikely(err)) {
17536+ err = -EFAULT;
17537+ goto out;
17538+ }
17539+
17540+ err = -EINVAL;
17541+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
17542+ wbrfd.oflags |= au_dir_roflags;
17543+ AuDbg("0%o\n", wbrfd.oflags);
17544+ if (unlikely(wbrfd.oflags & ~valid))
17545+ goto out;
17546+ }
17547+
2000de60 17548+ fd = get_unused_fd_flags(0);
1e00d052
AM
17549+ err = fd;
17550+ if (unlikely(fd < 0))
4a4d8108 17551+ goto out;
4a4d8108 17552+
1e00d052 17553+ h_file = ERR_PTR(-EINVAL);
4a4d8108 17554+ wbi = 0;
1e00d052 17555+ br = NULL;
4a4d8108
AM
17556+ sb = path->dentry->d_sb;
17557+ root = sb->s_root;
17558+ aufs_read_lock(root, AuLock_IR);
5afbbe0d 17559+ bbot = au_sbbot(sb);
1e00d052
AM
17560+ if (wbrfd.brid >= 0) {
17561+ wbi = au_br_index(sb, wbrfd.brid);
5afbbe0d 17562+ if (unlikely(wbi < 0 || wbi > bbot))
1e00d052
AM
17563+ goto out_unlock;
17564+ }
17565+
17566+ h_file = ERR_PTR(-ENOENT);
17567+ br = au_sbr(sb, wbi);
17568+ if (!au_br_writable(br->br_perm)) {
17569+ if (arg)
17570+ goto out_unlock;
17571+
17572+ bindex = wbi + 1;
17573+ wbi = -1;
5afbbe0d 17574+ for (; bindex <= bbot; bindex++) {
1e00d052
AM
17575+ br = au_sbr(sb, bindex);
17576+ if (au_br_writable(br->br_perm)) {
4a4d8108 17577+ wbi = bindex;
1e00d052 17578+ br = au_sbr(sb, wbi);
4a4d8108
AM
17579+ break;
17580+ }
17581+ }
4a4d8108
AM
17582+ }
17583+ AuDbg("wbi %d\n", wbi);
1e00d052 17584+ if (wbi >= 0)
392086de
AM
17585+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
17586+ /*force_wr*/0);
1e00d052
AM
17587+
17588+out_unlock:
4a4d8108
AM
17589+ aufs_read_unlock(root, AuLock_IR);
17590+ err = PTR_ERR(h_file);
17591+ if (IS_ERR(h_file))
17592+ goto out_fd;
17593+
5afbbe0d 17594+ au_br_put(br); /* cf. au_h_open() */
4a4d8108
AM
17595+ fd_install(fd, h_file);
17596+ err = fd;
17597+ goto out; /* success */
17598+
4f0767ce 17599+out_fd:
4a4d8108 17600+ put_unused_fd(fd);
4f0767ce 17601+out:
1e00d052 17602+ AuTraceErr(err);
4a4d8108
AM
17603+ return err;
17604+}
17605+
17606+/* ---------------------------------------------------------------------- */
17607+
17608+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
17609+{
17610+ long err;
c1595e42 17611+ struct dentry *dentry;
4a4d8108
AM
17612+
17613+ switch (cmd) {
4a4d8108
AM
17614+ case AUFS_CTL_RDU:
17615+ case AUFS_CTL_RDU_INO:
17616+ err = au_rdu_ioctl(file, cmd, arg);
17617+ break;
17618+
17619+ case AUFS_CTL_WBR_FD:
1e00d052 17620+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
17621+ break;
17622+
027c5e7a
AM
17623+ case AUFS_CTL_IBUSY:
17624+ err = au_ibusy_ioctl(file, arg);
17625+ break;
17626+
076b876e
AM
17627+ case AUFS_CTL_BRINFO:
17628+ err = au_brinfo_ioctl(file, arg);
17629+ break;
17630+
17631+ case AUFS_CTL_FHSM_FD:
2000de60 17632+ dentry = file->f_path.dentry;
c1595e42
JR
17633+ if (IS_ROOT(dentry))
17634+ err = au_fhsm_fd(dentry->d_sb, arg);
17635+ else
17636+ err = -ENOTTY;
076b876e
AM
17637+ break;
17638+
4a4d8108
AM
17639+ default:
17640+ /* do not call the lower */
17641+ AuDbg("0x%x\n", cmd);
17642+ err = -ENOTTY;
17643+ }
17644+
17645+ AuTraceErr(err);
17646+ return err;
17647+}
17648+
17649+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
17650+{
17651+ long err;
17652+
17653+ switch (cmd) {
c2b27bf2 17654+ case AUFS_CTL_MVDOWN:
2000de60 17655+ err = au_mvdown(file->f_path.dentry, (void __user *)arg);
c2b27bf2
AM
17656+ break;
17657+
4a4d8108 17658+ case AUFS_CTL_WBR_FD:
1e00d052 17659+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
17660+ break;
17661+
17662+ default:
17663+ /* do not call the lower */
17664+ AuDbg("0x%x\n", cmd);
17665+ err = -ENOTTY;
17666+ }
17667+
17668+ AuTraceErr(err);
17669+ return err;
17670+}
b752ccd1
AM
17671+
17672+#ifdef CONFIG_COMPAT
17673+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
17674+ unsigned long arg)
17675+{
17676+ long err;
17677+
17678+ switch (cmd) {
17679+ case AUFS_CTL_RDU:
17680+ case AUFS_CTL_RDU_INO:
17681+ err = au_rdu_compat_ioctl(file, cmd, arg);
17682+ break;
17683+
027c5e7a
AM
17684+ case AUFS_CTL_IBUSY:
17685+ err = au_ibusy_compat_ioctl(file, arg);
17686+ break;
17687+
076b876e
AM
17688+ case AUFS_CTL_BRINFO:
17689+ err = au_brinfo_compat_ioctl(file, arg);
17690+ break;
17691+
b752ccd1
AM
17692+ default:
17693+ err = aufs_ioctl_dir(file, cmd, arg);
17694+ }
17695+
17696+ AuTraceErr(err);
17697+ return err;
17698+}
17699+
b752ccd1
AM
17700+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
17701+ unsigned long arg)
17702+{
17703+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
17704+}
17705+#endif
7f207e10
AM
17706diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
17707--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 17708+++ linux/fs/aufs/i_op_add.c 2017-07-29 12:14:25.903042072 +0200
521ced18 17709@@ -0,0 +1,920 @@
4a4d8108 17710+/*
a2654f78 17711+ * Copyright (C) 2005-2017 Junjiro R. Okajima
4a4d8108
AM
17712+ *
17713+ * This program, aufs is free software; you can redistribute it and/or modify
17714+ * it under the terms of the GNU General Public License as published by
17715+ * the Free Software Foundation; either version 2 of the License, or
17716+ * (at your option) any later version.
17717+ *
17718+ * This program is distributed in the hope that it will be useful,
17719+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17720+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17721+ * GNU General Public License for more details.
17722+ *
17723+ * You should have received a copy of the GNU General Public License
523b37e3 17724+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
17725+ */
17726+
17727+/*
17728+ * inode operations (add entry)
17729+ */
17730+
17731+#include "aufs.h"
17732+
17733+/*
17734+ * final procedure of adding a new entry, except link(2).
17735+ * remove whiteout, instantiate, copyup the parent dir's times and size
17736+ * and update version.
17737+ * if it failed, re-create the removed whiteout.
17738+ */
17739+static int epilog(struct inode *dir, aufs_bindex_t bindex,
17740+ struct dentry *wh_dentry, struct dentry *dentry)
17741+{
17742+ int err, rerr;
17743+ aufs_bindex_t bwh;
17744+ struct path h_path;
076b876e 17745+ struct super_block *sb;
4a4d8108
AM
17746+ struct inode *inode, *h_dir;
17747+ struct dentry *wh;
17748+
17749+ bwh = -1;
076b876e 17750+ sb = dir->i_sb;
4a4d8108 17751+ if (wh_dentry) {
5527c038 17752+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
4a4d8108
AM
17753+ IMustLock(h_dir);
17754+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
17755+ bwh = au_dbwh(dentry);
17756+ h_path.dentry = wh_dentry;
076b876e 17757+ h_path.mnt = au_sbr_mnt(sb, bindex);
4a4d8108
AM
17758+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
17759+ dentry);
17760+ if (unlikely(err))
17761+ goto out;
17762+ }
17763+
17764+ inode = au_new_inode(dentry, /*must_new*/1);
17765+ if (!IS_ERR(inode)) {
17766+ d_instantiate(dentry, inode);
5527c038 17767+ dir = d_inode(dentry->d_parent); /* dir inode is locked */
4a4d8108 17768+ IMustLock(dir);
b912730e 17769+ au_dir_ts(dir, bindex);
4a4d8108 17770+ dir->i_version++;
076b876e 17771+ au_fhsm_wrote(sb, bindex, /*force*/0);
4a4d8108
AM
17772+ return 0; /* success */
17773+ }
17774+
17775+ err = PTR_ERR(inode);
17776+ if (!wh_dentry)
17777+ goto out;
17778+
17779+ /* revert */
17780+ /* dir inode is locked */
17781+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
17782+ rerr = PTR_ERR(wh);
17783+ if (IS_ERR(wh)) {
523b37e3
AM
17784+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
17785+ dentry, err, rerr);
4a4d8108
AM
17786+ err = -EIO;
17787+ } else
17788+ dput(wh);
17789+
4f0767ce 17790+out:
4a4d8108
AM
17791+ return err;
17792+}
17793+
027c5e7a
AM
17794+static int au_d_may_add(struct dentry *dentry)
17795+{
17796+ int err;
17797+
17798+ err = 0;
17799+ if (unlikely(d_unhashed(dentry)))
17800+ err = -ENOENT;
5527c038 17801+ if (unlikely(d_really_is_positive(dentry)))
027c5e7a
AM
17802+ err = -EEXIST;
17803+ return err;
17804+}
17805+
4a4d8108
AM
17806+/*
17807+ * simple tests for the adding inode operations.
17808+ * following the checks in vfs, plus the parent-child relationship.
17809+ */
17810+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
17811+ struct dentry *h_parent, int isdir)
17812+{
17813+ int err;
17814+ umode_t h_mode;
17815+ struct dentry *h_dentry;
17816+ struct inode *h_inode;
17817+
17818+ err = -ENAMETOOLONG;
17819+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17820+ goto out;
17821+
17822+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 17823+ if (d_really_is_negative(dentry)) {
4a4d8108 17824+ err = -EEXIST;
5527c038 17825+ if (unlikely(d_is_positive(h_dentry)))
4a4d8108
AM
17826+ goto out;
17827+ } else {
17828+ /* rename(2) case */
17829+ err = -EIO;
5527c038
JR
17830+ if (unlikely(d_is_negative(h_dentry)))
17831+ goto out;
17832+ h_inode = d_inode(h_dentry);
17833+ if (unlikely(!h_inode->i_nlink))
4a4d8108
AM
17834+ goto out;
17835+
17836+ h_mode = h_inode->i_mode;
17837+ if (!isdir) {
17838+ err = -EISDIR;
17839+ if (unlikely(S_ISDIR(h_mode)))
17840+ goto out;
17841+ } else if (unlikely(!S_ISDIR(h_mode))) {
17842+ err = -ENOTDIR;
17843+ goto out;
17844+ }
17845+ }
17846+
17847+ err = 0;
17848+ /* expected parent dir is locked */
17849+ if (unlikely(h_parent != h_dentry->d_parent))
17850+ err = -EIO;
17851+
4f0767ce 17852+out:
4a4d8108
AM
17853+ AuTraceErr(err);
17854+ return err;
17855+}
17856+
17857+/*
17858+ * initial procedure of adding a new entry.
17859+ * prepare writable branch and the parent dir, lock it,
17860+ * and lookup whiteout for the new entry.
17861+ */
17862+static struct dentry*
17863+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
17864+ struct dentry *src_dentry, struct au_pin *pin,
17865+ struct au_wr_dir_args *wr_dir_args)
17866+{
17867+ struct dentry *wh_dentry, *h_parent;
17868+ struct super_block *sb;
17869+ struct au_branch *br;
17870+ int err;
17871+ unsigned int udba;
17872+ aufs_bindex_t bcpup;
17873+
523b37e3 17874+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17875+
17876+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
17877+ bcpup = err;
17878+ wh_dentry = ERR_PTR(err);
17879+ if (unlikely(err < 0))
17880+ goto out;
17881+
17882+ sb = dentry->d_sb;
17883+ udba = au_opt_udba(sb);
17884+ err = au_pin(pin, dentry, bcpup, udba,
17885+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17886+ wh_dentry = ERR_PTR(err);
17887+ if (unlikely(err))
17888+ goto out;
17889+
17890+ h_parent = au_pinned_h_parent(pin);
17891+ if (udba != AuOpt_UDBA_NONE
5afbbe0d 17892+ && au_dbtop(dentry) == bcpup)
4a4d8108
AM
17893+ err = au_may_add(dentry, bcpup, h_parent,
17894+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
17895+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17896+ err = -ENAMETOOLONG;
17897+ wh_dentry = ERR_PTR(err);
17898+ if (unlikely(err))
17899+ goto out_unpin;
17900+
17901+ br = au_sbr(sb, bcpup);
17902+ if (dt) {
17903+ struct path tmp = {
17904+ .dentry = h_parent,
86dc4139 17905+ .mnt = au_br_mnt(br)
4a4d8108
AM
17906+ };
17907+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
17908+ }
17909+
17910+ wh_dentry = NULL;
17911+ if (bcpup != au_dbwh(dentry))
17912+ goto out; /* success */
17913+
2000de60
JR
17914+ /*
17915+ * ENAMETOOLONG here means that if we allowed create such name, then it
17916+ * would not be able to removed in the future. So we don't allow such
17917+ * name here and we don't handle ENAMETOOLONG differently here.
17918+ */
4a4d8108
AM
17919+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
17920+
4f0767ce 17921+out_unpin:
4a4d8108
AM
17922+ if (IS_ERR(wh_dentry))
17923+ au_unpin(pin);
4f0767ce 17924+out:
4a4d8108
AM
17925+ return wh_dentry;
17926+}
17927+
17928+/* ---------------------------------------------------------------------- */
17929+
17930+enum { Mknod, Symlink, Creat };
17931+struct simple_arg {
17932+ int type;
17933+ union {
17934+ struct {
b912730e
AM
17935+ umode_t mode;
17936+ bool want_excl;
17937+ bool try_aopen;
17938+ struct vfsub_aopen_args *aopen;
4a4d8108
AM
17939+ } c;
17940+ struct {
17941+ const char *symname;
17942+ } s;
17943+ struct {
7eafdf33 17944+ umode_t mode;
4a4d8108
AM
17945+ dev_t dev;
17946+ } m;
17947+ } u;
17948+};
17949+
17950+static int add_simple(struct inode *dir, struct dentry *dentry,
17951+ struct simple_arg *arg)
17952+{
076b876e 17953+ int err, rerr;
5afbbe0d 17954+ aufs_bindex_t btop;
4a4d8108 17955+ unsigned char created;
b912730e
AM
17956+ const unsigned char try_aopen
17957+ = (arg->type == Creat && arg->u.c.try_aopen);
4a4d8108
AM
17958+ struct dentry *wh_dentry, *parent;
17959+ struct inode *h_dir;
b912730e
AM
17960+ struct super_block *sb;
17961+ struct au_branch *br;
c2b27bf2
AM
17962+ /* to reuduce stack size */
17963+ struct {
17964+ struct au_dtime dt;
17965+ struct au_pin pin;
17966+ struct path h_path;
17967+ struct au_wr_dir_args wr_dir_args;
17968+ } *a;
4a4d8108 17969+
523b37e3 17970+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17971+ IMustLock(dir);
17972+
c2b27bf2
AM
17973+ err = -ENOMEM;
17974+ a = kmalloc(sizeof(*a), GFP_NOFS);
17975+ if (unlikely(!a))
17976+ goto out;
17977+ a->wr_dir_args.force_btgt = -1;
17978+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
17979+
4a4d8108 17980+ parent = dentry->d_parent; /* dir inode is locked */
b912730e
AM
17981+ if (!try_aopen) {
17982+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17983+ if (unlikely(err))
17984+ goto out_free;
17985+ }
027c5e7a
AM
17986+ err = au_d_may_add(dentry);
17987+ if (unlikely(err))
17988+ goto out_unlock;
b912730e
AM
17989+ if (!try_aopen)
17990+ di_write_lock_parent(parent);
c2b27bf2
AM
17991+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
17992+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
17993+ err = PTR_ERR(wh_dentry);
17994+ if (IS_ERR(wh_dentry))
027c5e7a 17995+ goto out_parent;
4a4d8108 17996+
5afbbe0d 17997+ btop = au_dbtop(dentry);
b912730e 17998+ sb = dentry->d_sb;
5afbbe0d
AM
17999+ br = au_sbr(sb, btop);
18000+ a->h_path.dentry = au_h_dptr(dentry, btop);
b912730e 18001+ a->h_path.mnt = au_br_mnt(br);
c2b27bf2 18002+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
18003+ switch (arg->type) {
18004+ case Creat:
b912730e
AM
18005+ err = 0;
18006+ if (!try_aopen || !h_dir->i_op->atomic_open)
18007+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
18008+ arg->u.c.want_excl);
18009+ else
18010+ err = vfsub_atomic_open(h_dir, a->h_path.dentry,
18011+ arg->u.c.aopen, br);
4a4d8108
AM
18012+ break;
18013+ case Symlink:
c2b27bf2 18014+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
4a4d8108
AM
18015+ break;
18016+ case Mknod:
c2b27bf2
AM
18017+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
18018+ arg->u.m.dev);
4a4d8108
AM
18019+ break;
18020+ default:
18021+ BUG();
18022+ }
18023+ created = !err;
18024+ if (!err)
5afbbe0d 18025+ err = epilog(dir, btop, wh_dentry, dentry);
4a4d8108
AM
18026+
18027+ /* revert */
5527c038 18028+ if (unlikely(created && err && d_is_positive(a->h_path.dentry))) {
523b37e3
AM
18029+ /* no delegation since it is just created */
18030+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
18031+ /*force*/0);
4a4d8108 18032+ if (rerr) {
523b37e3
AM
18033+ AuIOErr("%pd revert failure(%d, %d)\n",
18034+ dentry, err, rerr);
4a4d8108
AM
18035+ err = -EIO;
18036+ }
c2b27bf2 18037+ au_dtime_revert(&a->dt);
4a4d8108
AM
18038+ }
18039+
b912730e
AM
18040+ if (!err && try_aopen && !h_dir->i_op->atomic_open)
18041+ *arg->u.c.aopen->opened |= FILE_CREATED;
18042+
c2b27bf2 18043+ au_unpin(&a->pin);
4a4d8108
AM
18044+ dput(wh_dentry);
18045+
027c5e7a 18046+out_parent:
b912730e
AM
18047+ if (!try_aopen)
18048+ di_write_unlock(parent);
027c5e7a 18049+out_unlock:
4a4d8108 18050+ if (unlikely(err)) {
5afbbe0d 18051+ au_update_dbtop(dentry);
4a4d8108
AM
18052+ d_drop(dentry);
18053+ }
b912730e
AM
18054+ if (!try_aopen)
18055+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 18056+out_free:
1c60b727 18057+ kfree(a);
027c5e7a 18058+out:
4a4d8108
AM
18059+ return err;
18060+}
18061+
7eafdf33
AM
18062+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
18063+ dev_t dev)
4a4d8108
AM
18064+{
18065+ struct simple_arg arg = {
18066+ .type = Mknod,
18067+ .u.m = {
18068+ .mode = mode,
18069+ .dev = dev
18070+ }
18071+ };
18072+ return add_simple(dir, dentry, &arg);
18073+}
18074+
18075+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
18076+{
18077+ struct simple_arg arg = {
18078+ .type = Symlink,
18079+ .u.s.symname = symname
18080+ };
18081+ return add_simple(dir, dentry, &arg);
18082+}
18083+
7eafdf33 18084+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 18085+ bool want_excl)
4a4d8108
AM
18086+{
18087+ struct simple_arg arg = {
18088+ .type = Creat,
18089+ .u.c = {
b4510431
AM
18090+ .mode = mode,
18091+ .want_excl = want_excl
4a4d8108
AM
18092+ }
18093+ };
18094+ return add_simple(dir, dentry, &arg);
18095+}
18096+
b912730e
AM
18097+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
18098+ struct vfsub_aopen_args *aopen_args)
18099+{
18100+ struct simple_arg arg = {
18101+ .type = Creat,
18102+ .u.c = {
18103+ .mode = aopen_args->create_mode,
18104+ .want_excl = aopen_args->open_flag & O_EXCL,
18105+ .try_aopen = true,
18106+ .aopen = aopen_args
18107+ }
18108+ };
18109+ return add_simple(dir, dentry, &arg);
18110+}
18111+
38d290e6
JR
18112+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
18113+{
18114+ int err;
18115+ aufs_bindex_t bindex;
18116+ struct super_block *sb;
18117+ struct dentry *parent, *h_parent, *h_dentry;
18118+ struct inode *h_dir, *inode;
18119+ struct vfsmount *h_mnt;
18120+ struct au_wr_dir_args wr_dir_args = {
18121+ .force_btgt = -1,
18122+ .flags = AuWrDir_TMPFILE
18123+ };
18124+
18125+ /* copy-up may happen */
febd17d6 18126+ inode_lock(dir);
38d290e6
JR
18127+
18128+ sb = dir->i_sb;
18129+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18130+ if (unlikely(err))
18131+ goto out;
18132+
18133+ err = au_di_init(dentry);
18134+ if (unlikely(err))
18135+ goto out_si;
18136+
18137+ err = -EBUSY;
18138+ parent = d_find_any_alias(dir);
18139+ AuDebugOn(!parent);
18140+ di_write_lock_parent(parent);
5527c038 18141+ if (unlikely(d_inode(parent) != dir))
38d290e6
JR
18142+ goto out_parent;
18143+
18144+ err = au_digen_test(parent, au_sigen(sb));
18145+ if (unlikely(err))
18146+ goto out_parent;
18147+
5afbbe0d
AM
18148+ bindex = au_dbtop(parent);
18149+ au_set_dbtop(dentry, bindex);
18150+ au_set_dbbot(dentry, bindex);
38d290e6
JR
18151+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
18152+ bindex = err;
18153+ if (unlikely(err < 0))
18154+ goto out_parent;
18155+
18156+ err = -EOPNOTSUPP;
18157+ h_dir = au_h_iptr(dir, bindex);
18158+ if (unlikely(!h_dir->i_op->tmpfile))
18159+ goto out_parent;
18160+
18161+ h_mnt = au_sbr_mnt(sb, bindex);
18162+ err = vfsub_mnt_want_write(h_mnt);
18163+ if (unlikely(err))
18164+ goto out_parent;
18165+
18166+ h_parent = au_h_dptr(parent, bindex);
521ced18
JR
18167+ h_dentry = vfs_tmpfile(h_parent, mode, /*open_flag*/0);
18168+ if (IS_ERR(h_dentry)) {
18169+ err = PTR_ERR(h_dentry);
38d290e6 18170+ goto out_mnt;
521ced18 18171+ }
38d290e6 18172+
5afbbe0d
AM
18173+ au_set_dbtop(dentry, bindex);
18174+ au_set_dbbot(dentry, bindex);
38d290e6
JR
18175+ au_set_h_dptr(dentry, bindex, dget(h_dentry));
18176+ inode = au_new_inode(dentry, /*must_new*/1);
18177+ if (IS_ERR(inode)) {
18178+ err = PTR_ERR(inode);
18179+ au_set_h_dptr(dentry, bindex, NULL);
5afbbe0d
AM
18180+ au_set_dbtop(dentry, -1);
18181+ au_set_dbbot(dentry, -1);
38d290e6
JR
18182+ } else {
18183+ if (!inode->i_nlink)
18184+ set_nlink(inode, 1);
18185+ d_tmpfile(dentry, inode);
18186+ au_di(dentry)->di_tmpfile = 1;
18187+
18188+ /* update without i_mutex */
5afbbe0d 18189+ if (au_ibtop(dir) == au_dbtop(dentry))
38d290e6
JR
18190+ au_cpup_attr_timesizes(dir);
18191+ }
38d290e6 18192+ dput(h_dentry);
521ced18 18193+
38d290e6
JR
18194+out_mnt:
18195+ vfsub_mnt_drop_write(h_mnt);
18196+out_parent:
18197+ di_write_unlock(parent);
18198+ dput(parent);
18199+ di_write_unlock(dentry);
5afbbe0d 18200+ if (unlikely(err)) {
38d290e6
JR
18201+ au_di_fin(dentry);
18202+ dentry->d_fsdata = NULL;
18203+ }
18204+out_si:
18205+ si_read_unlock(sb);
18206+out:
febd17d6 18207+ inode_unlock(dir);
38d290e6
JR
18208+ return err;
18209+}
18210+
4a4d8108
AM
18211+/* ---------------------------------------------------------------------- */
18212+
18213+struct au_link_args {
18214+ aufs_bindex_t bdst, bsrc;
18215+ struct au_pin pin;
18216+ struct path h_path;
18217+ struct dentry *src_parent, *parent;
18218+};
18219+
18220+static int au_cpup_before_link(struct dentry *src_dentry,
18221+ struct au_link_args *a)
18222+{
18223+ int err;
18224+ struct dentry *h_src_dentry;
c2b27bf2
AM
18225+ struct au_cp_generic cpg = {
18226+ .dentry = src_dentry,
18227+ .bdst = a->bdst,
18228+ .bsrc = a->bsrc,
18229+ .len = -1,
18230+ .pin = &a->pin,
18231+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
18232+ };
4a4d8108
AM
18233+
18234+ di_read_lock_parent(a->src_parent, AuLock_IR);
18235+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
18236+ if (unlikely(err))
18237+ goto out;
18238+
18239+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
18240+ err = au_pin(&a->pin, src_dentry, a->bdst,
18241+ au_opt_udba(src_dentry->d_sb),
18242+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
18243+ if (unlikely(err))
18244+ goto out;
367653fa 18245+
c2b27bf2 18246+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
18247+ au_unpin(&a->pin);
18248+
4f0767ce 18249+out:
4a4d8108
AM
18250+ di_read_unlock(a->src_parent, AuLock_IR);
18251+ return err;
18252+}
18253+
86dc4139
AM
18254+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
18255+ struct au_link_args *a)
4a4d8108
AM
18256+{
18257+ int err;
18258+ unsigned char plink;
5afbbe0d 18259+ aufs_bindex_t bbot;
4a4d8108 18260+ struct dentry *h_src_dentry;
523b37e3 18261+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
18262+ struct super_block *sb;
18263+ struct file *h_file;
18264+
18265+ plink = 0;
18266+ h_inode = NULL;
18267+ sb = src_dentry->d_sb;
5527c038 18268+ inode = d_inode(src_dentry);
5afbbe0d 18269+ if (au_ibtop(inode) <= a->bdst)
4a4d8108
AM
18270+ h_inode = au_h_iptr(inode, a->bdst);
18271+ if (!h_inode || !h_inode->i_nlink) {
18272+ /* copyup src_dentry as the name of dentry. */
5afbbe0d
AM
18273+ bbot = au_dbbot(dentry);
18274+ if (bbot < a->bsrc)
18275+ au_set_dbbot(dentry, a->bsrc);
86dc4139
AM
18276+ au_set_h_dptr(dentry, a->bsrc,
18277+ dget(au_h_dptr(src_dentry, a->bsrc)));
18278+ dget(a->h_path.dentry);
18279+ au_set_h_dptr(dentry, a->bdst, NULL);
c1595e42
JR
18280+ AuDbg("temporary d_inode...\n");
18281+ spin_lock(&dentry->d_lock);
5527c038 18282+ dentry->d_inode = d_inode(src_dentry); /* tmp */
c1595e42 18283+ spin_unlock(&dentry->d_lock);
392086de 18284+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 18285+ if (IS_ERR(h_file))
4a4d8108 18286+ err = PTR_ERR(h_file);
86dc4139 18287+ else {
c2b27bf2
AM
18288+ struct au_cp_generic cpg = {
18289+ .dentry = dentry,
18290+ .bdst = a->bdst,
18291+ .bsrc = -1,
18292+ .len = -1,
18293+ .pin = &a->pin,
18294+ .flags = AuCpup_KEEPLINO
18295+ };
18296+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
18297+ au_h_open_post(dentry, a->bsrc, h_file);
18298+ if (!err) {
18299+ dput(a->h_path.dentry);
18300+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
18301+ } else
18302+ au_set_h_dptr(dentry, a->bdst,
18303+ a->h_path.dentry);
18304+ }
c1595e42 18305+ spin_lock(&dentry->d_lock);
86dc4139 18306+ dentry->d_inode = NULL; /* restore */
c1595e42
JR
18307+ spin_unlock(&dentry->d_lock);
18308+ AuDbg("temporary d_inode...done\n");
86dc4139 18309+ au_set_h_dptr(dentry, a->bsrc, NULL);
5afbbe0d 18310+ au_set_dbbot(dentry, bbot);
4a4d8108
AM
18311+ } else {
18312+ /* the inode of src_dentry already exists on a.bdst branch */
18313+ h_src_dentry = d_find_alias(h_inode);
18314+ if (!h_src_dentry && au_plink_test(inode)) {
18315+ plink = 1;
18316+ h_src_dentry = au_plink_lkup(inode, a->bdst);
18317+ err = PTR_ERR(h_src_dentry);
18318+ if (IS_ERR(h_src_dentry))
18319+ goto out;
18320+
5527c038 18321+ if (unlikely(d_is_negative(h_src_dentry))) {
4a4d8108
AM
18322+ dput(h_src_dentry);
18323+ h_src_dentry = NULL;
18324+ }
18325+
18326+ }
18327+ if (h_src_dentry) {
523b37e3 18328+ delegated = NULL;
4a4d8108 18329+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
18330+ &a->h_path, &delegated);
18331+ if (unlikely(err == -EWOULDBLOCK)) {
18332+ pr_warn("cannot retry for NFSv4 delegation"
18333+ " for an internal link\n");
18334+ iput(delegated);
18335+ }
4a4d8108
AM
18336+ dput(h_src_dentry);
18337+ } else {
18338+ AuIOErr("no dentry found for hi%lu on b%d\n",
18339+ h_inode->i_ino, a->bdst);
18340+ err = -EIO;
18341+ }
18342+ }
18343+
18344+ if (!err && !plink)
18345+ au_plink_append(inode, a->bdst, a->h_path.dentry);
18346+
18347+out:
2cbb1c4b 18348+ AuTraceErr(err);
4a4d8108
AM
18349+ return err;
18350+}
18351+
18352+int aufs_link(struct dentry *src_dentry, struct inode *dir,
18353+ struct dentry *dentry)
18354+{
18355+ int err, rerr;
18356+ struct au_dtime dt;
18357+ struct au_link_args *a;
18358+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 18359+ struct inode *inode, *delegated;
4a4d8108
AM
18360+ struct super_block *sb;
18361+ struct au_wr_dir_args wr_dir_args = {
18362+ /* .force_btgt = -1, */
18363+ .flags = AuWrDir_ADD_ENTRY
18364+ };
18365+
18366+ IMustLock(dir);
5527c038 18367+ inode = d_inode(src_dentry);
4a4d8108
AM
18368+ IMustLock(inode);
18369+
4a4d8108
AM
18370+ err = -ENOMEM;
18371+ a = kzalloc(sizeof(*a), GFP_NOFS);
18372+ if (unlikely(!a))
18373+ goto out;
18374+
18375+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
18376+ err = aufs_read_and_write_lock2(dentry, src_dentry,
18377+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
18378+ if (unlikely(err))
18379+ goto out_kfree;
38d290e6 18380+ err = au_d_linkable(src_dentry);
027c5e7a
AM
18381+ if (unlikely(err))
18382+ goto out_unlock;
18383+ err = au_d_may_add(dentry);
18384+ if (unlikely(err))
18385+ goto out_unlock;
e49829fe 18386+
4a4d8108 18387+ a->src_parent = dget_parent(src_dentry);
5afbbe0d 18388+ wr_dir_args.force_btgt = au_ibtop(inode);
4a4d8108
AM
18389+
18390+ di_write_lock_parent(a->parent);
18391+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
18392+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
18393+ &wr_dir_args);
18394+ err = PTR_ERR(wh_dentry);
18395+ if (IS_ERR(wh_dentry))
027c5e7a 18396+ goto out_parent;
4a4d8108
AM
18397+
18398+ err = 0;
18399+ sb = dentry->d_sb;
5afbbe0d 18400+ a->bdst = au_dbtop(dentry);
4a4d8108
AM
18401+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
18402+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
5afbbe0d 18403+ a->bsrc = au_ibtop(inode);
2cbb1c4b 18404+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
38d290e6
JR
18405+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
18406+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
2cbb1c4b 18407+ if (!h_src_dentry) {
5afbbe0d 18408+ a->bsrc = au_dbtop(src_dentry);
2cbb1c4b
JR
18409+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
18410+ AuDebugOn(!h_src_dentry);
38d290e6
JR
18411+ } else if (IS_ERR(h_src_dentry)) {
18412+ err = PTR_ERR(h_src_dentry);
2cbb1c4b 18413+ goto out_parent;
38d290e6 18414+ }
2cbb1c4b 18415+
f2c43d5f
AM
18416+ /*
18417+ * aufs doesn't touch the credential so
18418+ * security_dentry_create_files_as() is unnecrssary.
18419+ */
4a4d8108
AM
18420+ if (au_opt_test(au_mntflags(sb), PLINK)) {
18421+ if (a->bdst < a->bsrc
18422+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 18423+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
18424+ else {
18425+ delegated = NULL;
4a4d8108 18426+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
18427+ &a->h_path, &delegated);
18428+ if (unlikely(err == -EWOULDBLOCK)) {
18429+ pr_warn("cannot retry for NFSv4 delegation"
18430+ " for an internal link\n");
18431+ iput(delegated);
18432+ }
18433+ }
2cbb1c4b 18434+ dput(h_src_dentry);
4a4d8108
AM
18435+ } else {
18436+ /*
18437+ * copyup src_dentry to the branch we process,
18438+ * and then link(2) to it.
18439+ */
2cbb1c4b 18440+ dput(h_src_dentry);
4a4d8108
AM
18441+ if (a->bdst < a->bsrc
18442+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
18443+ au_unpin(&a->pin);
18444+ di_write_unlock(a->parent);
18445+ err = au_cpup_before_link(src_dentry, a);
18446+ di_write_lock_parent(a->parent);
18447+ if (!err)
18448+ err = au_pin(&a->pin, dentry, a->bdst,
18449+ au_opt_udba(sb),
18450+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
18451+ if (unlikely(err))
18452+ goto out_wh;
18453+ }
18454+ if (!err) {
18455+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
18456+ err = -ENOENT;
5527c038 18457+ if (h_src_dentry && d_is_positive(h_src_dentry)) {
523b37e3 18458+ delegated = NULL;
4a4d8108
AM
18459+ err = vfsub_link(h_src_dentry,
18460+ au_pinned_h_dir(&a->pin),
523b37e3
AM
18461+ &a->h_path, &delegated);
18462+ if (unlikely(err == -EWOULDBLOCK)) {
18463+ pr_warn("cannot retry"
18464+ " for NFSv4 delegation"
18465+ " for an internal link\n");
18466+ iput(delegated);
18467+ }
18468+ }
4a4d8108
AM
18469+ }
18470+ }
18471+ if (unlikely(err))
18472+ goto out_unpin;
18473+
18474+ if (wh_dentry) {
18475+ a->h_path.dentry = wh_dentry;
18476+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
18477+ dentry);
18478+ if (unlikely(err))
18479+ goto out_revert;
18480+ }
18481+
b912730e 18482+ au_dir_ts(dir, a->bdst);
4a4d8108 18483+ dir->i_version++;
4a4d8108
AM
18484+ inc_nlink(inode);
18485+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
18486+ d_instantiate(dentry, au_igrab(inode));
18487+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
18488+ /* some filesystem calls d_drop() */
18489+ d_drop(dentry);
076b876e
AM
18490+ /* some filesystems consume an inode even hardlink */
18491+ au_fhsm_wrote(sb, a->bdst, /*force*/0);
4a4d8108
AM
18492+ goto out_unpin; /* success */
18493+
4f0767ce 18494+out_revert:
523b37e3
AM
18495+ /* no delegation since it is just created */
18496+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
18497+ /*delegated*/NULL, /*force*/0);
027c5e7a 18498+ if (unlikely(rerr)) {
523b37e3 18499+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
18500+ err = -EIO;
18501+ }
4a4d8108 18502+ au_dtime_revert(&dt);
4f0767ce 18503+out_unpin:
4a4d8108 18504+ au_unpin(&a->pin);
4f0767ce 18505+out_wh:
4a4d8108 18506+ dput(wh_dentry);
027c5e7a
AM
18507+out_parent:
18508+ di_write_unlock(a->parent);
18509+ dput(a->src_parent);
4f0767ce 18510+out_unlock:
4a4d8108 18511+ if (unlikely(err)) {
5afbbe0d 18512+ au_update_dbtop(dentry);
4a4d8108
AM
18513+ d_drop(dentry);
18514+ }
4a4d8108 18515+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 18516+out_kfree:
1c60b727 18517+ kfree(a);
4f0767ce 18518+out:
86dc4139 18519+ AuTraceErr(err);
4a4d8108
AM
18520+ return err;
18521+}
18522+
7eafdf33 18523+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
18524+{
18525+ int err, rerr;
18526+ aufs_bindex_t bindex;
18527+ unsigned char diropq;
18528+ struct path h_path;
18529+ struct dentry *wh_dentry, *parent, *opq_dentry;
febd17d6 18530+ struct inode *h_inode;
4a4d8108
AM
18531+ struct super_block *sb;
18532+ struct {
18533+ struct au_pin pin;
18534+ struct au_dtime dt;
18535+ } *a; /* reduce the stack usage */
18536+ struct au_wr_dir_args wr_dir_args = {
18537+ .force_btgt = -1,
18538+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
18539+ };
18540+
18541+ IMustLock(dir);
18542+
18543+ err = -ENOMEM;
18544+ a = kmalloc(sizeof(*a), GFP_NOFS);
18545+ if (unlikely(!a))
18546+ goto out;
18547+
027c5e7a
AM
18548+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
18549+ if (unlikely(err))
18550+ goto out_free;
18551+ err = au_d_may_add(dentry);
18552+ if (unlikely(err))
18553+ goto out_unlock;
18554+
4a4d8108
AM
18555+ parent = dentry->d_parent; /* dir inode is locked */
18556+ di_write_lock_parent(parent);
18557+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
18558+ &a->pin, &wr_dir_args);
18559+ err = PTR_ERR(wh_dentry);
18560+ if (IS_ERR(wh_dentry))
027c5e7a 18561+ goto out_parent;
4a4d8108
AM
18562+
18563+ sb = dentry->d_sb;
5afbbe0d 18564+ bindex = au_dbtop(dentry);
4a4d8108
AM
18565+ h_path.dentry = au_h_dptr(dentry, bindex);
18566+ h_path.mnt = au_sbr_mnt(sb, bindex);
18567+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
18568+ if (unlikely(err))
027c5e7a 18569+ goto out_unpin;
4a4d8108
AM
18570+
18571+ /* make the dir opaque */
18572+ diropq = 0;
febd17d6 18573+ h_inode = d_inode(h_path.dentry);
4a4d8108
AM
18574+ if (wh_dentry
18575+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
febd17d6 18576+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 18577+ opq_dentry = au_diropq_create(dentry, bindex);
febd17d6 18578+ inode_unlock(h_inode);
4a4d8108
AM
18579+ err = PTR_ERR(opq_dentry);
18580+ if (IS_ERR(opq_dentry))
18581+ goto out_dir;
18582+ dput(opq_dentry);
18583+ diropq = 1;
18584+ }
18585+
18586+ err = epilog(dir, bindex, wh_dentry, dentry);
18587+ if (!err) {
18588+ inc_nlink(dir);
027c5e7a 18589+ goto out_unpin; /* success */
4a4d8108
AM
18590+ }
18591+
18592+ /* revert */
18593+ if (diropq) {
18594+ AuLabel(revert opq);
febd17d6 18595+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 18596+ rerr = au_diropq_remove(dentry, bindex);
febd17d6 18597+ inode_unlock(h_inode);
4a4d8108 18598+ if (rerr) {
523b37e3
AM
18599+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
18600+ dentry, err, rerr);
4a4d8108
AM
18601+ err = -EIO;
18602+ }
18603+ }
18604+
4f0767ce 18605+out_dir:
4a4d8108
AM
18606+ AuLabel(revert dir);
18607+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
18608+ if (rerr) {
523b37e3
AM
18609+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
18610+ dentry, err, rerr);
4a4d8108
AM
18611+ err = -EIO;
18612+ }
4a4d8108 18613+ au_dtime_revert(&a->dt);
027c5e7a 18614+out_unpin:
4a4d8108
AM
18615+ au_unpin(&a->pin);
18616+ dput(wh_dentry);
027c5e7a
AM
18617+out_parent:
18618+ di_write_unlock(parent);
18619+out_unlock:
4a4d8108 18620+ if (unlikely(err)) {
5afbbe0d 18621+ au_update_dbtop(dentry);
4a4d8108
AM
18622+ d_drop(dentry);
18623+ }
4a4d8108 18624+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 18625+out_free:
1c60b727 18626+ kfree(a);
4f0767ce 18627+out:
4a4d8108
AM
18628+ return err;
18629+}
7f207e10
AM
18630diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
18631--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
3c1bdaff 18632+++ linux/fs/aufs/i_op.c 2017-09-05 10:42:11.058755349 +0200
521ced18 18633@@ -0,0 +1,1452 @@
4a4d8108 18634+/*
a2654f78 18635+ * Copyright (C) 2005-2017 Junjiro R. Okajima
4a4d8108
AM
18636+ *
18637+ * This program, aufs is free software; you can redistribute it and/or modify
18638+ * it under the terms of the GNU General Public License as published by
18639+ * the Free Software Foundation; either version 2 of the License, or
18640+ * (at your option) any later version.
18641+ *
18642+ * This program is distributed in the hope that it will be useful,
18643+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18644+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18645+ * GNU General Public License for more details.
18646+ *
18647+ * You should have received a copy of the GNU General Public License
523b37e3 18648+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 18649+ */
1facf9fc 18650+
1308ab2a 18651+/*
4a4d8108 18652+ * inode operations (except add/del/rename)
1308ab2a 18653+ */
4a4d8108
AM
18654+
18655+#include <linux/device_cgroup.h>
18656+#include <linux/fs_stack.h>
4a4d8108
AM
18657+#include <linux/namei.h>
18658+#include <linux/security.h>
4a4d8108
AM
18659+#include "aufs.h"
18660+
1e00d052 18661+static int h_permission(struct inode *h_inode, int mask,
79b8bda9 18662+ struct path *h_path, int brperm)
1facf9fc 18663+{
1308ab2a 18664+ int err;
4a4d8108 18665+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 18666+
e2f27e51
AM
18667+ err = -EPERM;
18668+ if (write_mask && IS_IMMUTABLE(h_inode))
18669+ goto out;
18670+
4a4d8108 18671+ err = -EACCES;
e2f27e51
AM
18672+ if (((mask & MAY_EXEC)
18673+ && S_ISREG(h_inode->i_mode)
18674+ && (path_noexec(h_path)
18675+ || !(h_inode->i_mode & S_IXUGO))))
4a4d8108
AM
18676+ goto out;
18677+
18678+ /*
18679+ * - skip the lower fs test in the case of write to ro branch.
18680+ * - nfs dir permission write check is optimized, but a policy for
18681+ * link/rename requires a real check.
b912730e
AM
18682+ * - nfs always sets MS_POSIXACL regardless its mount option 'noacl.'
18683+ * in this case, generic_permission() returns -EOPNOTSUPP.
4a4d8108
AM
18684+ */
18685+ if ((write_mask && !au_br_writable(brperm))
18686+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
18687+ && write_mask && !(mask & MAY_READ))
18688+ || !h_inode->i_op->permission) {
18689+ /* AuLabel(generic_permission); */
b912730e 18690+ /* AuDbg("get_acl %pf\n", h_inode->i_op->get_acl); */
1e00d052 18691+ err = generic_permission(h_inode, mask);
b912730e
AM
18692+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode))
18693+ err = h_inode->i_op->permission(h_inode, mask);
18694+ AuTraceErr(err);
1308ab2a 18695+ } else {
4a4d8108 18696+ /* AuLabel(h_inode->permission); */
1e00d052 18697+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
18698+ AuTraceErr(err);
18699+ }
1facf9fc 18700+
4a4d8108
AM
18701+ if (!err)
18702+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 18703+ if (!err)
4a4d8108 18704+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
18705+
18706+#if 0
18707+ if (!err) {
18708+ /* todo: do we need to call ima_path_check()? */
18709+ struct path h_path = {
18710+ .dentry =
18711+ .mnt = h_mnt
18712+ };
18713+ err = ima_path_check(&h_path,
18714+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
18715+ IMA_COUNT_LEAVE);
1308ab2a 18716+ }
4a4d8108 18717+#endif
dece6358 18718+
4f0767ce 18719+out:
1308ab2a 18720+ return err;
18721+}
dece6358 18722+
1e00d052 18723+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 18724+{
18725+ int err;
5afbbe0d 18726+ aufs_bindex_t bindex, bbot;
4a4d8108
AM
18727+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
18728+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
18729+ struct inode *h_inode;
18730+ struct super_block *sb;
18731+ struct au_branch *br;
1facf9fc 18732+
027c5e7a 18733+ /* todo: support rcu-walk? */
1e00d052 18734+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
18735+ return -ECHILD;
18736+
4a4d8108
AM
18737+ sb = inode->i_sb;
18738+ si_read_lock(sb, AuLock_FLUSH);
18739+ ii_read_lock_child(inode);
027c5e7a
AM
18740+#if 0
18741+ err = au_iigen_test(inode, au_sigen(sb));
18742+ if (unlikely(err))
18743+ goto out;
18744+#endif
dece6358 18745+
076b876e
AM
18746+ if (!isdir
18747+ || write_mask
18748+ || au_opt_test(au_mntflags(sb), DIRPERM1)) {
4a4d8108 18749+ err = au_busy_or_stale();
5afbbe0d 18750+ h_inode = au_h_iptr(inode, au_ibtop(inode));
4a4d8108
AM
18751+ if (unlikely(!h_inode
18752+ || (h_inode->i_mode & S_IFMT)
18753+ != (inode->i_mode & S_IFMT)))
18754+ goto out;
1facf9fc 18755+
4a4d8108 18756+ err = 0;
5afbbe0d 18757+ bindex = au_ibtop(inode);
4a4d8108 18758+ br = au_sbr(sb, bindex);
79b8bda9 18759+ err = h_permission(h_inode, mask, &br->br_path, br->br_perm);
4a4d8108
AM
18760+ if (write_mask
18761+ && !err
18762+ && !special_file(h_inode->i_mode)) {
18763+ /* test whether the upper writable branch exists */
18764+ err = -EROFS;
18765+ for (; bindex >= 0; bindex--)
18766+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
18767+ err = 0;
18768+ break;
18769+ }
18770+ }
18771+ goto out;
18772+ }
dece6358 18773+
4a4d8108 18774+ /* non-write to dir */
1308ab2a 18775+ err = 0;
5afbbe0d
AM
18776+ bbot = au_ibbot(inode);
18777+ for (bindex = au_ibtop(inode); !err && bindex <= bbot; bindex++) {
4a4d8108
AM
18778+ h_inode = au_h_iptr(inode, bindex);
18779+ if (h_inode) {
18780+ err = au_busy_or_stale();
18781+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
18782+ break;
18783+
18784+ br = au_sbr(sb, bindex);
79b8bda9 18785+ err = h_permission(h_inode, mask, &br->br_path,
4a4d8108
AM
18786+ br->br_perm);
18787+ }
18788+ }
1308ab2a 18789+
4f0767ce 18790+out:
4a4d8108
AM
18791+ ii_read_unlock(inode);
18792+ si_read_unlock(sb);
1308ab2a 18793+ return err;
18794+}
18795+
4a4d8108 18796+/* ---------------------------------------------------------------------- */
1facf9fc 18797+
4a4d8108 18798+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 18799+ unsigned int flags)
4a4d8108
AM
18800+{
18801+ struct dentry *ret, *parent;
b752ccd1 18802+ struct inode *inode;
4a4d8108 18803+ struct super_block *sb;
1716fcea 18804+ int err, npositive;
dece6358 18805+
4a4d8108 18806+ IMustLock(dir);
1308ab2a 18807+
537831f9
AM
18808+ /* todo: support rcu-walk? */
18809+ ret = ERR_PTR(-ECHILD);
18810+ if (flags & LOOKUP_RCU)
18811+ goto out;
18812+
18813+ ret = ERR_PTR(-ENAMETOOLONG);
18814+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
18815+ goto out;
18816+
4a4d8108 18817+ sb = dir->i_sb;
7f207e10
AM
18818+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18819+ ret = ERR_PTR(err);
18820+ if (unlikely(err))
18821+ goto out;
18822+
4a4d8108
AM
18823+ err = au_di_init(dentry);
18824+ ret = ERR_PTR(err);
18825+ if (unlikely(err))
7f207e10 18826+ goto out_si;
1308ab2a 18827+
9dbd164d 18828+ inode = NULL;
027c5e7a 18829+ npositive = 0; /* suppress a warning */
4a4d8108
AM
18830+ parent = dentry->d_parent; /* dir inode is locked */
18831+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
18832+ err = au_alive_dir(parent);
18833+ if (!err)
18834+ err = au_digen_test(parent, au_sigen(sb));
18835+ if (!err) {
5afbbe0d
AM
18836+ /* regardless LOOKUP_CREATE, always ALLOW_NEG */
18837+ npositive = au_lkup_dentry(dentry, au_dbtop(parent),
18838+ AuLkup_ALLOW_NEG);
027c5e7a
AM
18839+ err = npositive;
18840+ }
4a4d8108 18841+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
18842+ ret = ERR_PTR(err);
18843+ if (unlikely(err < 0))
18844+ goto out_unlock;
1308ab2a 18845+
4a4d8108 18846+ if (npositive) {
b752ccd1 18847+ inode = au_new_inode(dentry, /*must_new*/0);
c1595e42
JR
18848+ if (IS_ERR(inode)) {
18849+ ret = (void *)inode;
18850+ inode = NULL;
18851+ goto out_unlock;
18852+ }
9dbd164d 18853+ }
4a4d8108 18854+
c1595e42
JR
18855+ if (inode)
18856+ atomic_inc(&inode->i_count);
4a4d8108 18857+ ret = d_splice_alias(inode, dentry);
537831f9
AM
18858+#if 0
18859+ if (unlikely(d_need_lookup(dentry))) {
18860+ spin_lock(&dentry->d_lock);
18861+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
18862+ spin_unlock(&dentry->d_lock);
18863+ } else
18864+#endif
c1595e42 18865+ if (inode) {
2000de60 18866+ if (!IS_ERR(ret)) {
c1595e42 18867+ iput(inode);
2000de60
JR
18868+ if (ret && ret != dentry)
18869+ ii_write_unlock(inode);
18870+ } else {
c1595e42
JR
18871+ ii_write_unlock(inode);
18872+ iput(inode);
18873+ inode = NULL;
18874+ }
7f207e10 18875+ }
1facf9fc 18876+
4f0767ce 18877+out_unlock:
4a4d8108 18878+ di_write_unlock(dentry);
7f207e10 18879+out_si:
4a4d8108 18880+ si_read_unlock(sb);
7f207e10 18881+out:
4a4d8108
AM
18882+ return ret;
18883+}
1facf9fc 18884+
4a4d8108 18885+/* ---------------------------------------------------------------------- */
1facf9fc 18886+
b912730e
AM
18887+struct aopen_node {
18888+ struct hlist_node hlist;
18889+ struct file *file, *h_file;
18890+};
18891+
18892+static int au_do_aopen(struct inode *inode, struct file *file)
18893+{
18894+ struct au_sphlhead *aopen;
18895+ struct aopen_node *node;
18896+ struct au_do_open_args args = {
18897+ .no_lock = 1,
18898+ .open = au_do_open_nondir
18899+ };
18900+
18901+ aopen = &au_sbi(inode->i_sb)->si_aopen;
18902+ spin_lock(&aopen->spin);
18903+ hlist_for_each_entry(node, &aopen->head, hlist)
18904+ if (node->file == file) {
18905+ args.h_file = node->h_file;
18906+ break;
18907+ }
18908+ spin_unlock(&aopen->spin);
18909+ /* AuDebugOn(!args.h_file); */
18910+
18911+ return au_do_open(file, &args);
18912+}
18913+
18914+static int aufs_atomic_open(struct inode *dir, struct dentry *dentry,
18915+ struct file *file, unsigned int open_flag,
18916+ umode_t create_mode, int *opened)
18917+{
18918+ int err, h_opened = *opened;
5afbbe0d 18919+ unsigned int lkup_flags;
f0c0a007 18920+ struct dentry *parent, *d;
b912730e
AM
18921+ struct au_sphlhead *aopen;
18922+ struct vfsub_aopen_args args = {
18923+ .open_flag = open_flag,
18924+ .create_mode = create_mode,
18925+ .opened = &h_opened
18926+ };
18927+ struct aopen_node aopen_node = {
18928+ .file = file
18929+ };
18930+
18931+ IMustLock(dir);
5afbbe0d 18932+ AuDbg("open_flag 0%o\n", open_flag);
b912730e
AM
18933+ AuDbgDentry(dentry);
18934+
18935+ err = 0;
18936+ if (!au_di(dentry)) {
5afbbe0d
AM
18937+ lkup_flags = LOOKUP_OPEN;
18938+ if (open_flag & O_CREAT)
18939+ lkup_flags |= LOOKUP_CREATE;
18940+ d = aufs_lookup(dir, dentry, lkup_flags);
b912730e
AM
18941+ if (IS_ERR(d)) {
18942+ err = PTR_ERR(d);
5afbbe0d 18943+ AuTraceErr(err);
b912730e
AM
18944+ goto out;
18945+ } else if (d) {
18946+ /*
18947+ * obsoleted dentry found.
18948+ * another error will be returned later.
18949+ */
18950+ d_drop(d);
b912730e 18951+ AuDbgDentry(d);
5afbbe0d 18952+ dput(d);
b912730e
AM
18953+ }
18954+ AuDbgDentry(dentry);
18955+ }
18956+
18957+ if (d_is_positive(dentry)
18958+ || d_unhashed(dentry)
18959+ || d_unlinked(dentry)
18960+ || !(open_flag & O_CREAT))
18961+ goto out_no_open;
18962+
18963+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
18964+ if (unlikely(err))
18965+ goto out;
18966+
18967+ parent = dentry->d_parent; /* dir is locked */
18968+ di_write_lock_parent(parent);
5afbbe0d 18969+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG);
b912730e
AM
18970+ if (unlikely(err))
18971+ goto out_unlock;
18972+
18973+ AuDbgDentry(dentry);
18974+ if (d_is_positive(dentry))
18975+ goto out_unlock;
18976+
18977+ args.file = get_empty_filp();
18978+ err = PTR_ERR(args.file);
18979+ if (IS_ERR(args.file))
18980+ goto out_unlock;
18981+
18982+ args.file->f_flags = file->f_flags;
18983+ err = au_aopen_or_create(dir, dentry, &args);
18984+ AuTraceErr(err);
18985+ AuDbgFile(args.file);
18986+ if (unlikely(err < 0)) {
18987+ if (h_opened & FILE_OPENED)
18988+ fput(args.file);
18989+ else
18990+ put_filp(args.file);
18991+ goto out_unlock;
18992+ }
18993+
18994+ /* some filesystems don't set FILE_CREATED while succeeded? */
18995+ *opened |= FILE_CREATED;
18996+ if (h_opened & FILE_OPENED)
18997+ aopen_node.h_file = args.file;
18998+ else {
18999+ put_filp(args.file);
19000+ args.file = NULL;
19001+ }
19002+ aopen = &au_sbi(dir->i_sb)->si_aopen;
19003+ au_sphl_add(&aopen_node.hlist, aopen);
19004+ err = finish_open(file, dentry, au_do_aopen, opened);
19005+ au_sphl_del(&aopen_node.hlist, aopen);
19006+ AuTraceErr(err);
19007+ AuDbgFile(file);
19008+ if (aopen_node.h_file)
19009+ fput(aopen_node.h_file);
19010+
19011+out_unlock:
19012+ di_write_unlock(parent);
19013+ aufs_read_unlock(dentry, AuLock_DW);
19014+ AuDbgDentry(dentry);
f0c0a007 19015+ if (unlikely(err < 0))
b912730e
AM
19016+ goto out;
19017+out_no_open:
f0c0a007 19018+ if (err >= 0 && !(*opened & FILE_CREATED)) {
b912730e
AM
19019+ AuLabel(out_no_open);
19020+ dget(dentry);
19021+ err = finish_no_open(file, dentry);
19022+ }
19023+out:
19024+ AuDbg("%pd%s%s\n", dentry,
19025+ (*opened & FILE_CREATED) ? " created" : "",
19026+ (*opened & FILE_OPENED) ? " opened" : "");
19027+ AuTraceErr(err);
19028+ return err;
19029+}
19030+
19031+
19032+/* ---------------------------------------------------------------------- */
19033+
4a4d8108
AM
19034+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
19035+ const unsigned char add_entry, aufs_bindex_t bcpup,
5afbbe0d 19036+ aufs_bindex_t btop)
4a4d8108
AM
19037+{
19038+ int err;
19039+ struct dentry *h_parent;
19040+ struct inode *h_dir;
1facf9fc 19041+
027c5e7a 19042+ if (add_entry)
5527c038 19043+ IMustLock(d_inode(parent));
027c5e7a 19044+ else
4a4d8108
AM
19045+ di_write_lock_parent(parent);
19046+
19047+ err = 0;
19048+ if (!au_h_dptr(parent, bcpup)) {
5afbbe0d 19049+ if (btop > bcpup)
c2b27bf2 19050+ err = au_cpup_dirs(dentry, bcpup);
5afbbe0d 19051+ else if (btop < bcpup)
4a4d8108
AM
19052+ err = au_cpdown_dirs(dentry, bcpup);
19053+ else
c2b27bf2 19054+ BUG();
4a4d8108 19055+ }
38d290e6 19056+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
4a4d8108 19057+ h_parent = au_h_dptr(parent, bcpup);
5527c038 19058+ h_dir = d_inode(h_parent);
3c1bdaff 19059+ vfsub_inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
7e9cd9fe 19060+ err = au_lkup_neg(dentry, bcpup, /*wh*/0);
4a4d8108 19061+ /* todo: no unlock here */
3c1bdaff 19062+ inode_unlock_shared(h_dir);
027c5e7a
AM
19063+
19064+ AuDbg("bcpup %d\n", bcpup);
19065+ if (!err) {
5527c038 19066+ if (d_really_is_negative(dentry))
5afbbe0d 19067+ au_set_h_dptr(dentry, btop, NULL);
4a4d8108
AM
19068+ au_update_dbrange(dentry, /*do_put_zero*/0);
19069+ }
1308ab2a 19070+ }
1facf9fc 19071+
4a4d8108
AM
19072+ if (!add_entry)
19073+ di_write_unlock(parent);
19074+ if (!err)
19075+ err = bcpup; /* success */
1308ab2a 19076+
027c5e7a 19077+ AuTraceErr(err);
4a4d8108
AM
19078+ return err;
19079+}
1facf9fc 19080+
4a4d8108
AM
19081+/*
19082+ * decide the branch and the parent dir where we will create a new entry.
19083+ * returns new bindex or an error.
19084+ * copyup the parent dir if needed.
19085+ */
19086+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
19087+ struct au_wr_dir_args *args)
19088+{
19089+ int err;
392086de 19090+ unsigned int flags;
5afbbe0d 19091+ aufs_bindex_t bcpup, btop, src_btop;
86dc4139
AM
19092+ const unsigned char add_entry
19093+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
38d290e6 19094+ | au_ftest_wrdir(args->flags, TMPFILE);
4a4d8108
AM
19095+ struct super_block *sb;
19096+ struct dentry *parent;
19097+ struct au_sbinfo *sbinfo;
1facf9fc 19098+
4a4d8108
AM
19099+ sb = dentry->d_sb;
19100+ sbinfo = au_sbi(sb);
19101+ parent = dget_parent(dentry);
5afbbe0d
AM
19102+ btop = au_dbtop(dentry);
19103+ bcpup = btop;
4a4d8108
AM
19104+ if (args->force_btgt < 0) {
19105+ if (src_dentry) {
5afbbe0d
AM
19106+ src_btop = au_dbtop(src_dentry);
19107+ if (src_btop < btop)
19108+ bcpup = src_btop;
4a4d8108 19109+ } else if (add_entry) {
392086de
AM
19110+ flags = 0;
19111+ if (au_ftest_wrdir(args->flags, ISDIR))
19112+ au_fset_wbr(flags, DIR);
19113+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
19114+ bcpup = err;
19115+ }
1facf9fc 19116+
5527c038 19117+ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) {
4a4d8108
AM
19118+ if (add_entry)
19119+ err = AuWbrCopyup(sbinfo, dentry);
19120+ else {
19121+ if (!IS_ROOT(dentry)) {
19122+ di_read_lock_parent(parent, !AuLock_IR);
19123+ err = AuWbrCopyup(sbinfo, dentry);
19124+ di_read_unlock(parent, !AuLock_IR);
19125+ } else
19126+ err = AuWbrCopyup(sbinfo, dentry);
19127+ }
19128+ bcpup = err;
19129+ if (unlikely(err < 0))
19130+ goto out;
19131+ }
19132+ } else {
19133+ bcpup = args->force_btgt;
5527c038 19134+ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry)));
1308ab2a 19135+ }
027c5e7a 19136+
5afbbe0d 19137+ AuDbg("btop %d, bcpup %d\n", btop, bcpup);
4a4d8108 19138+ err = bcpup;
5afbbe0d 19139+ if (bcpup == btop)
4a4d8108 19140+ goto out; /* success */
4a4d8108
AM
19141+
19142+ /* copyup the new parent into the branch we process */
5afbbe0d 19143+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, btop);
027c5e7a 19144+ if (err >= 0) {
5527c038 19145+ if (d_really_is_negative(dentry)) {
5afbbe0d
AM
19146+ au_set_h_dptr(dentry, btop, NULL);
19147+ au_set_dbtop(dentry, bcpup);
19148+ au_set_dbbot(dentry, bcpup);
027c5e7a 19149+ }
38d290e6
JR
19150+ AuDebugOn(add_entry
19151+ && !au_ftest_wrdir(args->flags, TMPFILE)
19152+ && !au_h_dptr(dentry, bcpup));
027c5e7a 19153+ }
86dc4139
AM
19154+
19155+out:
19156+ dput(parent);
19157+ return err;
19158+}
19159+
19160+/* ---------------------------------------------------------------------- */
19161+
19162+void au_pin_hdir_unlock(struct au_pin *p)
19163+{
19164+ if (p->hdir)
5afbbe0d 19165+ au_hn_inode_unlock(p->hdir);
86dc4139
AM
19166+}
19167+
c1595e42 19168+int au_pin_hdir_lock(struct au_pin *p)
86dc4139
AM
19169+{
19170+ int err;
19171+
19172+ err = 0;
19173+ if (!p->hdir)
19174+ goto out;
19175+
19176+ /* even if an error happens later, keep this lock */
5afbbe0d 19177+ au_hn_inode_lock_nested(p->hdir, p->lsc_hi);
86dc4139
AM
19178+
19179+ err = -EBUSY;
5527c038 19180+ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent)))
86dc4139
AM
19181+ goto out;
19182+
19183+ err = 0;
19184+ if (p->h_dentry)
19185+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
19186+ p->h_parent, p->br);
19187+
19188+out:
19189+ return err;
19190+}
19191+
19192+int au_pin_hdir_relock(struct au_pin *p)
19193+{
19194+ int err, i;
19195+ struct inode *h_i;
19196+ struct dentry *h_d[] = {
19197+ p->h_dentry,
19198+ p->h_parent
19199+ };
19200+
19201+ err = au_pin_hdir_lock(p);
19202+ if (unlikely(err))
19203+ goto out;
19204+
19205+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
19206+ if (!h_d[i])
19207+ continue;
5527c038
JR
19208+ if (d_is_positive(h_d[i])) {
19209+ h_i = d_inode(h_d[i]);
86dc4139 19210+ err = !h_i->i_nlink;
5527c038 19211+ }
86dc4139
AM
19212+ }
19213+
19214+out:
19215+ return err;
19216+}
19217+
5afbbe0d 19218+static void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
86dc4139 19219+{
5afbbe0d
AM
19220+#if !defined(CONFIG_RWSEM_GENERIC_SPINLOCK) && defined(CONFIG_RWSEM_SPIN_ON_OWNER)
19221+ p->hdir->hi_inode->i_rwsem.owner = task;
86dc4139
AM
19222+#endif
19223+}
19224+
19225+void au_pin_hdir_acquire_nest(struct au_pin *p)
19226+{
19227+ if (p->hdir) {
5afbbe0d 19228+ rwsem_acquire_nest(&p->hdir->hi_inode->i_rwsem.dep_map,
86dc4139
AM
19229+ p->lsc_hi, 0, NULL, _RET_IP_);
19230+ au_pin_hdir_set_owner(p, current);
19231+ }
dece6358 19232+}
1facf9fc 19233+
86dc4139
AM
19234+void au_pin_hdir_release(struct au_pin *p)
19235+{
19236+ if (p->hdir) {
19237+ au_pin_hdir_set_owner(p, p->task);
5afbbe0d 19238+ rwsem_release(&p->hdir->hi_inode->i_rwsem.dep_map, 1, _RET_IP_);
86dc4139
AM
19239+ }
19240+}
1308ab2a 19241+
4a4d8108 19242+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 19243+{
4a4d8108
AM
19244+ if (pin && pin->parent)
19245+ return au_h_dptr(pin->parent, pin->bindex);
19246+ return NULL;
dece6358 19247+}
1facf9fc 19248+
4a4d8108 19249+void au_unpin(struct au_pin *p)
dece6358 19250+{
86dc4139
AM
19251+ if (p->hdir)
19252+ au_pin_hdir_unlock(p);
e49829fe 19253+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 19254+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
19255+ if (!p->hdir)
19256+ return;
1facf9fc 19257+
4a4d8108
AM
19258+ if (!au_ftest_pin(p->flags, DI_LOCKED))
19259+ di_read_unlock(p->parent, AuLock_IR);
19260+ iput(p->hdir->hi_inode);
19261+ dput(p->parent);
19262+ p->parent = NULL;
19263+ p->hdir = NULL;
19264+ p->h_mnt = NULL;
86dc4139 19265+ /* do not clear p->task */
4a4d8108 19266+}
1308ab2a 19267+
4a4d8108
AM
19268+int au_do_pin(struct au_pin *p)
19269+{
19270+ int err;
19271+ struct super_block *sb;
4a4d8108
AM
19272+ struct inode *h_dir;
19273+
19274+ err = 0;
19275+ sb = p->dentry->d_sb;
86dc4139 19276+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
19277+ if (IS_ROOT(p->dentry)) {
19278+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 19279+ p->h_mnt = au_br_mnt(p->br);
b4510431 19280+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
19281+ if (unlikely(err)) {
19282+ au_fclr_pin(p->flags, MNT_WRITE);
19283+ goto out_err;
19284+ }
19285+ }
dece6358 19286+ goto out;
1facf9fc 19287+ }
19288+
86dc4139 19289+ p->h_dentry = NULL;
5afbbe0d 19290+ if (p->bindex <= au_dbbot(p->dentry))
86dc4139 19291+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 19292+
4a4d8108
AM
19293+ p->parent = dget_parent(p->dentry);
19294+ if (!au_ftest_pin(p->flags, DI_LOCKED))
19295+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 19296+
4a4d8108 19297+ h_dir = NULL;
86dc4139 19298+ p->h_parent = au_h_dptr(p->parent, p->bindex);
5527c038 19299+ p->hdir = au_hi(d_inode(p->parent), p->bindex);
4a4d8108
AM
19300+ if (p->hdir)
19301+ h_dir = p->hdir->hi_inode;
dece6358 19302+
b752ccd1
AM
19303+ /*
19304+ * udba case, or
19305+ * if DI_LOCKED is not set, then p->parent may be different
19306+ * and h_parent can be NULL.
19307+ */
86dc4139 19308+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 19309+ err = -EBUSY;
4a4d8108
AM
19310+ if (!au_ftest_pin(p->flags, DI_LOCKED))
19311+ di_read_unlock(p->parent, AuLock_IR);
19312+ dput(p->parent);
19313+ p->parent = NULL;
19314+ goto out_err;
19315+ }
1308ab2a 19316+
4a4d8108 19317+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 19318+ p->h_mnt = au_br_mnt(p->br);
b4510431 19319+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 19320+ if (unlikely(err)) {
4a4d8108 19321+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
19322+ if (!au_ftest_pin(p->flags, DI_LOCKED))
19323+ di_read_unlock(p->parent, AuLock_IR);
19324+ dput(p->parent);
19325+ p->parent = NULL;
19326+ goto out_err;
dece6358
AM
19327+ }
19328+ }
4a4d8108 19329+
86dc4139
AM
19330+ au_igrab(h_dir);
19331+ err = au_pin_hdir_lock(p);
19332+ if (!err)
19333+ goto out; /* success */
19334+
076b876e
AM
19335+ au_unpin(p);
19336+
4f0767ce 19337+out_err:
4a4d8108
AM
19338+ pr_err("err %d\n", err);
19339+ err = au_busy_or_stale();
4f0767ce 19340+out:
1facf9fc 19341+ return err;
19342+}
19343+
4a4d8108
AM
19344+void au_pin_init(struct au_pin *p, struct dentry *dentry,
19345+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
19346+ unsigned int udba, unsigned char flags)
19347+{
19348+ p->dentry = dentry;
19349+ p->udba = udba;
19350+ p->lsc_di = lsc_di;
19351+ p->lsc_hi = lsc_hi;
19352+ p->flags = flags;
19353+ p->bindex = bindex;
19354+
19355+ p->parent = NULL;
19356+ p->hdir = NULL;
19357+ p->h_mnt = NULL;
86dc4139
AM
19358+
19359+ p->h_dentry = NULL;
19360+ p->h_parent = NULL;
19361+ p->br = NULL;
19362+ p->task = current;
4a4d8108
AM
19363+}
19364+
19365+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
19366+ unsigned int udba, unsigned char flags)
19367+{
19368+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
19369+ udba, flags);
19370+ return au_do_pin(pin);
19371+}
19372+
dece6358
AM
19373+/* ---------------------------------------------------------------------- */
19374+
1308ab2a 19375+/*
4a4d8108
AM
19376+ * ->setattr() and ->getattr() are called in various cases.
19377+ * chmod, stat: dentry is revalidated.
19378+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
19379+ * unhashed.
19380+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 19381+ */
027c5e7a 19382+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
c1595e42 19383+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 19384+{
4a4d8108 19385+ int err;
4a4d8108 19386+ struct dentry *parent;
1facf9fc 19387+
1308ab2a 19388+ err = 0;
027c5e7a 19389+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
19390+ parent = dget_parent(dentry);
19391+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 19392+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
19393+ di_read_unlock(parent, AuLock_IR);
19394+ dput(parent);
dece6358 19395+ }
1facf9fc 19396+
4a4d8108 19397+ AuTraceErr(err);
1308ab2a 19398+ return err;
19399+}
dece6358 19400+
c1595e42
JR
19401+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
19402+ struct au_icpup_args *a)
1308ab2a 19403+{
19404+ int err;
4a4d8108 19405+ loff_t sz;
5afbbe0d 19406+ aufs_bindex_t btop, ibtop;
4a4d8108
AM
19407+ struct dentry *hi_wh, *parent;
19408+ struct inode *inode;
4a4d8108
AM
19409+ struct au_wr_dir_args wr_dir_args = {
19410+ .force_btgt = -1,
19411+ .flags = 0
19412+ };
19413+
2000de60 19414+ if (d_is_dir(dentry))
4a4d8108
AM
19415+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
19416+ /* plink or hi_wh() case */
5afbbe0d 19417+ btop = au_dbtop(dentry);
5527c038 19418+ inode = d_inode(dentry);
5afbbe0d
AM
19419+ ibtop = au_ibtop(inode);
19420+ if (btop != ibtop && !au_test_ro(inode->i_sb, ibtop, inode))
19421+ wr_dir_args.force_btgt = ibtop;
4a4d8108
AM
19422+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
19423+ if (unlikely(err < 0))
19424+ goto out;
19425+ a->btgt = err;
5afbbe0d 19426+ if (err != btop)
4a4d8108
AM
19427+ au_fset_icpup(a->flags, DID_CPUP);
19428+
19429+ err = 0;
19430+ a->pin_flags = AuPin_MNT_WRITE;
19431+ parent = NULL;
19432+ if (!IS_ROOT(dentry)) {
19433+ au_fset_pin(a->pin_flags, DI_LOCKED);
19434+ parent = dget_parent(dentry);
19435+ di_write_lock_parent(parent);
19436+ }
19437+
19438+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
19439+ if (unlikely(err))
19440+ goto out_parent;
19441+
4a4d8108 19442+ sz = -1;
5afbbe0d 19443+ a->h_path.dentry = au_h_dptr(dentry, btop);
5527c038 19444+ a->h_inode = d_inode(a->h_path.dentry);
c1595e42 19445+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
3c1bdaff 19446+ vfsub_inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
c1595e42
JR
19447+ if (ia->ia_size < i_size_read(a->h_inode))
19448+ sz = ia->ia_size;
3c1bdaff 19449+ inode_unlock_shared(a->h_inode);
c1595e42 19450+ }
4a4d8108 19451+
4a4d8108 19452+ hi_wh = NULL;
027c5e7a 19453+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
19454+ hi_wh = au_hi_wh(inode, a->btgt);
19455+ if (!hi_wh) {
c2b27bf2
AM
19456+ struct au_cp_generic cpg = {
19457+ .dentry = dentry,
19458+ .bdst = a->btgt,
19459+ .bsrc = -1,
19460+ .len = sz,
19461+ .pin = &a->pin
19462+ };
19463+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
19464+ if (unlikely(err))
19465+ goto out_unlock;
19466+ hi_wh = au_hi_wh(inode, a->btgt);
19467+ /* todo: revalidate hi_wh? */
19468+ }
19469+ }
19470+
19471+ if (parent) {
19472+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
19473+ di_downgrade_lock(parent, AuLock_IR);
19474+ dput(parent);
19475+ parent = NULL;
19476+ }
19477+ if (!au_ftest_icpup(a->flags, DID_CPUP))
19478+ goto out; /* success */
19479+
19480+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
19481+ struct au_cp_generic cpg = {
19482+ .dentry = dentry,
19483+ .bdst = a->btgt,
5afbbe0d 19484+ .bsrc = btop,
c2b27bf2
AM
19485+ .len = sz,
19486+ .pin = &a->pin,
19487+ .flags = AuCpup_DTIME | AuCpup_HOPEN
19488+ };
19489+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
19490+ if (!err)
19491+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
19492+ } else if (!hi_wh)
19493+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
19494+ else
19495+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 19496+
4f0767ce 19497+out_unlock:
5527c038 19498+ a->h_inode = d_inode(a->h_path.dentry);
86dc4139 19499+ if (!err)
dece6358 19500+ goto out; /* success */
4a4d8108 19501+ au_unpin(&a->pin);
4f0767ce 19502+out_parent:
4a4d8108
AM
19503+ if (parent) {
19504+ di_write_unlock(parent);
19505+ dput(parent);
19506+ }
4f0767ce 19507+out:
86dc4139 19508+ if (!err)
febd17d6 19509+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
1facf9fc 19510+ return err;
19511+}
19512+
4a4d8108 19513+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 19514+{
4a4d8108 19515+ int err;
523b37e3 19516+ struct inode *inode, *delegated;
4a4d8108
AM
19517+ struct super_block *sb;
19518+ struct file *file;
19519+ struct au_icpup_args *a;
1facf9fc 19520+
5527c038 19521+ inode = d_inode(dentry);
4a4d8108 19522+ IMustLock(inode);
dece6358 19523+
f2c43d5f
AM
19524+ err = setattr_prepare(dentry, ia);
19525+ if (unlikely(err))
19526+ goto out;
19527+
4a4d8108
AM
19528+ err = -ENOMEM;
19529+ a = kzalloc(sizeof(*a), GFP_NOFS);
19530+ if (unlikely(!a))
19531+ goto out;
1facf9fc 19532+
4a4d8108
AM
19533+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
19534+ ia->ia_valid &= ~ATTR_MODE;
dece6358 19535+
4a4d8108
AM
19536+ file = NULL;
19537+ sb = dentry->d_sb;
e49829fe
JR
19538+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
19539+ if (unlikely(err))
19540+ goto out_kfree;
19541+
4a4d8108
AM
19542+ if (ia->ia_valid & ATTR_FILE) {
19543+ /* currently ftruncate(2) only */
7e9cd9fe 19544+ AuDebugOn(!d_is_reg(dentry));
4a4d8108 19545+ file = ia->ia_file;
521ced18
JR
19546+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1,
19547+ /*fi_lsc*/0);
4a4d8108
AM
19548+ if (unlikely(err))
19549+ goto out_si;
19550+ ia->ia_file = au_hf_top(file);
19551+ a->udba = AuOpt_UDBA_NONE;
19552+ } else {
19553+ /* fchmod() doesn't pass ia_file */
19554+ a->udba = au_opt_udba(sb);
027c5e7a
AM
19555+ di_write_lock_child(dentry);
19556+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
19557+ if (d_unhashed(dentry))
19558+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
19559+ if (a->udba != AuOpt_UDBA_NONE) {
19560+ AuDebugOn(IS_ROOT(dentry));
19561+ err = au_reval_for_attr(dentry, au_sigen(sb));
19562+ if (unlikely(err))
19563+ goto out_dentry;
19564+ }
dece6358 19565+ }
dece6358 19566+
4a4d8108
AM
19567+ err = au_pin_and_icpup(dentry, ia, a);
19568+ if (unlikely(err < 0))
19569+ goto out_dentry;
19570+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
19571+ ia->ia_file = NULL;
19572+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 19573+ }
dece6358 19574+
4a4d8108
AM
19575+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
19576+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
19577+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 19578+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
19579+ if (unlikely(err))
19580+ goto out_unlock;
19581+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
19582+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 19583+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
19584+ if (unlikely(err))
19585+ goto out_unlock;
19586+ }
dece6358 19587+
4a4d8108
AM
19588+ if (ia->ia_valid & ATTR_SIZE) {
19589+ struct file *f;
1308ab2a 19590+
953406b4 19591+ if (ia->ia_size < i_size_read(inode))
4a4d8108 19592+ /* unmap only */
953406b4 19593+ truncate_setsize(inode, ia->ia_size);
1308ab2a 19594+
4a4d8108
AM
19595+ f = NULL;
19596+ if (ia->ia_valid & ATTR_FILE)
19597+ f = ia->ia_file;
febd17d6 19598+ inode_unlock(a->h_inode);
4a4d8108 19599+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
febd17d6 19600+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
523b37e3
AM
19601+ } else {
19602+ delegated = NULL;
19603+ while (1) {
19604+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
19605+ if (delegated) {
19606+ err = break_deleg_wait(&delegated);
19607+ if (!err)
19608+ continue;
19609+ }
19610+ break;
19611+ }
19612+ }
8cdd5066
JR
19613+ /*
19614+ * regardless aufs 'acl' option setting.
19615+ * why don't all acl-aware fs call this func from their ->setattr()?
19616+ */
19617+ if (!err && (ia->ia_valid & ATTR_MODE))
19618+ err = vfsub_acl_chmod(a->h_inode, ia->ia_mode);
4a4d8108
AM
19619+ if (!err)
19620+ au_cpup_attr_changeable(inode);
1308ab2a 19621+
4f0767ce 19622+out_unlock:
febd17d6 19623+ inode_unlock(a->h_inode);
4a4d8108 19624+ au_unpin(&a->pin);
027c5e7a 19625+ if (unlikely(err))
5afbbe0d 19626+ au_update_dbtop(dentry);
4f0767ce 19627+out_dentry:
4a4d8108
AM
19628+ di_write_unlock(dentry);
19629+ if (file) {
19630+ fi_write_unlock(file);
19631+ ia->ia_file = file;
19632+ ia->ia_valid |= ATTR_FILE;
19633+ }
4f0767ce 19634+out_si:
4a4d8108 19635+ si_read_unlock(sb);
e49829fe 19636+out_kfree:
1c60b727 19637+ kfree(a);
4f0767ce 19638+out:
4a4d8108
AM
19639+ AuTraceErr(err);
19640+ return err;
1facf9fc 19641+}
19642+
c1595e42
JR
19643+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
19644+static int au_h_path_to_set_attr(struct dentry *dentry,
19645+ struct au_icpup_args *a, struct path *h_path)
19646+{
19647+ int err;
19648+ struct super_block *sb;
19649+
19650+ sb = dentry->d_sb;
19651+ a->udba = au_opt_udba(sb);
19652+ /* no d_unlinked(), to set UDBA_NONE for root */
19653+ if (d_unhashed(dentry))
19654+ a->udba = AuOpt_UDBA_NONE;
19655+ if (a->udba != AuOpt_UDBA_NONE) {
19656+ AuDebugOn(IS_ROOT(dentry));
19657+ err = au_reval_for_attr(dentry, au_sigen(sb));
19658+ if (unlikely(err))
19659+ goto out;
19660+ }
19661+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a);
19662+ if (unlikely(err < 0))
19663+ goto out;
19664+
19665+ h_path->dentry = a->h_path.dentry;
19666+ h_path->mnt = au_sbr_mnt(sb, a->btgt);
19667+
19668+out:
19669+ return err;
19670+}
19671+
f2c43d5f
AM
19672+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
19673+ struct au_sxattr *arg)
c1595e42
JR
19674+{
19675+ int err;
19676+ struct path h_path;
19677+ struct super_block *sb;
19678+ struct au_icpup_args *a;
5afbbe0d 19679+ struct inode *h_inode;
c1595e42 19680+
c1595e42
JR
19681+ IMustLock(inode);
19682+
19683+ err = -ENOMEM;
19684+ a = kzalloc(sizeof(*a), GFP_NOFS);
19685+ if (unlikely(!a))
19686+ goto out;
19687+
19688+ sb = dentry->d_sb;
19689+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
19690+ if (unlikely(err))
19691+ goto out_kfree;
19692+
19693+ h_path.dentry = NULL; /* silence gcc */
19694+ di_write_lock_child(dentry);
19695+ err = au_h_path_to_set_attr(dentry, a, &h_path);
19696+ if (unlikely(err))
19697+ goto out_di;
19698+
febd17d6 19699+ inode_unlock(a->h_inode);
c1595e42
JR
19700+ switch (arg->type) {
19701+ case AU_XATTR_SET:
5afbbe0d 19702+ AuDebugOn(d_is_negative(h_path.dentry));
c1595e42
JR
19703+ err = vfsub_setxattr(h_path.dentry,
19704+ arg->u.set.name, arg->u.set.value,
19705+ arg->u.set.size, arg->u.set.flags);
19706+ break;
c1595e42
JR
19707+ case AU_ACL_SET:
19708+ err = -EOPNOTSUPP;
5527c038 19709+ h_inode = d_inode(h_path.dentry);
c1595e42 19710+ if (h_inode->i_op->set_acl)
f2c43d5f 19711+ /* this will call posix_acl_update_mode */
c1595e42
JR
19712+ err = h_inode->i_op->set_acl(h_inode,
19713+ arg->u.acl_set.acl,
19714+ arg->u.acl_set.type);
19715+ break;
19716+ }
19717+ if (!err)
19718+ au_cpup_attr_timesizes(inode);
19719+
19720+ au_unpin(&a->pin);
19721+ if (unlikely(err))
5afbbe0d 19722+ au_update_dbtop(dentry);
c1595e42
JR
19723+
19724+out_di:
19725+ di_write_unlock(dentry);
19726+ si_read_unlock(sb);
19727+out_kfree:
1c60b727 19728+ kfree(a);
c1595e42
JR
19729+out:
19730+ AuTraceErr(err);
19731+ return err;
19732+}
19733+#endif
19734+
4a4d8108
AM
19735+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
19736+ unsigned int nlink)
1facf9fc 19737+{
9dbd164d
AM
19738+ unsigned int n;
19739+
4a4d8108 19740+ inode->i_mode = st->mode;
86dc4139
AM
19741+ /* don't i_[ug]id_write() here */
19742+ inode->i_uid = st->uid;
19743+ inode->i_gid = st->gid;
4a4d8108
AM
19744+ inode->i_atime = st->atime;
19745+ inode->i_mtime = st->mtime;
19746+ inode->i_ctime = st->ctime;
1facf9fc 19747+
4a4d8108
AM
19748+ au_cpup_attr_nlink(inode, /*force*/0);
19749+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
19750+ n = inode->i_nlink;
19751+ n -= nlink;
19752+ n += st->nlink;
f6b6e03d 19753+ smp_mb(); /* for i_nlink */
7eafdf33 19754+ /* 0 can happen */
92d182d2 19755+ set_nlink(inode, n);
4a4d8108 19756+ }
1facf9fc 19757+
4a4d8108
AM
19758+ spin_lock(&inode->i_lock);
19759+ inode->i_blocks = st->blocks;
19760+ i_size_write(inode, st->size);
19761+ spin_unlock(&inode->i_lock);
1facf9fc 19762+}
19763+
c1595e42 19764+/*
f2c43d5f 19765+ * common routine for aufs_getattr() and au_getxattr().
c1595e42
JR
19766+ * returns zero or negative (an error).
19767+ * @dentry will be read-locked in success.
19768+ */
a2654f78
AM
19769+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
19770+ int locked)
1facf9fc 19771+{
4a4d8108 19772+ int err;
076b876e 19773+ unsigned int mnt_flags, sigen;
c1595e42 19774+ unsigned char udba_none;
4a4d8108 19775+ aufs_bindex_t bindex;
4a4d8108
AM
19776+ struct super_block *sb, *h_sb;
19777+ struct inode *inode;
1facf9fc 19778+
c1595e42
JR
19779+ h_path->mnt = NULL;
19780+ h_path->dentry = NULL;
19781+
19782+ err = 0;
4a4d8108 19783+ sb = dentry->d_sb;
4a4d8108
AM
19784+ mnt_flags = au_mntflags(sb);
19785+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 19786+
a2654f78
AM
19787+ if (unlikely(locked))
19788+ goto body; /* skip locking dinfo */
19789+
4a4d8108 19790+ /* support fstat(2) */
027c5e7a 19791+ if (!d_unlinked(dentry) && !udba_none) {
076b876e 19792+ sigen = au_sigen(sb);
027c5e7a
AM
19793+ err = au_digen_test(dentry, sigen);
19794+ if (!err) {
4a4d8108 19795+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a 19796+ err = au_dbrange_test(dentry);
c1595e42
JR
19797+ if (unlikely(err)) {
19798+ di_read_unlock(dentry, AuLock_IR);
19799+ goto out;
19800+ }
027c5e7a 19801+ } else {
4a4d8108
AM
19802+ AuDebugOn(IS_ROOT(dentry));
19803+ di_write_lock_child(dentry);
027c5e7a
AM
19804+ err = au_dbrange_test(dentry);
19805+ if (!err)
19806+ err = au_reval_for_attr(dentry, sigen);
c1595e42
JR
19807+ if (!err)
19808+ di_downgrade_lock(dentry, AuLock_IR);
19809+ else {
19810+ di_write_unlock(dentry);
19811+ goto out;
19812+ }
4a4d8108
AM
19813+ }
19814+ } else
19815+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 19816+
a2654f78 19817+body:
5527c038 19818+ inode = d_inode(dentry);
5afbbe0d 19819+ bindex = au_ibtop(inode);
c1595e42
JR
19820+ h_path->mnt = au_sbr_mnt(sb, bindex);
19821+ h_sb = h_path->mnt->mnt_sb;
19822+ if (!force
19823+ && !au_test_fs_bad_iattr(h_sb)
19824+ && udba_none)
19825+ goto out; /* success */
1facf9fc 19826+
5afbbe0d 19827+ if (au_dbtop(dentry) == bindex)
c1595e42 19828+ h_path->dentry = au_h_dptr(dentry, bindex);
4a4d8108 19829+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c1595e42
JR
19830+ h_path->dentry = au_plink_lkup(inode, bindex);
19831+ if (IS_ERR(h_path->dentry))
19832+ /* pretending success */
19833+ h_path->dentry = NULL;
19834+ else
19835+ dput(h_path->dentry);
4a4d8108 19836+ }
c1595e42
JR
19837+
19838+out:
19839+ return err;
19840+}
19841+
521ced18
JR
19842+static int aufs_getattr(const struct path *path, struct kstat *st,
19843+ u32 request, unsigned int query)
c1595e42
JR
19844+{
19845+ int err;
19846+ unsigned char positive;
19847+ struct path h_path;
521ced18 19848+ struct dentry *dentry;
c1595e42
JR
19849+ struct inode *inode;
19850+ struct super_block *sb;
19851+
521ced18 19852+ dentry = path->dentry;
5527c038 19853+ inode = d_inode(dentry);
c1595e42
JR
19854+ sb = dentry->d_sb;
19855+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
19856+ if (unlikely(err))
19857+ goto out;
a2654f78 19858+ err = au_h_path_getattr(dentry, /*force*/0, &h_path, /*locked*/0);
c1595e42
JR
19859+ if (unlikely(err))
19860+ goto out_si;
c06a8ce3 19861+ if (unlikely(!h_path.dentry))
c1595e42 19862+ /* illegally overlapped or something */
4a4d8108
AM
19863+ goto out_fill; /* pretending success */
19864+
5527c038 19865+ positive = d_is_positive(h_path.dentry);
4a4d8108 19866+ if (positive)
521ced18
JR
19867+ /* no vfsub version */
19868+ err = vfs_getattr(&h_path, st, request, query);
4a4d8108
AM
19869+ if (!err) {
19870+ if (positive)
c06a8ce3 19871+ au_refresh_iattr(inode, st,
5527c038 19872+ d_inode(h_path.dentry)->i_nlink);
4a4d8108 19873+ goto out_fill; /* success */
1facf9fc 19874+ }
7f207e10 19875+ AuTraceErr(err);
c1595e42 19876+ goto out_di;
4a4d8108 19877+
4f0767ce 19878+out_fill:
4a4d8108 19879+ generic_fillattr(inode, st);
c1595e42 19880+out_di:
4a4d8108 19881+ di_read_unlock(dentry, AuLock_IR);
c1595e42 19882+out_si:
4a4d8108 19883+ si_read_unlock(sb);
7f207e10
AM
19884+out:
19885+ AuTraceErr(err);
4a4d8108 19886+ return err;
1facf9fc 19887+}
19888+
19889+/* ---------------------------------------------------------------------- */
19890+
febd17d6
JR
19891+static const char *aufs_get_link(struct dentry *dentry, struct inode *inode,
19892+ struct delayed_call *done)
4a4d8108 19893+{
c2c0f25c 19894+ const char *ret;
c2c0f25c 19895+ struct dentry *h_dentry;
febd17d6 19896+ struct inode *h_inode;
4a4d8108 19897+ int err;
c2c0f25c 19898+ aufs_bindex_t bindex;
1facf9fc 19899+
79b8bda9 19900+ ret = NULL; /* suppress a warning */
febd17d6
JR
19901+ err = -ECHILD;
19902+ if (!dentry)
19903+ goto out;
19904+
027c5e7a
AM
19905+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
19906+ if (unlikely(err))
c2c0f25c 19907+ goto out;
027c5e7a
AM
19908+
19909+ err = au_d_hashed_positive(dentry);
c2c0f25c
AM
19910+ if (unlikely(err))
19911+ goto out_unlock;
19912+
19913+ err = -EINVAL;
19914+ inode = d_inode(dentry);
5afbbe0d 19915+ bindex = au_ibtop(inode);
c2c0f25c 19916+ h_inode = au_h_iptr(inode, bindex);
febd17d6 19917+ if (unlikely(!h_inode->i_op->get_link))
c2c0f25c
AM
19918+ goto out_unlock;
19919+
19920+ err = -EBUSY;
19921+ h_dentry = NULL;
5afbbe0d 19922+ if (au_dbtop(dentry) <= bindex) {
c2c0f25c
AM
19923+ h_dentry = au_h_dptr(dentry, bindex);
19924+ if (h_dentry)
19925+ dget(h_dentry);
027c5e7a 19926+ }
c2c0f25c
AM
19927+ if (!h_dentry) {
19928+ h_dentry = d_find_any_alias(h_inode);
19929+ if (IS_ERR(h_dentry)) {
19930+ err = PTR_ERR(h_dentry);
febd17d6 19931+ goto out_unlock;
c2c0f25c
AM
19932+ }
19933+ }
19934+ if (unlikely(!h_dentry))
febd17d6 19935+ goto out_unlock;
1facf9fc 19936+
c2c0f25c 19937+ err = 0;
febd17d6 19938+ AuDbg("%pf\n", h_inode->i_op->get_link);
c2c0f25c 19939+ AuDbgDentry(h_dentry);
f2c43d5f 19940+ ret = vfs_get_link(h_dentry, done);
c2c0f25c 19941+ dput(h_dentry);
febd17d6
JR
19942+ if (IS_ERR(ret))
19943+ err = PTR_ERR(ret);
c2c0f25c 19944+
c2c0f25c
AM
19945+out_unlock:
19946+ aufs_read_unlock(dentry, AuLock_IR);
4f0767ce 19947+out:
c2c0f25c
AM
19948+ if (unlikely(err))
19949+ ret = ERR_PTR(err);
19950+ AuTraceErrPtr(ret);
19951+ return ret;
4a4d8108 19952+}
1facf9fc 19953+
4a4d8108 19954+/* ---------------------------------------------------------------------- */
1facf9fc 19955+
e2f27e51
AM
19956+static int au_is_special(struct inode *inode)
19957+{
19958+ return (inode->i_mode & (S_IFBLK | S_IFCHR | S_IFIFO | S_IFSOCK));
19959+}
19960+
0c3ec466 19961+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 19962+{
0c3ec466 19963+ int err;
e2f27e51 19964+ aufs_bindex_t bindex;
0c3ec466
AM
19965+ struct super_block *sb;
19966+ struct inode *h_inode;
e2f27e51 19967+ struct vfsmount *h_mnt;
0c3ec466
AM
19968+
19969+ sb = inode->i_sb;
e2f27e51
AM
19970+ WARN_ONCE((flags & S_ATIME) && !IS_NOATIME(inode),
19971+ "unexpected s_flags 0x%lx", sb->s_flags);
19972+
0c3ec466
AM
19973+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
19974+ lockdep_off();
19975+ si_read_lock(sb, AuLock_FLUSH);
19976+ ii_write_lock_child(inode);
19977+ lockdep_on();
e2f27e51
AM
19978+
19979+ err = 0;
19980+ bindex = au_ibtop(inode);
19981+ h_inode = au_h_iptr(inode, bindex);
19982+ if (!au_test_ro(sb, bindex, inode)) {
19983+ h_mnt = au_sbr_mnt(sb, bindex);
19984+ err = vfsub_mnt_want_write(h_mnt);
19985+ if (!err) {
19986+ err = vfsub_update_time(h_inode, ts, flags);
19987+ vfsub_mnt_drop_write(h_mnt);
19988+ }
19989+ } else if (au_is_special(h_inode)) {
19990+ /*
19991+ * Never copy-up here.
19992+ * These special files may already be opened and used for
19993+ * communicating. If we copied it up, then the communication
19994+ * would be corrupted.
19995+ */
19996+ AuWarn1("timestamps for i%lu are ignored "
19997+ "since it is on readonly branch (hi%lu).\n",
19998+ inode->i_ino, h_inode->i_ino);
19999+ } else if (flags & ~S_ATIME) {
20000+ err = -EIO;
20001+ AuIOErr1("unexpected flags 0x%x\n", flags);
20002+ AuDebugOn(1);
20003+ }
20004+
0c3ec466 20005+ lockdep_off();
38d290e6
JR
20006+ if (!err)
20007+ au_cpup_attr_timesizes(inode);
0c3ec466
AM
20008+ ii_write_unlock(inode);
20009+ si_read_unlock(sb);
20010+ lockdep_on();
38d290e6
JR
20011+
20012+ if (!err && (flags & S_VERSION))
20013+ inode_inc_iversion(inode);
20014+
0c3ec466 20015+ return err;
4a4d8108 20016+}
1facf9fc 20017+
4a4d8108 20018+/* ---------------------------------------------------------------------- */
1308ab2a 20019+
b95c5147
AM
20020+/* no getattr version will be set by module.c:aufs_init() */
20021+struct inode_operations aufs_iop_nogetattr[AuIop_Last],
20022+ aufs_iop[] = {
20023+ [AuIop_SYMLINK] = {
20024+ .permission = aufs_permission,
c1595e42 20025+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
20026+ .get_acl = aufs_get_acl,
20027+ .set_acl = aufs_set_acl, /* unsupport for symlink? */
c1595e42
JR
20028+#endif
20029+
b95c5147
AM
20030+ .setattr = aufs_setattr,
20031+ .getattr = aufs_getattr,
0c3ec466 20032+
c1595e42 20033+#ifdef CONFIG_AUFS_XATTR
b95c5147 20034+ .listxattr = aufs_listxattr,
c1595e42
JR
20035+#endif
20036+
febd17d6 20037+ .get_link = aufs_get_link,
0c3ec466 20038+
b95c5147
AM
20039+ /* .update_time = aufs_update_time */
20040+ },
20041+ [AuIop_DIR] = {
20042+ .create = aufs_create,
20043+ .lookup = aufs_lookup,
20044+ .link = aufs_link,
20045+ .unlink = aufs_unlink,
20046+ .symlink = aufs_symlink,
20047+ .mkdir = aufs_mkdir,
20048+ .rmdir = aufs_rmdir,
20049+ .mknod = aufs_mknod,
20050+ .rename = aufs_rename,
20051+
20052+ .permission = aufs_permission,
c1595e42 20053+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
20054+ .get_acl = aufs_get_acl,
20055+ .set_acl = aufs_set_acl,
c1595e42
JR
20056+#endif
20057+
b95c5147
AM
20058+ .setattr = aufs_setattr,
20059+ .getattr = aufs_getattr,
0c3ec466 20060+
c1595e42 20061+#ifdef CONFIG_AUFS_XATTR
b95c5147 20062+ .listxattr = aufs_listxattr,
c1595e42
JR
20063+#endif
20064+
b95c5147
AM
20065+ .update_time = aufs_update_time,
20066+ .atomic_open = aufs_atomic_open,
20067+ .tmpfile = aufs_tmpfile
20068+ },
20069+ [AuIop_OTHER] = {
20070+ .permission = aufs_permission,
c1595e42 20071+#ifdef CONFIG_FS_POSIX_ACL
b95c5147
AM
20072+ .get_acl = aufs_get_acl,
20073+ .set_acl = aufs_set_acl,
c1595e42
JR
20074+#endif
20075+
b95c5147
AM
20076+ .setattr = aufs_setattr,
20077+ .getattr = aufs_getattr,
0c3ec466 20078+
c1595e42 20079+#ifdef CONFIG_AUFS_XATTR
b95c5147 20080+ .listxattr = aufs_listxattr,
c1595e42
JR
20081+#endif
20082+
b95c5147
AM
20083+ .update_time = aufs_update_time
20084+ }
4a4d8108 20085+};
7f207e10
AM
20086diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
20087--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 20088+++ linux/fs/aufs/i_op_del.c 2017-07-29 12:14:25.903042072 +0200
5afbbe0d 20089@@ -0,0 +1,511 @@
1facf9fc 20090+/*
a2654f78 20091+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 20092+ *
20093+ * This program, aufs is free software; you can redistribute it and/or modify
20094+ * it under the terms of the GNU General Public License as published by
20095+ * the Free Software Foundation; either version 2 of the License, or
20096+ * (at your option) any later version.
dece6358
AM
20097+ *
20098+ * This program is distributed in the hope that it will be useful,
20099+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20100+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20101+ * GNU General Public License for more details.
20102+ *
20103+ * You should have received a copy of the GNU General Public License
523b37e3 20104+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 20105+ */
20106+
20107+/*
4a4d8108 20108+ * inode operations (del entry)
1308ab2a 20109+ */
dece6358 20110+
1308ab2a 20111+#include "aufs.h"
dece6358 20112+
4a4d8108
AM
20113+/*
20114+ * decide if a new whiteout for @dentry is necessary or not.
20115+ * when it is necessary, prepare the parent dir for the upper branch whose
20116+ * branch index is @bcpup for creation. the actual creation of the whiteout will
20117+ * be done by caller.
20118+ * return value:
20119+ * 0: wh is unnecessary
20120+ * plus: wh is necessary
20121+ * minus: error
20122+ */
20123+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 20124+{
4a4d8108 20125+ int need_wh, err;
5afbbe0d 20126+ aufs_bindex_t btop;
4a4d8108 20127+ struct super_block *sb;
dece6358 20128+
4a4d8108 20129+ sb = dentry->d_sb;
5afbbe0d 20130+ btop = au_dbtop(dentry);
4a4d8108 20131+ if (*bcpup < 0) {
5afbbe0d
AM
20132+ *bcpup = btop;
20133+ if (au_test_ro(sb, btop, d_inode(dentry))) {
4a4d8108
AM
20134+ err = AuWbrCopyup(au_sbi(sb), dentry);
20135+ *bcpup = err;
20136+ if (unlikely(err < 0))
20137+ goto out;
20138+ }
20139+ } else
5afbbe0d 20140+ AuDebugOn(btop < *bcpup
5527c038 20141+ || au_test_ro(sb, *bcpup, d_inode(dentry)));
5afbbe0d 20142+ AuDbg("bcpup %d, btop %d\n", *bcpup, btop);
1308ab2a 20143+
5afbbe0d 20144+ if (*bcpup != btop) {
4a4d8108
AM
20145+ err = au_cpup_dirs(dentry, *bcpup);
20146+ if (unlikely(err))
20147+ goto out;
20148+ need_wh = 1;
20149+ } else {
027c5e7a 20150+ struct au_dinfo *dinfo, *tmp;
4a4d8108 20151+
027c5e7a
AM
20152+ need_wh = -ENOMEM;
20153+ dinfo = au_di(dentry);
20154+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
20155+ if (tmp) {
20156+ au_di_cp(tmp, dinfo);
20157+ au_di_swap(tmp, dinfo);
20158+ /* returns the number of positive dentries */
5afbbe0d
AM
20159+ need_wh = au_lkup_dentry(dentry, btop + 1,
20160+ /* AuLkup_IGNORE_PERM */ 0);
027c5e7a
AM
20161+ au_di_swap(tmp, dinfo);
20162+ au_rw_write_unlock(&tmp->di_rwsem);
20163+ au_di_free(tmp);
4a4d8108
AM
20164+ }
20165+ }
20166+ AuDbg("need_wh %d\n", need_wh);
20167+ err = need_wh;
20168+
4f0767ce 20169+out:
4a4d8108 20170+ return err;
1facf9fc 20171+}
20172+
4a4d8108
AM
20173+/*
20174+ * simple tests for the del-entry operations.
20175+ * following the checks in vfs, plus the parent-child relationship.
20176+ */
20177+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
20178+ struct dentry *h_parent, int isdir)
1facf9fc 20179+{
4a4d8108
AM
20180+ int err;
20181+ umode_t h_mode;
20182+ struct dentry *h_dentry, *h_latest;
1308ab2a 20183+ struct inode *h_inode;
1facf9fc 20184+
4a4d8108 20185+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 20186+ if (d_really_is_positive(dentry)) {
4a4d8108 20187+ err = -ENOENT;
5527c038
JR
20188+ if (unlikely(d_is_negative(h_dentry)))
20189+ goto out;
20190+ h_inode = d_inode(h_dentry);
20191+ if (unlikely(!h_inode->i_nlink))
4a4d8108 20192+ goto out;
1facf9fc 20193+
4a4d8108
AM
20194+ h_mode = h_inode->i_mode;
20195+ if (!isdir) {
20196+ err = -EISDIR;
20197+ if (unlikely(S_ISDIR(h_mode)))
20198+ goto out;
20199+ } else if (unlikely(!S_ISDIR(h_mode))) {
20200+ err = -ENOTDIR;
20201+ goto out;
20202+ }
20203+ } else {
20204+ /* rename(2) case */
20205+ err = -EIO;
5527c038 20206+ if (unlikely(d_is_positive(h_dentry)))
4a4d8108
AM
20207+ goto out;
20208+ }
1facf9fc 20209+
4a4d8108
AM
20210+ err = -ENOENT;
20211+ /* expected parent dir is locked */
20212+ if (unlikely(h_parent != h_dentry->d_parent))
20213+ goto out;
20214+ err = 0;
20215+
20216+ /*
20217+ * rmdir a dir may break the consistency on some filesystem.
20218+ * let's try heavy test.
20219+ */
20220+ err = -EACCES;
076b876e 20221+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
5527c038 20222+ && au_test_h_perm(d_inode(h_parent),
076b876e 20223+ MAY_EXEC | MAY_WRITE)))
4a4d8108
AM
20224+ goto out;
20225+
076b876e 20226+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
4a4d8108
AM
20227+ err = -EIO;
20228+ if (IS_ERR(h_latest))
20229+ goto out;
20230+ if (h_latest == h_dentry)
20231+ err = 0;
20232+ dput(h_latest);
20233+
4f0767ce 20234+out:
4a4d8108 20235+ return err;
1308ab2a 20236+}
1facf9fc 20237+
4a4d8108
AM
20238+/*
20239+ * decide the branch where we operate for @dentry. the branch index will be set
20240+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
20241+ * dir for reverting.
20242+ * when a new whiteout is necessary, create it.
20243+ */
20244+static struct dentry*
20245+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
20246+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 20247+{
4a4d8108
AM
20248+ struct dentry *wh_dentry;
20249+ struct super_block *sb;
20250+ struct path h_path;
20251+ int err, need_wh;
20252+ unsigned int udba;
20253+ aufs_bindex_t bcpup;
dece6358 20254+
4a4d8108
AM
20255+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
20256+ wh_dentry = ERR_PTR(need_wh);
20257+ if (unlikely(need_wh < 0))
20258+ goto out;
20259+
20260+ sb = dentry->d_sb;
20261+ udba = au_opt_udba(sb);
20262+ bcpup = *rbcpup;
20263+ err = au_pin(pin, dentry, bcpup, udba,
20264+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
20265+ wh_dentry = ERR_PTR(err);
20266+ if (unlikely(err))
20267+ goto out;
20268+
20269+ h_path.dentry = au_pinned_h_parent(pin);
20270+ if (udba != AuOpt_UDBA_NONE
5afbbe0d 20271+ && au_dbtop(dentry) == bcpup) {
4a4d8108
AM
20272+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
20273+ wh_dentry = ERR_PTR(err);
20274+ if (unlikely(err))
20275+ goto out_unpin;
20276+ }
20277+
20278+ h_path.mnt = au_sbr_mnt(sb, bcpup);
20279+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
20280+ wh_dentry = NULL;
20281+ if (!need_wh)
20282+ goto out; /* success, no need to create whiteout */
20283+
20284+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
20285+ if (IS_ERR(wh_dentry))
20286+ goto out_unpin;
20287+
20288+ /* returns with the parent is locked and wh_dentry is dget-ed */
20289+ goto out; /* success */
20290+
4f0767ce 20291+out_unpin:
4a4d8108 20292+ au_unpin(pin);
4f0767ce 20293+out:
4a4d8108 20294+ return wh_dentry;
1facf9fc 20295+}
20296+
4a4d8108
AM
20297+/*
20298+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
20299+ * in order to be revertible and save time for removing many child whiteouts
20300+ * under the dir.
20301+ * returns 1 when there are too many child whiteout and caller should remove
20302+ * them asynchronously. returns 0 when the number of children is enough small to
20303+ * remove now or the branch fs is a remote fs.
20304+ * otherwise return an error.
20305+ */
20306+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
20307+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 20308+{
4a4d8108
AM
20309+ int rmdir_later, err, dirwh;
20310+ struct dentry *h_dentry;
20311+ struct super_block *sb;
5527c038 20312+ struct inode *inode;
4a4d8108
AM
20313+
20314+ sb = dentry->d_sb;
20315+ SiMustAnyLock(sb);
20316+ h_dentry = au_h_dptr(dentry, bindex);
20317+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
20318+ if (unlikely(err))
20319+ goto out;
20320+
20321+ /* stop monitoring */
5527c038
JR
20322+ inode = d_inode(dentry);
20323+ au_hn_free(au_hi(inode, bindex));
4a4d8108
AM
20324+
20325+ if (!au_test_fs_remote(h_dentry->d_sb)) {
20326+ dirwh = au_sbi(sb)->si_dirwh;
20327+ rmdir_later = (dirwh <= 1);
20328+ if (!rmdir_later)
20329+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
20330+ dirwh);
20331+ if (rmdir_later)
20332+ return rmdir_later;
20333+ }
1facf9fc 20334+
4a4d8108
AM
20335+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
20336+ if (unlikely(err)) {
523b37e3
AM
20337+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
20338+ h_dentry, bindex, err);
4a4d8108
AM
20339+ err = 0;
20340+ }
dece6358 20341+
4f0767ce 20342+out:
4a4d8108
AM
20343+ AuTraceErr(err);
20344+ return err;
20345+}
1308ab2a 20346+
4a4d8108
AM
20347+/*
20348+ * final procedure for deleting a entry.
20349+ * maintain dentry and iattr.
20350+ */
20351+static void epilog(struct inode *dir, struct dentry *dentry,
20352+ aufs_bindex_t bindex)
20353+{
20354+ struct inode *inode;
1308ab2a 20355+
5527c038 20356+ inode = d_inode(dentry);
4a4d8108
AM
20357+ d_drop(dentry);
20358+ inode->i_ctime = dir->i_ctime;
1308ab2a 20359+
b912730e 20360+ au_dir_ts(dir, bindex);
4a4d8108 20361+ dir->i_version++;
1facf9fc 20362+}
20363+
4a4d8108
AM
20364+/*
20365+ * when an error happened, remove the created whiteout and revert everything.
20366+ */
7f207e10
AM
20367+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
20368+ aufs_bindex_t bwh, struct dentry *wh_dentry,
20369+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 20370+{
4a4d8108
AM
20371+ int rerr;
20372+ struct path h_path = {
20373+ .dentry = wh_dentry,
7f207e10 20374+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 20375+ };
dece6358 20376+
7f207e10 20377+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
20378+ if (!rerr) {
20379+ au_set_dbwh(dentry, bwh);
20380+ au_dtime_revert(dt);
20381+ return 0;
20382+ }
dece6358 20383+
523b37e3 20384+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 20385+ return -EIO;
1facf9fc 20386+}
20387+
4a4d8108 20388+/* ---------------------------------------------------------------------- */
1facf9fc 20389+
4a4d8108 20390+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 20391+{
4a4d8108 20392+ int err;
5afbbe0d 20393+ aufs_bindex_t bwh, bindex, btop;
523b37e3 20394+ struct inode *inode, *h_dir, *delegated;
4a4d8108 20395+ struct dentry *parent, *wh_dentry;
c2b27bf2
AM
20396+ /* to reuduce stack size */
20397+ struct {
20398+ struct au_dtime dt;
20399+ struct au_pin pin;
20400+ struct path h_path;
20401+ } *a;
1facf9fc 20402+
4a4d8108 20403+ IMustLock(dir);
027c5e7a 20404+
c2b27bf2
AM
20405+ err = -ENOMEM;
20406+ a = kmalloc(sizeof(*a), GFP_NOFS);
20407+ if (unlikely(!a))
20408+ goto out;
20409+
027c5e7a
AM
20410+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
20411+ if (unlikely(err))
c2b27bf2 20412+ goto out_free;
027c5e7a
AM
20413+ err = au_d_hashed_positive(dentry);
20414+ if (unlikely(err))
20415+ goto out_unlock;
5527c038 20416+ inode = d_inode(dentry);
4a4d8108 20417+ IMustLock(inode);
027c5e7a 20418+ err = -EISDIR;
2000de60 20419+ if (unlikely(d_is_dir(dentry)))
027c5e7a 20420+ goto out_unlock; /* possible? */
1facf9fc 20421+
5afbbe0d 20422+ btop = au_dbtop(dentry);
4a4d8108
AM
20423+ bwh = au_dbwh(dentry);
20424+ bindex = -1;
027c5e7a
AM
20425+ parent = dentry->d_parent; /* dir inode is locked */
20426+ di_write_lock_parent(parent);
c2b27bf2
AM
20427+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
20428+ &a->pin);
4a4d8108
AM
20429+ err = PTR_ERR(wh_dentry);
20430+ if (IS_ERR(wh_dentry))
027c5e7a 20431+ goto out_parent;
1facf9fc 20432+
5afbbe0d
AM
20433+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, btop);
20434+ a->h_path.dentry = au_h_dptr(dentry, btop);
c2b27bf2 20435+ dget(a->h_path.dentry);
5afbbe0d 20436+ if (bindex == btop) {
c2b27bf2 20437+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
20438+ delegated = NULL;
20439+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
20440+ if (unlikely(err == -EWOULDBLOCK)) {
20441+ pr_warn("cannot retry for NFSv4 delegation"
20442+ " for an internal unlink\n");
20443+ iput(delegated);
20444+ }
4a4d8108
AM
20445+ } else {
20446+ /* dir inode is locked */
5527c038 20447+ h_dir = d_inode(wh_dentry->d_parent);
4a4d8108
AM
20448+ IMustLock(h_dir);
20449+ err = 0;
20450+ }
dece6358 20451+
4a4d8108 20452+ if (!err) {
7f207e10 20453+ vfsub_drop_nlink(inode);
4a4d8108
AM
20454+ epilog(dir, dentry, bindex);
20455+
20456+ /* update target timestamps */
5afbbe0d 20457+ if (bindex == btop) {
c2b27bf2
AM
20458+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
20459+ /*ignore*/
5527c038 20460+ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
4a4d8108
AM
20461+ } else
20462+ /* todo: this timestamp may be reverted later */
20463+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 20464+ goto out_unpin; /* success */
1facf9fc 20465+ }
20466+
4a4d8108
AM
20467+ /* revert */
20468+ if (wh_dentry) {
20469+ int rerr;
20470+
c2b27bf2
AM
20471+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
20472+ &a->dt);
4a4d8108
AM
20473+ if (rerr)
20474+ err = rerr;
dece6358 20475+ }
1facf9fc 20476+
027c5e7a 20477+out_unpin:
c2b27bf2 20478+ au_unpin(&a->pin);
4a4d8108 20479+ dput(wh_dentry);
c2b27bf2 20480+ dput(a->h_path.dentry);
027c5e7a 20481+out_parent:
4a4d8108 20482+ di_write_unlock(parent);
027c5e7a 20483+out_unlock:
4a4d8108 20484+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 20485+out_free:
1c60b727 20486+ kfree(a);
027c5e7a 20487+out:
4a4d8108 20488+ return err;
dece6358
AM
20489+}
20490+
4a4d8108 20491+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 20492+{
4a4d8108 20493+ int err, rmdir_later;
5afbbe0d 20494+ aufs_bindex_t bwh, bindex, btop;
4a4d8108
AM
20495+ struct inode *inode;
20496+ struct dentry *parent, *wh_dentry, *h_dentry;
20497+ struct au_whtmp_rmdir *args;
c2b27bf2
AM
20498+ /* to reuduce stack size */
20499+ struct {
20500+ struct au_dtime dt;
20501+ struct au_pin pin;
20502+ } *a;
1facf9fc 20503+
4a4d8108 20504+ IMustLock(dir);
027c5e7a 20505+
c2b27bf2
AM
20506+ err = -ENOMEM;
20507+ a = kmalloc(sizeof(*a), GFP_NOFS);
20508+ if (unlikely(!a))
20509+ goto out;
20510+
027c5e7a
AM
20511+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
20512+ if (unlikely(err))
c2b27bf2 20513+ goto out_free;
53392da6
AM
20514+ err = au_alive_dir(dentry);
20515+ if (unlikely(err))
027c5e7a 20516+ goto out_unlock;
5527c038 20517+ inode = d_inode(dentry);
4a4d8108 20518+ IMustLock(inode);
027c5e7a 20519+ err = -ENOTDIR;
2000de60 20520+ if (unlikely(!d_is_dir(dentry)))
027c5e7a 20521+ goto out_unlock; /* possible? */
dece6358 20522+
4a4d8108
AM
20523+ err = -ENOMEM;
20524+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
20525+ if (unlikely(!args))
20526+ goto out_unlock;
dece6358 20527+
4a4d8108
AM
20528+ parent = dentry->d_parent; /* dir inode is locked */
20529+ di_write_lock_parent(parent);
20530+ err = au_test_empty(dentry, &args->whlist);
20531+ if (unlikely(err))
027c5e7a 20532+ goto out_parent;
1facf9fc 20533+
5afbbe0d 20534+ btop = au_dbtop(dentry);
4a4d8108
AM
20535+ bwh = au_dbwh(dentry);
20536+ bindex = -1;
c2b27bf2
AM
20537+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
20538+ &a->pin);
4a4d8108
AM
20539+ err = PTR_ERR(wh_dentry);
20540+ if (IS_ERR(wh_dentry))
027c5e7a 20541+ goto out_parent;
1facf9fc 20542+
5afbbe0d 20543+ h_dentry = au_h_dptr(dentry, btop);
4a4d8108
AM
20544+ dget(h_dentry);
20545+ rmdir_later = 0;
5afbbe0d
AM
20546+ if (bindex == btop) {
20547+ err = renwh_and_rmdir(dentry, btop, &args->whlist, dir);
4a4d8108
AM
20548+ if (err > 0) {
20549+ rmdir_later = err;
20550+ err = 0;
20551+ }
20552+ } else {
20553+ /* stop monitoring */
5afbbe0d 20554+ au_hn_free(au_hi(inode, btop));
4a4d8108
AM
20555+
20556+ /* dir inode is locked */
5527c038 20557+ IMustLock(d_inode(wh_dentry->d_parent));
1facf9fc 20558+ err = 0;
20559+ }
20560+
4a4d8108 20561+ if (!err) {
027c5e7a 20562+ vfsub_dead_dir(inode);
4a4d8108
AM
20563+ au_set_dbdiropq(dentry, -1);
20564+ epilog(dir, dentry, bindex);
1308ab2a 20565+
4a4d8108 20566+ if (rmdir_later) {
5afbbe0d 20567+ au_whtmp_kick_rmdir(dir, btop, h_dentry, args);
4a4d8108
AM
20568+ args = NULL;
20569+ }
1308ab2a 20570+
4a4d8108 20571+ goto out_unpin; /* success */
1facf9fc 20572+ }
20573+
4a4d8108
AM
20574+ /* revert */
20575+ AuLabel(revert);
20576+ if (wh_dentry) {
20577+ int rerr;
1308ab2a 20578+
c2b27bf2
AM
20579+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
20580+ &a->dt);
4a4d8108
AM
20581+ if (rerr)
20582+ err = rerr;
1facf9fc 20583+ }
20584+
4f0767ce 20585+out_unpin:
c2b27bf2 20586+ au_unpin(&a->pin);
4a4d8108
AM
20587+ dput(wh_dentry);
20588+ dput(h_dentry);
027c5e7a 20589+out_parent:
4a4d8108
AM
20590+ di_write_unlock(parent);
20591+ if (args)
20592+ au_whtmp_rmdir_free(args);
4f0767ce 20593+out_unlock:
4a4d8108 20594+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2 20595+out_free:
1c60b727 20596+ kfree(a);
4f0767ce 20597+out:
4a4d8108
AM
20598+ AuTraceErr(err);
20599+ return err;
dece6358 20600+}
7f207e10
AM
20601diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
20602--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 20603+++ linux/fs/aufs/i_op_ren.c 2017-07-29 12:14:25.903042072 +0200
f2c43d5f 20604@@ -0,0 +1,1165 @@
1facf9fc 20605+/*
a2654f78 20606+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 20607+ *
20608+ * This program, aufs is free software; you can redistribute it and/or modify
20609+ * it under the terms of the GNU General Public License as published by
20610+ * the Free Software Foundation; either version 2 of the License, or
20611+ * (at your option) any later version.
dece6358
AM
20612+ *
20613+ * This program is distributed in the hope that it will be useful,
20614+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20615+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20616+ * GNU General Public License for more details.
20617+ *
20618+ * You should have received a copy of the GNU General Public License
523b37e3 20619+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 20620+ */
20621+
20622+/*
4a4d8108
AM
20623+ * inode operation (rename entry)
20624+ * todo: this is crazy monster
1facf9fc 20625+ */
20626+
20627+#include "aufs.h"
20628+
4a4d8108
AM
20629+enum { AuSRC, AuDST, AuSrcDst };
20630+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 20631+
f2c43d5f
AM
20632+#define AuRen_ISDIR_SRC 1
20633+#define AuRen_ISDIR_DST (1 << 1)
20634+#define AuRen_ISSAMEDIR (1 << 2)
20635+#define AuRen_WHSRC (1 << 3)
20636+#define AuRen_WHDST (1 << 4)
20637+#define AuRen_MNT_WRITE (1 << 5)
20638+#define AuRen_DT_DSTDIR (1 << 6)
20639+#define AuRen_DIROPQ_SRC (1 << 7)
20640+#define AuRen_DIROPQ_DST (1 << 8)
4a4d8108 20641+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
20642+#define au_fset_ren(flags, name) \
20643+ do { (flags) |= AuRen_##name; } while (0)
20644+#define au_fclr_ren(flags, name) \
20645+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 20646+
4a4d8108
AM
20647+struct au_ren_args {
20648+ struct {
20649+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
20650+ *wh_dentry;
20651+ struct inode *dir, *inode;
f2c43d5f 20652+ struct au_hinode *hdir, *hinode;
4a4d8108 20653+ struct au_dtime dt[AuParentChild];
f2c43d5f 20654+ aufs_bindex_t btop, bdiropq;
4a4d8108 20655+ } sd[AuSrcDst];
1facf9fc 20656+
4a4d8108
AM
20657+#define src_dentry sd[AuSRC].dentry
20658+#define src_dir sd[AuSRC].dir
20659+#define src_inode sd[AuSRC].inode
20660+#define src_h_dentry sd[AuSRC].h_dentry
20661+#define src_parent sd[AuSRC].parent
20662+#define src_h_parent sd[AuSRC].h_parent
20663+#define src_wh_dentry sd[AuSRC].wh_dentry
20664+#define src_hdir sd[AuSRC].hdir
f2c43d5f 20665+#define src_hinode sd[AuSRC].hinode
4a4d8108
AM
20666+#define src_h_dir sd[AuSRC].hdir->hi_inode
20667+#define src_dt sd[AuSRC].dt
5afbbe0d 20668+#define src_btop sd[AuSRC].btop
f2c43d5f 20669+#define src_bdiropq sd[AuSRC].bdiropq
1facf9fc 20670+
4a4d8108
AM
20671+#define dst_dentry sd[AuDST].dentry
20672+#define dst_dir sd[AuDST].dir
20673+#define dst_inode sd[AuDST].inode
20674+#define dst_h_dentry sd[AuDST].h_dentry
20675+#define dst_parent sd[AuDST].parent
20676+#define dst_h_parent sd[AuDST].h_parent
20677+#define dst_wh_dentry sd[AuDST].wh_dentry
20678+#define dst_hdir sd[AuDST].hdir
f2c43d5f 20679+#define dst_hinode sd[AuDST].hinode
4a4d8108
AM
20680+#define dst_h_dir sd[AuDST].hdir->hi_inode
20681+#define dst_dt sd[AuDST].dt
5afbbe0d 20682+#define dst_btop sd[AuDST].btop
f2c43d5f 20683+#define dst_bdiropq sd[AuDST].bdiropq
4a4d8108
AM
20684+
20685+ struct dentry *h_trap;
20686+ struct au_branch *br;
4a4d8108
AM
20687+ struct path h_path;
20688+ struct au_nhash whlist;
f2c43d5f 20689+ aufs_bindex_t btgt, src_bwh;
1facf9fc 20690+
f2c43d5f
AM
20691+ struct {
20692+ unsigned short auren_flags;
20693+ unsigned char flags; /* syscall parameter */
20694+ unsigned char exchange;
20695+ } __packed;
1facf9fc 20696+
4a4d8108
AM
20697+ struct au_whtmp_rmdir *thargs;
20698+ struct dentry *h_dst;
20699+};
1308ab2a 20700+
4a4d8108 20701+/* ---------------------------------------------------------------------- */
1308ab2a 20702+
4a4d8108
AM
20703+/*
20704+ * functions for reverting.
20705+ * when an error happened in a single rename systemcall, we should revert
79b8bda9 20706+ * everything as if nothing happened.
4a4d8108
AM
20707+ * we don't need to revert the copied-up/down the parent dir since they are
20708+ * harmless.
20709+ */
1facf9fc 20710+
4a4d8108
AM
20711+#define RevertFailure(fmt, ...) do { \
20712+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
20713+ ##__VA_ARGS__, err, rerr); \
20714+ err = -EIO; \
20715+} while (0)
1facf9fc 20716+
f2c43d5f 20717+static void au_ren_do_rev_diropq(int err, struct au_ren_args *a, int idx)
1facf9fc 20718+{
4a4d8108 20719+ int rerr;
f2c43d5f
AM
20720+ struct dentry *d;
20721+#define src_or_dst(member) a->sd[idx].member
1facf9fc 20722+
f2c43d5f
AM
20723+ d = src_or_dst(dentry); /* {src,dst}_dentry */
20724+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD);
20725+ rerr = au_diropq_remove(d, a->btgt);
20726+ au_hn_inode_unlock(src_or_dst(hinode));
20727+ au_set_dbdiropq(d, src_or_dst(bdiropq));
4a4d8108 20728+ if (rerr)
f2c43d5f
AM
20729+ RevertFailure("remove diropq %pd", d);
20730+
20731+#undef src_or_dst_
20732+}
20733+
20734+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
20735+{
20736+ if (au_ftest_ren(a->auren_flags, DIROPQ_SRC))
20737+ au_ren_do_rev_diropq(err, a, AuSRC);
20738+ if (au_ftest_ren(a->auren_flags, DIROPQ_DST))
20739+ au_ren_do_rev_diropq(err, a, AuDST);
4a4d8108 20740+}
1facf9fc 20741+
4a4d8108
AM
20742+static void au_ren_rev_rename(int err, struct au_ren_args *a)
20743+{
20744+ int rerr;
523b37e3 20745+ struct inode *delegated;
1facf9fc 20746+
b4510431
AM
20747+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
20748+ a->src_h_parent);
4a4d8108
AM
20749+ rerr = PTR_ERR(a->h_path.dentry);
20750+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 20751+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 20752+ return;
1facf9fc 20753+ }
20754+
523b37e3 20755+ delegated = NULL;
4a4d8108
AM
20756+ rerr = vfsub_rename(a->dst_h_dir,
20757+ au_h_dptr(a->src_dentry, a->btgt),
f2c43d5f 20758+ a->src_h_dir, &a->h_path, &delegated, a->flags);
523b37e3
AM
20759+ if (unlikely(rerr == -EWOULDBLOCK)) {
20760+ pr_warn("cannot retry for NFSv4 delegation"
20761+ " for an internal rename\n");
20762+ iput(delegated);
20763+ }
4a4d8108
AM
20764+ d_drop(a->h_path.dentry);
20765+ dput(a->h_path.dentry);
20766+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
20767+ if (rerr)
523b37e3 20768+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 20769+}
20770+
4a4d8108 20771+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 20772+{
4a4d8108 20773+ int rerr;
523b37e3 20774+ struct inode *delegated;
dece6358 20775+
b4510431
AM
20776+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
20777+ a->dst_h_parent);
4a4d8108
AM
20778+ rerr = PTR_ERR(a->h_path.dentry);
20779+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 20780+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
20781+ return;
20782+ }
5527c038 20783+ if (d_is_positive(a->h_path.dentry)) {
4a4d8108
AM
20784+ d_drop(a->h_path.dentry);
20785+ dput(a->h_path.dentry);
20786+ return;
dece6358
AM
20787+ }
20788+
523b37e3
AM
20789+ delegated = NULL;
20790+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
f2c43d5f 20791+ &delegated, a->flags);
523b37e3
AM
20792+ if (unlikely(rerr == -EWOULDBLOCK)) {
20793+ pr_warn("cannot retry for NFSv4 delegation"
20794+ " for an internal rename\n");
20795+ iput(delegated);
20796+ }
4a4d8108
AM
20797+ d_drop(a->h_path.dentry);
20798+ dput(a->h_path.dentry);
20799+ if (!rerr)
20800+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
20801+ else
523b37e3 20802+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 20803+}
1308ab2a 20804+
4a4d8108
AM
20805+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
20806+{
20807+ int rerr;
1308ab2a 20808+
4a4d8108
AM
20809+ a->h_path.dentry = a->src_wh_dentry;
20810+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 20811+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 20812+ if (rerr)
523b37e3 20813+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 20814+}
4a4d8108 20815+#undef RevertFailure
1facf9fc 20816+
1308ab2a 20817+/* ---------------------------------------------------------------------- */
20818+
4a4d8108
AM
20819+/*
20820+ * when we have to copyup the renaming entry, do it with the rename-target name
20821+ * in order to minimize the cost (the later actual rename is unnecessary).
20822+ * otherwise rename it on the target branch.
20823+ */
20824+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 20825+{
dece6358 20826+ int err;
4a4d8108 20827+ struct dentry *d;
523b37e3 20828+ struct inode *delegated;
1facf9fc 20829+
4a4d8108 20830+ d = a->src_dentry;
5afbbe0d 20831+ if (au_dbtop(d) == a->btgt) {
4a4d8108 20832+ a->h_path.dentry = a->dst_h_dentry;
5afbbe0d 20833+ AuDebugOn(au_dbtop(d) != a->btgt);
523b37e3 20834+ delegated = NULL;
4a4d8108 20835+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
f2c43d5f
AM
20836+ a->dst_h_dir, &a->h_path, &delegated,
20837+ a->flags);
523b37e3
AM
20838+ if (unlikely(err == -EWOULDBLOCK)) {
20839+ pr_warn("cannot retry for NFSv4 delegation"
20840+ " for an internal rename\n");
20841+ iput(delegated);
20842+ }
c2b27bf2 20843+ } else
86dc4139 20844+ BUG();
1308ab2a 20845+
027c5e7a
AM
20846+ if (!err && a->h_dst)
20847+ /* it will be set to dinfo later */
20848+ dget(a->h_dst);
1facf9fc 20849+
dece6358
AM
20850+ return err;
20851+}
1facf9fc 20852+
4a4d8108
AM
20853+/* cf. aufs_rmdir() */
20854+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 20855+{
4a4d8108
AM
20856+ int err;
20857+ struct inode *dir;
1facf9fc 20858+
4a4d8108
AM
20859+ dir = a->dst_dir;
20860+ SiMustAnyLock(dir->i_sb);
20861+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
20862+ au_sbi(dir->i_sb)->si_dirwh)
20863+ || au_test_fs_remote(a->h_dst->d_sb)) {
20864+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
20865+ if (unlikely(err))
523b37e3
AM
20866+ pr_warn("failed removing whtmp dir %pd (%d), "
20867+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
20868+ } else {
20869+ au_nhash_wh_free(&a->thargs->whlist);
20870+ a->thargs->whlist = a->whlist;
20871+ a->whlist.nh_num = 0;
20872+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
20873+ dput(a->h_dst);
20874+ a->thargs = NULL;
20875+ }
20876+
20877+ return 0;
1308ab2a 20878+}
1facf9fc 20879+
4a4d8108 20880+/* make it 'opaque' dir. */
f2c43d5f 20881+static int au_ren_do_diropq(struct au_ren_args *a, int idx)
4a4d8108
AM
20882+{
20883+ int err;
f2c43d5f
AM
20884+ struct dentry *d, *diropq;
20885+#define src_or_dst(member) a->sd[idx].member
1facf9fc 20886+
4a4d8108 20887+ err = 0;
f2c43d5f
AM
20888+ d = src_or_dst(dentry); /* {src,dst}_dentry */
20889+ src_or_dst(bdiropq) = au_dbdiropq(d);
20890+ src_or_dst(hinode) = au_hi(src_or_dst(inode), a->btgt);
20891+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD);
20892+ diropq = au_diropq_create(d, a->btgt);
20893+ au_hn_inode_unlock(src_or_dst(hinode));
4a4d8108
AM
20894+ if (IS_ERR(diropq))
20895+ err = PTR_ERR(diropq);
076b876e
AM
20896+ else
20897+ dput(diropq);
1facf9fc 20898+
f2c43d5f 20899+#undef src_or_dst_
4a4d8108
AM
20900+ return err;
20901+}
1facf9fc 20902+
f2c43d5f 20903+static int au_ren_diropq(struct au_ren_args *a)
4a4d8108
AM
20904+{
20905+ int err;
f2c43d5f
AM
20906+ unsigned char always;
20907+ struct dentry *d;
1facf9fc 20908+
f2c43d5f
AM
20909+ err = 0;
20910+ d = a->dst_dentry; /* already renamed on the branch */
20911+ always = !!au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ);
20912+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)
20913+ && a->btgt != au_dbdiropq(a->src_dentry)
20914+ && (a->dst_wh_dentry
20915+ || a->btgt <= au_dbdiropq(d)
20916+ /* hide the lower to keep xino */
20917+ /* the lowers may not be a dir, but we hide them anyway */
20918+ || a->btgt < au_dbbot(d)
20919+ || always)) {
20920+ AuDbg("here\n");
20921+ err = au_ren_do_diropq(a, AuSRC);
20922+ if (unlikely(err))
4a4d8108 20923+ goto out;
f2c43d5f 20924+ au_fset_ren(a->auren_flags, DIROPQ_SRC);
4a4d8108 20925+ }
f2c43d5f
AM
20926+ if (!a->exchange)
20927+ goto out; /* success */
1facf9fc 20928+
f2c43d5f
AM
20929+ d = a->src_dentry; /* already renamed on the branch */
20930+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)
20931+ && a->btgt != au_dbdiropq(a->dst_dentry)
20932+ && (a->btgt < au_dbdiropq(d)
20933+ || a->btgt < au_dbbot(d)
20934+ || always)) {
20935+ AuDbgDentry(a->src_dentry);
20936+ AuDbgDentry(a->dst_dentry);
20937+ err = au_ren_do_diropq(a, AuDST);
4a4d8108 20938+ if (unlikely(err))
f2c43d5f
AM
20939+ goto out_rev_src;
20940+ au_fset_ren(a->auren_flags, DIROPQ_DST);
20941+ }
20942+ goto out; /* success */
dece6358 20943+
f2c43d5f
AM
20944+out_rev_src:
20945+ AuDbg("err %d, reverting src\n", err);
20946+ au_ren_rev_diropq(err, a);
20947+out:
20948+ return err;
20949+}
20950+
20951+static int do_rename(struct au_ren_args *a)
20952+{
20953+ int err;
20954+ struct dentry *d, *h_d;
20955+
20956+ if (!a->exchange) {
20957+ /* prepare workqueue args for asynchronous rmdir */
20958+ h_d = a->dst_h_dentry;
20959+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)
20960+ && d_is_positive(h_d)) {
20961+ err = -ENOMEM;
20962+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb,
20963+ GFP_NOFS);
20964+ if (unlikely(!a->thargs))
20965+ goto out;
20966+ a->h_dst = dget(h_d);
20967+ }
20968+
20969+ /* create whiteout for src_dentry */
20970+ if (au_ftest_ren(a->auren_flags, WHSRC)) {
20971+ a->src_bwh = au_dbwh(a->src_dentry);
20972+ AuDebugOn(a->src_bwh >= 0);
20973+ a->src_wh_dentry = au_wh_create(a->src_dentry, a->btgt,
20974+ a->src_h_parent);
20975+ err = PTR_ERR(a->src_wh_dentry);
20976+ if (IS_ERR(a->src_wh_dentry))
20977+ goto out_thargs;
20978+ }
20979+
20980+ /* lookup whiteout for dentry */
20981+ if (au_ftest_ren(a->auren_flags, WHDST)) {
20982+ h_d = au_wh_lkup(a->dst_h_parent,
20983+ &a->dst_dentry->d_name, a->br);
20984+ err = PTR_ERR(h_d);
20985+ if (IS_ERR(h_d))
20986+ goto out_whsrc;
20987+ if (d_is_negative(h_d))
20988+ dput(h_d);
20989+ else
20990+ a->dst_wh_dentry = h_d;
20991+ }
20992+
20993+ /* rename dentry to tmpwh */
20994+ if (a->thargs) {
20995+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
20996+ if (unlikely(err))
20997+ goto out_whdst;
20998+
20999+ d = a->dst_dentry;
21000+ au_set_h_dptr(d, a->btgt, NULL);
21001+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
21002+ if (unlikely(err))
21003+ goto out_whtmp;
21004+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
21005+ }
4a4d8108 21006+ }
1facf9fc 21007+
5afbbe0d 21008+ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_btop != a->btgt);
1facf9fc 21009+
4a4d8108 21010+ /* rename by vfs_rename or cpup */
4a4d8108
AM
21011+ err = au_ren_or_cpup(a);
21012+ if (unlikely(err))
21013+ /* leave the copied-up one */
21014+ goto out_whtmp;
1308ab2a 21015+
4a4d8108 21016+ /* make dir opaque */
f2c43d5f
AM
21017+ err = au_ren_diropq(a);
21018+ if (unlikely(err))
21019+ goto out_rename;
1308ab2a 21020+
4a4d8108 21021+ /* update target timestamps */
f2c43d5f
AM
21022+ if (a->exchange) {
21023+ AuDebugOn(au_dbtop(a->dst_dentry) != a->btgt);
21024+ a->h_path.dentry = au_h_dptr(a->dst_dentry, a->btgt);
21025+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
21026+ a->dst_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
21027+ }
5afbbe0d 21028+ AuDebugOn(au_dbtop(a->src_dentry) != a->btgt);
4a4d8108
AM
21029+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
21030+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
5527c038 21031+ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
1facf9fc 21032+
f2c43d5f
AM
21033+ if (!a->exchange) {
21034+ /* remove whiteout for dentry */
21035+ if (a->dst_wh_dentry) {
21036+ a->h_path.dentry = a->dst_wh_dentry;
21037+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
21038+ a->dst_dentry);
21039+ if (unlikely(err))
21040+ goto out_diropq;
21041+ }
1facf9fc 21042+
f2c43d5f
AM
21043+ /* remove whtmp */
21044+ if (a->thargs)
21045+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 21046+
f2c43d5f
AM
21047+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
21048+ }
4a4d8108
AM
21049+ err = 0;
21050+ goto out_success;
21051+
4f0767ce 21052+out_diropq:
f2c43d5f 21053+ au_ren_rev_diropq(err, a);
4f0767ce 21054+out_rename:
7e9cd9fe 21055+ au_ren_rev_rename(err, a);
027c5e7a 21056+ dput(a->h_dst);
4f0767ce 21057+out_whtmp:
4a4d8108
AM
21058+ if (a->thargs)
21059+ au_ren_rev_whtmp(err, a);
4f0767ce 21060+out_whdst:
4a4d8108
AM
21061+ dput(a->dst_wh_dentry);
21062+ a->dst_wh_dentry = NULL;
4f0767ce 21063+out_whsrc:
4a4d8108
AM
21064+ if (a->src_wh_dentry)
21065+ au_ren_rev_whsrc(err, a);
4f0767ce 21066+out_success:
4a4d8108
AM
21067+ dput(a->src_wh_dentry);
21068+ dput(a->dst_wh_dentry);
4f0767ce 21069+out_thargs:
4a4d8108
AM
21070+ if (a->thargs) {
21071+ dput(a->h_dst);
21072+ au_whtmp_rmdir_free(a->thargs);
21073+ a->thargs = NULL;
21074+ }
4f0767ce 21075+out:
4a4d8108 21076+ return err;
dece6358 21077+}
1facf9fc 21078+
1308ab2a 21079+/* ---------------------------------------------------------------------- */
1facf9fc 21080+
4a4d8108
AM
21081+/*
21082+ * test if @dentry dir can be rename destination or not.
21083+ * success means, it is a logically empty dir.
21084+ */
21085+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 21086+{
4a4d8108 21087+ return au_test_empty(dentry, whlist);
1308ab2a 21088+}
1facf9fc 21089+
4a4d8108
AM
21090+/*
21091+ * test if @dentry dir can be rename source or not.
21092+ * if it can, return 0 and @children is filled.
21093+ * success means,
21094+ * - it is a logically empty dir.
21095+ * - or, it exists on writable branch and has no children including whiteouts
21096+ * on the lower branch.
21097+ */
21098+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
21099+{
21100+ int err;
21101+ unsigned int rdhash;
5afbbe0d 21102+ aufs_bindex_t btop;
1facf9fc 21103+
5afbbe0d
AM
21104+ btop = au_dbtop(dentry);
21105+ if (btop != btgt) {
4a4d8108 21106+ struct au_nhash whlist;
dece6358 21107+
4a4d8108
AM
21108+ SiMustAnyLock(dentry->d_sb);
21109+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
21110+ if (!rdhash)
21111+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
21112+ dentry));
21113+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
21114+ if (unlikely(err))
21115+ goto out;
21116+ err = au_test_empty(dentry, &whlist);
21117+ au_nhash_wh_free(&whlist);
21118+ goto out;
21119+ }
dece6358 21120+
5afbbe0d 21121+ if (btop == au_dbtaildir(dentry))
4a4d8108 21122+ return 0; /* success */
dece6358 21123+
4a4d8108 21124+ err = au_test_empty_lower(dentry);
1facf9fc 21125+
4f0767ce 21126+out:
4a4d8108
AM
21127+ if (err == -ENOTEMPTY) {
21128+ AuWarn1("renaming dir who has child(ren) on multiple branches,"
21129+ " is not supported\n");
21130+ err = -EXDEV;
21131+ }
21132+ return err;
21133+}
1308ab2a 21134+
4a4d8108
AM
21135+/* side effect: sets whlist and h_dentry */
21136+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 21137+{
4a4d8108
AM
21138+ int err;
21139+ unsigned int rdhash;
21140+ struct dentry *d;
1facf9fc 21141+
4a4d8108
AM
21142+ d = a->dst_dentry;
21143+ SiMustAnyLock(d->d_sb);
1facf9fc 21144+
4a4d8108 21145+ err = 0;
f2c43d5f 21146+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) && a->dst_inode) {
4a4d8108
AM
21147+ rdhash = au_sbi(d->d_sb)->si_rdhash;
21148+ if (!rdhash)
21149+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
21150+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
21151+ if (unlikely(err))
21152+ goto out;
1308ab2a 21153+
f2c43d5f
AM
21154+ if (!a->exchange) {
21155+ au_set_dbtop(d, a->dst_btop);
21156+ err = may_rename_dstdir(d, &a->whlist);
21157+ au_set_dbtop(d, a->btgt);
21158+ } else
21159+ err = may_rename_srcdir(d, a->btgt);
4a4d8108 21160+ }
5afbbe0d 21161+ a->dst_h_dentry = au_h_dptr(d, au_dbtop(d));
4a4d8108
AM
21162+ if (unlikely(err))
21163+ goto out;
21164+
21165+ d = a->src_dentry;
5afbbe0d 21166+ a->src_h_dentry = au_h_dptr(d, au_dbtop(d));
f2c43d5f 21167+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) {
4a4d8108
AM
21168+ err = may_rename_srcdir(d, a->btgt);
21169+ if (unlikely(err)) {
21170+ au_nhash_wh_free(&a->whlist);
21171+ a->whlist.nh_num = 0;
21172+ }
21173+ }
4f0767ce 21174+out:
4a4d8108 21175+ return err;
1facf9fc 21176+}
21177+
4a4d8108 21178+/* ---------------------------------------------------------------------- */
1facf9fc 21179+
4a4d8108
AM
21180+/*
21181+ * simple tests for rename.
21182+ * following the checks in vfs, plus the parent-child relationship.
21183+ */
21184+static int au_may_ren(struct au_ren_args *a)
21185+{
21186+ int err, isdir;
21187+ struct inode *h_inode;
1facf9fc 21188+
5afbbe0d 21189+ if (a->src_btop == a->btgt) {
4a4d8108 21190+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
f2c43d5f 21191+ au_ftest_ren(a->auren_flags, ISDIR_SRC));
4a4d8108
AM
21192+ if (unlikely(err))
21193+ goto out;
21194+ err = -EINVAL;
21195+ if (unlikely(a->src_h_dentry == a->h_trap))
21196+ goto out;
21197+ }
1facf9fc 21198+
4a4d8108 21199+ err = 0;
5afbbe0d 21200+ if (a->dst_btop != a->btgt)
4a4d8108 21201+ goto out;
1facf9fc 21202+
027c5e7a
AM
21203+ err = -ENOTEMPTY;
21204+ if (unlikely(a->dst_h_dentry == a->h_trap))
21205+ goto out;
21206+
4a4d8108 21207+ err = -EIO;
f2c43d5f 21208+ isdir = !!au_ftest_ren(a->auren_flags, ISDIR_DST);
5527c038
JR
21209+ if (d_really_is_negative(a->dst_dentry)) {
21210+ if (d_is_negative(a->dst_h_dentry))
21211+ err = au_may_add(a->dst_dentry, a->btgt,
21212+ a->dst_h_parent, isdir);
4a4d8108 21213+ } else {
5527c038 21214+ if (unlikely(d_is_negative(a->dst_h_dentry)))
4a4d8108 21215+ goto out;
5527c038
JR
21216+ h_inode = d_inode(a->dst_h_dentry);
21217+ if (h_inode->i_nlink)
21218+ err = au_may_del(a->dst_dentry, a->btgt,
21219+ a->dst_h_parent, isdir);
4a4d8108 21220+ }
1facf9fc 21221+
4f0767ce 21222+out:
4a4d8108
AM
21223+ if (unlikely(err == -ENOENT || err == -EEXIST))
21224+ err = -EIO;
21225+ AuTraceErr(err);
21226+ return err;
21227+}
1facf9fc 21228+
1308ab2a 21229+/* ---------------------------------------------------------------------- */
1facf9fc 21230+
4a4d8108
AM
21231+/*
21232+ * locking order
21233+ * (VFS)
21234+ * - src_dir and dir by lock_rename()
21235+ * - inode if exitsts
21236+ * (aufs)
21237+ * - lock all
21238+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
21239+ * + si_read_lock
21240+ * + di_write_lock2_child()
21241+ * + di_write_lock_child()
21242+ * + ii_write_lock_child()
21243+ * + di_write_lock_child2()
21244+ * + ii_write_lock_child2()
21245+ * + src_parent and parent
21246+ * + di_write_lock_parent()
21247+ * + ii_write_lock_parent()
21248+ * + di_write_lock_parent2()
21249+ * + ii_write_lock_parent2()
21250+ * + lower src_dir and dir by vfsub_lock_rename()
21251+ * + verify the every relationships between child and parent. if any
21252+ * of them failed, unlock all and return -EBUSY.
21253+ */
21254+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 21255+{
4a4d8108
AM
21256+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
21257+ a->dst_h_parent, a->dst_hdir);
f2c43d5f 21258+ if (au_ftest_ren(a->auren_flags, MNT_WRITE))
86dc4139 21259+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 21260+}
21261+
4a4d8108 21262+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 21263+{
4a4d8108
AM
21264+ int err;
21265+ unsigned int udba;
1308ab2a 21266+
4a4d8108
AM
21267+ err = 0;
21268+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
21269+ a->src_hdir = au_hi(a->src_dir, a->btgt);
21270+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
21271+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
21272+
21273+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
21274+ if (unlikely(err))
21275+ goto out;
f2c43d5f 21276+ au_fset_ren(a->auren_flags, MNT_WRITE);
4a4d8108
AM
21277+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
21278+ a->dst_h_parent, a->dst_hdir);
21279+ udba = au_opt_udba(a->src_dentry->d_sb);
5527c038
JR
21280+ if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent)
21281+ || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent)))
4a4d8108 21282+ err = au_busy_or_stale();
5afbbe0d 21283+ if (!err && au_dbtop(a->src_dentry) == a->btgt)
4a4d8108 21284+ err = au_h_verify(a->src_h_dentry, udba,
5527c038 21285+ d_inode(a->src_h_parent), a->src_h_parent,
4a4d8108 21286+ a->br);
5afbbe0d 21287+ if (!err && au_dbtop(a->dst_dentry) == a->btgt)
4a4d8108 21288+ err = au_h_verify(a->dst_h_dentry, udba,
5527c038 21289+ d_inode(a->dst_h_parent), a->dst_h_parent,
4a4d8108 21290+ a->br);
86dc4139 21291+ if (!err)
4a4d8108 21292+ goto out; /* success */
4a4d8108
AM
21293+
21294+ err = au_busy_or_stale();
4a4d8108 21295+ au_ren_unlock(a);
86dc4139 21296+
4f0767ce 21297+out:
4a4d8108 21298+ return err;
1facf9fc 21299+}
21300+
21301+/* ---------------------------------------------------------------------- */
21302+
4a4d8108 21303+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 21304+{
4a4d8108 21305+ struct inode *dir;
dece6358 21306+
4a4d8108
AM
21307+ dir = a->dst_dir;
21308+ dir->i_version++;
f2c43d5f 21309+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) {
4a4d8108
AM
21310+ /* is this updating defined in POSIX? */
21311+ au_cpup_attr_timesizes(a->src_inode);
21312+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 21313+ }
b912730e 21314+ au_dir_ts(dir, a->btgt);
dece6358 21315+
f2c43d5f
AM
21316+ if (a->exchange) {
21317+ dir = a->src_dir;
21318+ dir->i_version++;
21319+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)) {
21320+ /* is this updating defined in POSIX? */
21321+ au_cpup_attr_timesizes(a->dst_inode);
21322+ au_cpup_attr_nlink(dir, /*force*/1);
21323+ }
21324+ au_dir_ts(dir, a->btgt);
21325+ }
21326+
21327+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108 21328+ return;
dece6358 21329+
4a4d8108
AM
21330+ dir = a->src_dir;
21331+ dir->i_version++;
f2c43d5f 21332+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC))
4a4d8108 21333+ au_cpup_attr_nlink(dir, /*force*/1);
b912730e 21334+ au_dir_ts(dir, a->btgt);
1facf9fc 21335+}
21336+
4a4d8108 21337+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 21338+{
5afbbe0d 21339+ aufs_bindex_t bbot, bindex;
4a4d8108
AM
21340+ struct dentry *d, *h_d;
21341+ struct inode *i, *h_i;
21342+ struct super_block *sb;
dece6358 21343+
027c5e7a
AM
21344+ d = a->dst_dentry;
21345+ d_drop(d);
21346+ if (a->h_dst)
21347+ /* already dget-ed by au_ren_or_cpup() */
21348+ au_set_h_dptr(d, a->btgt, a->h_dst);
21349+
21350+ i = a->dst_inode;
21351+ if (i) {
f2c43d5f
AM
21352+ if (!a->exchange) {
21353+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST))
21354+ vfsub_drop_nlink(i);
21355+ else {
21356+ vfsub_dead_dir(i);
21357+ au_cpup_attr_timesizes(i);
21358+ }
21359+ au_update_dbrange(d, /*do_put_zero*/1);
21360+ } else
21361+ au_cpup_attr_nlink(i, /*force*/1);
027c5e7a 21362+ } else {
5afbbe0d
AM
21363+ bbot = a->btgt;
21364+ for (bindex = au_dbtop(d); bindex < bbot; bindex++)
027c5e7a 21365+ au_set_h_dptr(d, bindex, NULL);
5afbbe0d
AM
21366+ bbot = au_dbbot(d);
21367+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++)
027c5e7a
AM
21368+ au_set_h_dptr(d, bindex, NULL);
21369+ au_update_dbrange(d, /*do_put_zero*/0);
21370+ }
21371+
4a4d8108 21372+ d = a->src_dentry;
f2c43d5f
AM
21373+ if (!a->exchange) {
21374+ au_set_dbwh(d, -1);
21375+ bbot = au_dbbot(d);
21376+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) {
21377+ h_d = au_h_dptr(d, bindex);
21378+ if (h_d)
21379+ au_set_h_dptr(d, bindex, NULL);
21380+ }
21381+ au_set_dbbot(d, a->btgt);
4a4d8108 21382+
f2c43d5f
AM
21383+ sb = d->d_sb;
21384+ i = a->src_inode;
21385+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
21386+ return; /* success */
4a4d8108 21387+
f2c43d5f
AM
21388+ bbot = au_ibbot(i);
21389+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) {
21390+ h_i = au_h_iptr(i, bindex);
21391+ if (h_i) {
21392+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
21393+ /* ignore this error */
21394+ au_set_h_iptr(i, bindex, NULL, 0);
21395+ }
4a4d8108 21396+ }
f2c43d5f 21397+ au_set_ibbot(i, a->btgt);
4a4d8108 21398+ }
f2c43d5f 21399+ d_drop(a->src_dentry);
1308ab2a 21400+}
dece6358 21401+
4a4d8108
AM
21402+/* ---------------------------------------------------------------------- */
21403+
21404+/* mainly for link(2) and rename(2) */
21405+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 21406+{
4a4d8108
AM
21407+ aufs_bindex_t bdiropq, bwh;
21408+ struct dentry *parent;
21409+ struct au_branch *br;
21410+
21411+ parent = dentry->d_parent;
5527c038 21412+ IMustLock(d_inode(parent)); /* dir is locked */
4a4d8108
AM
21413+
21414+ bdiropq = au_dbdiropq(parent);
21415+ bwh = au_dbwh(dentry);
21416+ br = au_sbr(dentry->d_sb, btgt);
21417+ if (au_br_rdonly(br)
21418+ || (0 <= bdiropq && bdiropq < btgt)
21419+ || (0 <= bwh && bwh < btgt))
21420+ btgt = -1;
21421+
21422+ AuDbg("btgt %d\n", btgt);
21423+ return btgt;
1facf9fc 21424+}
21425+
5afbbe0d 21426+/* sets src_btop, dst_btop and btgt */
4a4d8108 21427+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 21428+{
4a4d8108
AM
21429+ int err;
21430+ struct au_wr_dir_args wr_dir_args = {
21431+ /* .force_btgt = -1, */
21432+ .flags = AuWrDir_ADD_ENTRY
21433+ };
dece6358 21434+
5afbbe0d
AM
21435+ a->src_btop = au_dbtop(a->src_dentry);
21436+ a->dst_btop = au_dbtop(a->dst_dentry);
f2c43d5f
AM
21437+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)
21438+ || au_ftest_ren(a->auren_flags, ISDIR_DST))
4a4d8108 21439+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
5afbbe0d
AM
21440+ wr_dir_args.force_btgt = a->src_btop;
21441+ if (a->dst_inode && a->dst_btop < a->src_btop)
21442+ wr_dir_args.force_btgt = a->dst_btop;
4a4d8108
AM
21443+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
21444+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
21445+ a->btgt = err;
f2c43d5f
AM
21446+ if (a->exchange)
21447+ au_update_dbtop(a->dst_dentry);
dece6358 21448+
4a4d8108 21449+ return err;
1facf9fc 21450+}
21451+
4a4d8108 21452+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 21453+{
4a4d8108
AM
21454+ a->h_path.dentry = a->src_h_parent;
21455+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
f2c43d5f 21456+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) {
4a4d8108
AM
21457+ a->h_path.dentry = a->dst_h_parent;
21458+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
21459+ }
1facf9fc 21460+
f2c43d5f
AM
21461+ au_fclr_ren(a->auren_flags, DT_DSTDIR);
21462+ if (!au_ftest_ren(a->auren_flags, ISDIR_SRC)
21463+ && !a->exchange)
4a4d8108 21464+ return;
dece6358 21465+
4a4d8108
AM
21466+ a->h_path.dentry = a->src_h_dentry;
21467+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
5527c038 21468+ if (d_is_positive(a->dst_h_dentry)) {
f2c43d5f 21469+ au_fset_ren(a->auren_flags, DT_DSTDIR);
4a4d8108
AM
21470+ a->h_path.dentry = a->dst_h_dentry;
21471+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
21472+ }
1308ab2a 21473+}
dece6358 21474+
4a4d8108 21475+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 21476+{
4a4d8108 21477+ struct dentry *h_d;
febd17d6 21478+ struct inode *h_inode;
4a4d8108
AM
21479+
21480+ au_dtime_revert(a->src_dt + AuPARENT);
f2c43d5f 21481+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108
AM
21482+ au_dtime_revert(a->dst_dt + AuPARENT);
21483+
f2c43d5f 21484+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) && err != -EIO) {
4a4d8108 21485+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
febd17d6
JR
21486+ h_inode = d_inode(h_d);
21487+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 21488+ au_dtime_revert(a->src_dt + AuCHILD);
febd17d6 21489+ inode_unlock(h_inode);
4a4d8108 21490+
f2c43d5f 21491+ if (au_ftest_ren(a->auren_flags, DT_DSTDIR)) {
4a4d8108 21492+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
febd17d6
JR
21493+ h_inode = d_inode(h_d);
21494+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
4a4d8108 21495+ au_dtime_revert(a->dst_dt + AuCHILD);
febd17d6 21496+ inode_unlock(h_inode);
1facf9fc 21497+ }
21498+ }
21499+}
21500+
4a4d8108
AM
21501+/* ---------------------------------------------------------------------- */
21502+
21503+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
f2c43d5f
AM
21504+ struct inode *_dst_dir, struct dentry *_dst_dentry,
21505+ unsigned int _flags)
1facf9fc 21506+{
f2c43d5f 21507+ int err, lock_flags;
4a4d8108
AM
21508+ /* reduce stack space */
21509+ struct au_ren_args *a;
f2c43d5f 21510+ struct au_pin pin;
4a4d8108 21511+
f2c43d5f 21512+ AuDbg("%pd, %pd, 0x%x\n", _src_dentry, _dst_dentry, _flags);
4a4d8108
AM
21513+ IMustLock(_src_dir);
21514+ IMustLock(_dst_dir);
21515+
f2c43d5f
AM
21516+ err = -EINVAL;
21517+ if (unlikely(_flags & RENAME_WHITEOUT))
21518+ goto out;
21519+
4a4d8108
AM
21520+ err = -ENOMEM;
21521+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
21522+ a = kzalloc(sizeof(*a), GFP_NOFS);
21523+ if (unlikely(!a))
21524+ goto out;
21525+
f2c43d5f
AM
21526+ a->flags = _flags;
21527+ a->exchange = _flags & RENAME_EXCHANGE;
4a4d8108
AM
21528+ a->src_dir = _src_dir;
21529+ a->src_dentry = _src_dentry;
5527c038
JR
21530+ a->src_inode = NULL;
21531+ if (d_really_is_positive(a->src_dentry))
21532+ a->src_inode = d_inode(a->src_dentry);
4a4d8108
AM
21533+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
21534+ a->dst_dir = _dst_dir;
21535+ a->dst_dentry = _dst_dentry;
5527c038
JR
21536+ a->dst_inode = NULL;
21537+ if (d_really_is_positive(a->dst_dentry))
21538+ a->dst_inode = d_inode(a->dst_dentry);
4a4d8108
AM
21539+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
21540+ if (a->dst_inode) {
f2c43d5f
AM
21541+ /*
21542+ * if EXCHANGE && src is non-dir && dst is dir,
21543+ * dst is not locked.
21544+ */
21545+ /* IMustLock(a->dst_inode); */
4a4d8108 21546+ au_igrab(a->dst_inode);
1facf9fc 21547+ }
1facf9fc 21548+
4a4d8108 21549+ err = -ENOTDIR;
f2c43d5f 21550+ lock_flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
2000de60 21551+ if (d_is_dir(a->src_dentry)) {
f2c43d5f
AM
21552+ au_fset_ren(a->auren_flags, ISDIR_SRC);
21553+ if (unlikely(!a->exchange
21554+ && d_really_is_positive(a->dst_dentry)
2000de60 21555+ && !d_is_dir(a->dst_dentry)))
4a4d8108 21556+ goto out_free;
f2c43d5f
AM
21557+ lock_flags |= AuLock_DIRS;
21558+ }
21559+ if (a->dst_inode && d_is_dir(a->dst_dentry)) {
21560+ au_fset_ren(a->auren_flags, ISDIR_DST);
21561+ if (unlikely(!a->exchange
21562+ && d_really_is_positive(a->src_dentry)
21563+ && !d_is_dir(a->src_dentry)))
21564+ goto out_free;
21565+ lock_flags |= AuLock_DIRS;
b95c5147 21566+ }
f2c43d5f 21567+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, lock_flags);
e49829fe
JR
21568+ if (unlikely(err))
21569+ goto out_free;
1facf9fc 21570+
027c5e7a
AM
21571+ err = au_d_hashed_positive(a->src_dentry);
21572+ if (unlikely(err))
21573+ goto out_unlock;
21574+ err = -ENOENT;
21575+ if (a->dst_inode) {
21576+ /*
f2c43d5f 21577+ * If it is a dir, VFS unhash it before this
027c5e7a
AM
21578+ * function. It means we cannot rely upon d_unhashed().
21579+ */
21580+ if (unlikely(!a->dst_inode->i_nlink))
21581+ goto out_unlock;
f2c43d5f 21582+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) {
027c5e7a 21583+ err = au_d_hashed_positive(a->dst_dentry);
f2c43d5f 21584+ if (unlikely(err && !a->exchange))
027c5e7a
AM
21585+ goto out_unlock;
21586+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
21587+ goto out_unlock;
21588+ } else if (unlikely(d_unhashed(a->dst_dentry)))
21589+ goto out_unlock;
21590+
7eafdf33
AM
21591+ /*
21592+ * is it possible?
79b8bda9 21593+ * yes, it happened (in linux-3.3-rcN) but I don't know why.
7eafdf33
AM
21594+ * there may exist a problem somewhere else.
21595+ */
21596+ err = -EINVAL;
5527c038 21597+ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry)))
7eafdf33
AM
21598+ goto out_unlock;
21599+
f2c43d5f 21600+ au_fset_ren(a->auren_flags, ISSAMEDIR); /* temporary */
4a4d8108 21601+ di_write_lock_parent(a->dst_parent);
1facf9fc 21602+
4a4d8108
AM
21603+ /* which branch we process */
21604+ err = au_ren_wbr(a);
21605+ if (unlikely(err < 0))
027c5e7a 21606+ goto out_parent;
4a4d8108 21607+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 21608+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 21609+
4a4d8108
AM
21610+ /* are they available to be renamed */
21611+ err = au_ren_may_dir(a);
21612+ if (unlikely(err))
21613+ goto out_children;
1facf9fc 21614+
4a4d8108 21615+ /* prepare the writable parent dir on the same branch */
5afbbe0d 21616+ if (a->dst_btop == a->btgt) {
f2c43d5f 21617+ au_fset_ren(a->auren_flags, WHDST);
4a4d8108
AM
21618+ } else {
21619+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
21620+ if (unlikely(err))
21621+ goto out_children;
21622+ }
1facf9fc 21623+
f2c43d5f
AM
21624+ err = 0;
21625+ if (!a->exchange) {
21626+ if (a->src_dir != a->dst_dir) {
21627+ /*
21628+ * this temporary unlock is safe,
21629+ * because both dir->i_mutex are locked.
21630+ */
21631+ di_write_unlock(a->dst_parent);
21632+ di_write_lock_parent(a->src_parent);
21633+ err = au_wr_dir_need_wh(a->src_dentry,
21634+ au_ftest_ren(a->auren_flags,
21635+ ISDIR_SRC),
21636+ &a->btgt);
21637+ di_write_unlock(a->src_parent);
21638+ di_write_lock2_parent(a->src_parent, a->dst_parent,
21639+ /*isdir*/1);
21640+ au_fclr_ren(a->auren_flags, ISSAMEDIR);
21641+ } else
21642+ err = au_wr_dir_need_wh(a->src_dentry,
21643+ au_ftest_ren(a->auren_flags,
21644+ ISDIR_SRC),
21645+ &a->btgt);
21646+ }
4a4d8108
AM
21647+ if (unlikely(err < 0))
21648+ goto out_children;
21649+ if (err)
f2c43d5f 21650+ au_fset_ren(a->auren_flags, WHSRC);
1facf9fc 21651+
86dc4139 21652+ /* cpup src */
5afbbe0d 21653+ if (a->src_btop != a->btgt) {
86dc4139
AM
21654+ err = au_pin(&pin, a->src_dentry, a->btgt,
21655+ au_opt_udba(a->src_dentry->d_sb),
21656+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 21657+ if (!err) {
c2b27bf2
AM
21658+ struct au_cp_generic cpg = {
21659+ .dentry = a->src_dentry,
21660+ .bdst = a->btgt,
5afbbe0d 21661+ .bsrc = a->src_btop,
c2b27bf2
AM
21662+ .len = -1,
21663+ .pin = &pin,
21664+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21665+ };
5afbbe0d 21666+ AuDebugOn(au_dbtop(a->src_dentry) != a->src_btop);
c2b27bf2 21667+ err = au_sio_cpup_simple(&cpg);
367653fa 21668+ au_unpin(&pin);
86dc4139 21669+ }
86dc4139
AM
21670+ if (unlikely(err))
21671+ goto out_children;
5afbbe0d 21672+ a->src_btop = a->btgt;
86dc4139 21673+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
f2c43d5f
AM
21674+ if (!a->exchange)
21675+ au_fset_ren(a->auren_flags, WHSRC);
21676+ }
21677+
21678+ /* cpup dst */
21679+ if (a->exchange && a->dst_inode
21680+ && a->dst_btop != a->btgt) {
21681+ err = au_pin(&pin, a->dst_dentry, a->btgt,
21682+ au_opt_udba(a->dst_dentry->d_sb),
21683+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
21684+ if (!err) {
21685+ struct au_cp_generic cpg = {
21686+ .dentry = a->dst_dentry,
21687+ .bdst = a->btgt,
21688+ .bsrc = a->dst_btop,
21689+ .len = -1,
21690+ .pin = &pin,
21691+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21692+ };
21693+ err = au_sio_cpup_simple(&cpg);
21694+ au_unpin(&pin);
21695+ }
21696+ if (unlikely(err))
21697+ goto out_children;
21698+ a->dst_btop = a->btgt;
21699+ a->dst_h_dentry = au_h_dptr(a->dst_dentry, a->btgt);
86dc4139
AM
21700+ }
21701+
4a4d8108
AM
21702+ /* lock them all */
21703+ err = au_ren_lock(a);
21704+ if (unlikely(err))
86dc4139 21705+ /* leave the copied-up one */
4a4d8108 21706+ goto out_children;
1facf9fc 21707+
f2c43d5f
AM
21708+ if (!a->exchange) {
21709+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
21710+ err = au_may_ren(a);
21711+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
21712+ err = -ENAMETOOLONG;
21713+ if (unlikely(err))
21714+ goto out_hdir;
21715+ }
1facf9fc 21716+
4a4d8108
AM
21717+ /* store timestamps to be revertible */
21718+ au_ren_dt(a);
1facf9fc 21719+
4a4d8108
AM
21720+ /* here we go */
21721+ err = do_rename(a);
21722+ if (unlikely(err))
21723+ goto out_dt;
21724+
21725+ /* update dir attributes */
21726+ au_ren_refresh_dir(a);
21727+
21728+ /* dput/iput all lower dentries */
21729+ au_ren_refresh(a);
21730+
21731+ goto out_hdir; /* success */
21732+
4f0767ce 21733+out_dt:
4a4d8108 21734+ au_ren_rev_dt(err, a);
4f0767ce 21735+out_hdir:
4a4d8108 21736+ au_ren_unlock(a);
4f0767ce 21737+out_children:
4a4d8108 21738+ au_nhash_wh_free(&a->whlist);
5afbbe0d
AM
21739+ if (err && a->dst_inode && a->dst_btop != a->btgt) {
21740+ AuDbg("btop %d, btgt %d\n", a->dst_btop, a->btgt);
027c5e7a 21741+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
5afbbe0d 21742+ au_set_dbtop(a->dst_dentry, a->dst_btop);
4a4d8108 21743+ }
027c5e7a 21744+out_parent:
f2c43d5f
AM
21745+ if (!err) {
21746+ if (!a->exchange)
21747+ d_move(a->src_dentry, a->dst_dentry);
21748+ else
21749+ d_exchange(a->src_dentry, a->dst_dentry);
21750+ } else {
5afbbe0d 21751+ au_update_dbtop(a->dst_dentry);
027c5e7a
AM
21752+ if (!a->dst_inode)
21753+ d_drop(a->dst_dentry);
21754+ }
f2c43d5f 21755+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR))
4a4d8108
AM
21756+ di_write_unlock(a->dst_parent);
21757+ else
21758+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 21759+out_unlock:
4a4d8108 21760+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 21761+out_free:
4a4d8108
AM
21762+ iput(a->dst_inode);
21763+ if (a->thargs)
21764+ au_whtmp_rmdir_free(a->thargs);
1c60b727 21765+ kfree(a);
4f0767ce 21766+out:
4a4d8108
AM
21767+ AuTraceErr(err);
21768+ return err;
1308ab2a 21769+}
7f207e10
AM
21770diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
21771--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
1c60b727 21772+++ linux/fs/aufs/Kconfig 2017-07-29 12:14:25.896375188 +0200
c1595e42 21773@@ -0,0 +1,185 @@
4a4d8108
AM
21774+config AUFS_FS
21775+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
21776+ help
21777+ Aufs is a stackable unification filesystem such as Unionfs,
21778+ which unifies several directories and provides a merged single
21779+ directory.
21780+ In the early days, aufs was entirely re-designed and
21781+ re-implemented Unionfs Version 1.x series. Introducing many
21782+ original ideas, approaches and improvements, it becomes totally
21783+ different from Unionfs while keeping the basic features.
1facf9fc 21784+
4a4d8108
AM
21785+if AUFS_FS
21786+choice
21787+ prompt "Maximum number of branches"
21788+ default AUFS_BRANCH_MAX_127
21789+ help
21790+ Specifies the maximum number of branches (or member directories)
21791+ in a single aufs. The larger value consumes more system
21792+ resources and has a minor impact to performance.
21793+config AUFS_BRANCH_MAX_127
21794+ bool "127"
21795+ help
21796+ Specifies the maximum number of branches (or member directories)
21797+ in a single aufs. The larger value consumes more system
21798+ resources and has a minor impact to performance.
21799+config AUFS_BRANCH_MAX_511
21800+ bool "511"
21801+ help
21802+ Specifies the maximum number of branches (or member directories)
21803+ in a single aufs. The larger value consumes more system
21804+ resources and has a minor impact to performance.
21805+config AUFS_BRANCH_MAX_1023
21806+ bool "1023"
21807+ help
21808+ Specifies the maximum number of branches (or member directories)
21809+ in a single aufs. The larger value consumes more system
21810+ resources and has a minor impact to performance.
21811+config AUFS_BRANCH_MAX_32767
21812+ bool "32767"
21813+ help
21814+ Specifies the maximum number of branches (or member directories)
21815+ in a single aufs. The larger value consumes more system
21816+ resources and has a minor impact to performance.
21817+endchoice
1facf9fc 21818+
e49829fe
JR
21819+config AUFS_SBILIST
21820+ bool
21821+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
21822+ default y
21823+ help
21824+ Automatic configuration for internal use.
21825+ When aufs supports Magic SysRq or /proc, enabled automatically.
21826+
4a4d8108
AM
21827+config AUFS_HNOTIFY
21828+ bool "Detect direct branch access (bypassing aufs)"
21829+ help
21830+ If you want to modify files on branches directly, eg. bypassing aufs,
21831+ and want aufs to detect the changes of them fully, then enable this
21832+ option and use 'udba=notify' mount option.
7f207e10 21833+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
21834+ It will have a negative impact to the performance.
21835+ See detail in aufs.5.
dece6358 21836+
4a4d8108
AM
21837+choice
21838+ prompt "method" if AUFS_HNOTIFY
21839+ default AUFS_HFSNOTIFY
21840+config AUFS_HFSNOTIFY
21841+ bool "fsnotify"
21842+ select FSNOTIFY
4a4d8108 21843+endchoice
1facf9fc 21844+
4a4d8108
AM
21845+config AUFS_EXPORT
21846+ bool "NFS-exportable aufs"
2cbb1c4b 21847+ depends on EXPORTFS
4a4d8108
AM
21848+ help
21849+ If you want to export your mounted aufs via NFS, then enable this
21850+ option. There are several requirements for this configuration.
21851+ See detail in aufs.5.
1facf9fc 21852+
4a4d8108
AM
21853+config AUFS_INO_T_64
21854+ bool
21855+ depends on AUFS_EXPORT
21856+ depends on 64BIT && !(ALPHA || S390)
21857+ default y
21858+ help
21859+ Automatic configuration for internal use.
21860+ /* typedef unsigned long/int __kernel_ino_t */
21861+ /* alpha and s390x are int */
1facf9fc 21862+
c1595e42
JR
21863+config AUFS_XATTR
21864+ bool "support for XATTR/EA (including Security Labels)"
21865+ help
21866+ If your branch fs supports XATTR/EA and you want to make them
21867+ available in aufs too, then enable this opsion and specify the
21868+ branch attributes for EA.
21869+ See detail in aufs.5.
21870+
076b876e
AM
21871+config AUFS_FHSM
21872+ bool "File-based Hierarchical Storage Management"
21873+ help
21874+ Hierarchical Storage Management (or HSM) is a well-known feature
21875+ in the storage world. Aufs provides this feature as file-based.
21876+ with multiple branches.
21877+ These multiple branches are prioritized, ie. the topmost one
21878+ should be the fastest drive and be used heavily.
21879+
4a4d8108
AM
21880+config AUFS_RDU
21881+ bool "Readdir in userspace"
21882+ help
21883+ Aufs has two methods to provide a merged view for a directory,
21884+ by a user-space library and by kernel-space natively. The latter
21885+ is always enabled but sometimes large and slow.
21886+ If you enable this option, install the library in aufs2-util
21887+ package, and set some environment variables for your readdir(3),
21888+ then the work will be handled in user-space which generally
21889+ shows better performance in most cases.
21890+ See detail in aufs.5.
1facf9fc 21891+
4a4d8108
AM
21892+config AUFS_SHWH
21893+ bool "Show whiteouts"
21894+ help
21895+ If you want to make the whiteouts in aufs visible, then enable
21896+ this option and specify 'shwh' mount option. Although it may
21897+ sounds like philosophy or something, but in technically it
21898+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 21899+
4a4d8108
AM
21900+config AUFS_BR_RAMFS
21901+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
21902+ help
21903+ If you want to use ramfs as an aufs branch fs, then enable this
21904+ option. Generally tmpfs is recommended.
21905+ Aufs prohibited them to be a branch fs by default, because
21906+ initramfs becomes unusable after switch_root or something
21907+ generally. If you sets initramfs as an aufs branch and boot your
21908+ system by switch_root, you will meet a problem easily since the
21909+ files in initramfs may be inaccessible.
21910+ Unless you are going to use ramfs as an aufs branch fs without
21911+ switch_root or something, leave it N.
1facf9fc 21912+
4a4d8108
AM
21913+config AUFS_BR_FUSE
21914+ bool "Fuse fs as an aufs branch"
21915+ depends on FUSE_FS
21916+ select AUFS_POLL
21917+ help
21918+ If you want to use fuse-based userspace filesystem as an aufs
21919+ branch fs, then enable this option.
21920+ It implements the internal poll(2) operation which is
21921+ implemented by fuse only (curretnly).
1facf9fc 21922+
4a4d8108
AM
21923+config AUFS_POLL
21924+ bool
21925+ help
21926+ Automatic configuration for internal use.
1facf9fc 21927+
4a4d8108
AM
21928+config AUFS_BR_HFSPLUS
21929+ bool "Hfsplus as an aufs branch"
21930+ depends on HFSPLUS_FS
21931+ default y
21932+ help
21933+ If you want to use hfsplus fs as an aufs branch fs, then enable
21934+ this option. This option introduces a small overhead at
21935+ copying-up a file on hfsplus.
1facf9fc 21936+
4a4d8108
AM
21937+config AUFS_BDEV_LOOP
21938+ bool
21939+ depends on BLK_DEV_LOOP
21940+ default y
21941+ help
21942+ Automatic configuration for internal use.
21943+ Convert =[ym] into =y.
1308ab2a 21944+
4a4d8108
AM
21945+config AUFS_DEBUG
21946+ bool "Debug aufs"
21947+ help
21948+ Enable this to compile aufs internal debug code.
21949+ It will have a negative impact to the performance.
21950+
21951+config AUFS_MAGIC_SYSRQ
21952+ bool
21953+ depends on AUFS_DEBUG && MAGIC_SYSRQ
21954+ default y
21955+ help
21956+ Automatic configuration for internal use.
21957+ When aufs supports Magic SysRq, enabled automatically.
21958+endif
7f207e10
AM
21959diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
21960--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 21961+++ linux/fs/aufs/loop.c 2017-07-29 12:14:25.903042072 +0200
e2f27e51 21962@@ -0,0 +1,147 @@
1facf9fc 21963+/*
a2654f78 21964+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 21965+ *
21966+ * This program, aufs is free software; you can redistribute it and/or modify
21967+ * it under the terms of the GNU General Public License as published by
21968+ * the Free Software Foundation; either version 2 of the License, or
21969+ * (at your option) any later version.
dece6358
AM
21970+ *
21971+ * This program is distributed in the hope that it will be useful,
21972+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21973+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21974+ * GNU General Public License for more details.
21975+ *
21976+ * You should have received a copy of the GNU General Public License
523b37e3 21977+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21978+ */
21979+
21980+/*
21981+ * support for loopback block device as a branch
21982+ */
21983+
1facf9fc 21984+#include "aufs.h"
21985+
392086de
AM
21986+/* added into drivers/block/loop.c */
21987+static struct file *(*backing_file_func)(struct super_block *sb);
21988+
1facf9fc 21989+/*
21990+ * test if two lower dentries have overlapping branches.
21991+ */
b752ccd1 21992+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 21993+{
b752ccd1 21994+ struct super_block *h_sb;
392086de
AM
21995+ struct file *backing_file;
21996+
21997+ if (unlikely(!backing_file_func)) {
21998+ /* don't load "loop" module here */
21999+ backing_file_func = symbol_get(loop_backing_file);
22000+ if (unlikely(!backing_file_func))
22001+ /* "loop" module is not loaded */
22002+ return 0;
22003+ }
1facf9fc 22004+
b752ccd1 22005+ h_sb = h_adding->d_sb;
392086de
AM
22006+ backing_file = backing_file_func(h_sb);
22007+ if (!backing_file)
1facf9fc 22008+ return 0;
22009+
2000de60 22010+ h_adding = backing_file->f_path.dentry;
b752ccd1
AM
22011+ /*
22012+ * h_adding can be local NFS.
22013+ * in this case aufs cannot detect the loop.
22014+ */
22015+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 22016+ return 1;
b752ccd1 22017+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 22018+}
22019+
22020+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
22021+int au_test_loopback_kthread(void)
22022+{
b752ccd1
AM
22023+ int ret;
22024+ struct task_struct *tsk = current;
a2a7ad62 22025+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
22026+
22027+ ret = 0;
22028+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
22029+ get_task_comm(comm, tsk);
22030+ c = comm[4];
b752ccd1 22031+ ret = ('0' <= c && c <= '9'
a2a7ad62 22032+ && !strncmp(comm, "loop", 4));
b752ccd1 22033+ }
1facf9fc 22034+
b752ccd1 22035+ return ret;
1facf9fc 22036+}
87a755f4
AM
22037+
22038+/* ---------------------------------------------------------------------- */
22039+
22040+#define au_warn_loopback_step 16
22041+static int au_warn_loopback_nelem = au_warn_loopback_step;
22042+static unsigned long *au_warn_loopback_array;
22043+
22044+void au_warn_loopback(struct super_block *h_sb)
22045+{
22046+ int i, new_nelem;
22047+ unsigned long *a, magic;
22048+ static DEFINE_SPINLOCK(spin);
22049+
22050+ magic = h_sb->s_magic;
22051+ spin_lock(&spin);
22052+ a = au_warn_loopback_array;
22053+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
22054+ if (a[i] == magic) {
22055+ spin_unlock(&spin);
22056+ return;
22057+ }
22058+
22059+ /* h_sb is new to us, print it */
22060+ if (i < au_warn_loopback_nelem) {
22061+ a[i] = magic;
22062+ goto pr;
22063+ }
22064+
22065+ /* expand the array */
22066+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
22067+ a = au_kzrealloc(au_warn_loopback_array,
22068+ au_warn_loopback_nelem * sizeof(unsigned long),
e2f27e51
AM
22069+ new_nelem * sizeof(unsigned long), GFP_ATOMIC,
22070+ /*may_shrink*/0);
87a755f4
AM
22071+ if (a) {
22072+ au_warn_loopback_nelem = new_nelem;
22073+ au_warn_loopback_array = a;
22074+ a[i] = magic;
22075+ goto pr;
22076+ }
22077+
22078+ spin_unlock(&spin);
22079+ AuWarn1("realloc failed, ignored\n");
22080+ return;
22081+
22082+pr:
22083+ spin_unlock(&spin);
0c3ec466
AM
22084+ pr_warn("you may want to try another patch for loopback file "
22085+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
22086+}
22087+
22088+int au_loopback_init(void)
22089+{
22090+ int err;
22091+ struct super_block *sb __maybe_unused;
22092+
79b8bda9 22093+ BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(unsigned long));
87a755f4
AM
22094+
22095+ err = 0;
22096+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
22097+ sizeof(unsigned long), GFP_NOFS);
22098+ if (unlikely(!au_warn_loopback_array))
22099+ err = -ENOMEM;
22100+
22101+ return err;
22102+}
22103+
22104+void au_loopback_fin(void)
22105+{
79b8bda9
AM
22106+ if (backing_file_func)
22107+ symbol_put(loop_backing_file);
1c60b727 22108+ kfree(au_warn_loopback_array);
87a755f4 22109+}
7f207e10
AM
22110diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
22111--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 22112+++ linux/fs/aufs/loop.h 2017-07-29 12:14:25.903042072 +0200
523b37e3 22113@@ -0,0 +1,52 @@
1facf9fc 22114+/*
a2654f78 22115+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 22116+ *
22117+ * This program, aufs is free software; you can redistribute it and/or modify
22118+ * it under the terms of the GNU General Public License as published by
22119+ * the Free Software Foundation; either version 2 of the License, or
22120+ * (at your option) any later version.
dece6358
AM
22121+ *
22122+ * This program is distributed in the hope that it will be useful,
22123+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22124+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22125+ * GNU General Public License for more details.
22126+ *
22127+ * You should have received a copy of the GNU General Public License
523b37e3 22128+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22129+ */
22130+
22131+/*
22132+ * support for loopback mount as a branch
22133+ */
22134+
22135+#ifndef __AUFS_LOOP_H__
22136+#define __AUFS_LOOP_H__
22137+
22138+#ifdef __KERNEL__
22139+
dece6358
AM
22140+struct dentry;
22141+struct super_block;
1facf9fc 22142+
22143+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
22144+/* drivers/block/loop.c */
22145+struct file *loop_backing_file(struct super_block *sb);
22146+
1facf9fc 22147+/* loop.c */
b752ccd1 22148+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 22149+int au_test_loopback_kthread(void);
87a755f4
AM
22150+void au_warn_loopback(struct super_block *h_sb);
22151+
22152+int au_loopback_init(void);
22153+void au_loopback_fin(void);
1facf9fc 22154+#else
4a4d8108 22155+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 22156+ struct dentry *h_adding)
4a4d8108 22157+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
22158+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
22159+
22160+AuStubInt0(au_loopback_init, void)
22161+AuStubVoid(au_loopback_fin, void)
1facf9fc 22162+#endif /* BLK_DEV_LOOP */
22163+
22164+#endif /* __KERNEL__ */
22165+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
22166diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
22167--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
1c60b727 22168+++ linux/fs/aufs/magic.mk 2017-07-29 12:14:25.903042072 +0200
7e9cd9fe 22169@@ -0,0 +1,30 @@
1facf9fc 22170+
22171+# defined in ${srctree}/fs/fuse/inode.c
22172+# tristate
22173+ifdef CONFIG_FUSE_FS
22174+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
22175+endif
22176+
1facf9fc 22177+# defined in ${srctree}/fs/xfs/xfs_sb.h
22178+# tristate
22179+ifdef CONFIG_XFS_FS
22180+ccflags-y += -DXFS_SB_MAGIC=0x58465342
22181+endif
22182+
22183+# defined in ${srctree}/fs/configfs/mount.c
22184+# tristate
22185+ifdef CONFIG_CONFIGFS_FS
22186+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
22187+endif
22188+
1facf9fc 22189+# defined in ${srctree}/fs/ubifs/ubifs.h
22190+# tristate
22191+ifdef CONFIG_UBIFS_FS
22192+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
22193+endif
4a4d8108
AM
22194+
22195+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
22196+# tristate
22197+ifdef CONFIG_HFSPLUS_FS
22198+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
22199+endif
7f207e10
AM
22200diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
22201--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
1c60b727 22202+++ linux/fs/aufs/Makefile 2017-07-29 12:14:25.896375188 +0200
c1595e42 22203@@ -0,0 +1,44 @@
4a4d8108
AM
22204+
22205+include ${src}/magic.mk
22206+ifeq (${CONFIG_AUFS_FS},m)
22207+include ${src}/conf.mk
22208+endif
22209+-include ${src}/priv_def.mk
22210+
22211+# cf. include/linux/kernel.h
22212+# enable pr_debug
22213+ccflags-y += -DDEBUG
f6c5ef8b
AM
22214+# sparse requires the full pathname
22215+ifdef M
523b37e3 22216+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 22217+else
523b37e3 22218+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 22219+endif
4a4d8108
AM
22220+
22221+obj-$(CONFIG_AUFS_FS) += aufs.o
22222+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
22223+ wkq.o vfsub.o dcsub.o \
e49829fe 22224+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
22225+ dinfo.o dentry.o \
22226+ dynop.o \
22227+ finfo.o file.o f_op.o \
22228+ dir.o vdir.o \
22229+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 22230+ mvdown.o ioctl.o
4a4d8108
AM
22231+
22232+# all are boolean
e49829fe 22233+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
22234+aufs-$(CONFIG_SYSFS) += sysfs.o
22235+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
22236+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
22237+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
22238+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108 22239+aufs-$(CONFIG_AUFS_EXPORT) += export.o
c1595e42
JR
22240+aufs-$(CONFIG_AUFS_XATTR) += xattr.o
22241+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
076b876e 22242+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
4a4d8108
AM
22243+aufs-$(CONFIG_AUFS_POLL) += poll.o
22244+aufs-$(CONFIG_AUFS_RDU) += rdu.o
4a4d8108
AM
22245+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
22246+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
22247+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
22248diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
22249--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
22250+++ linux/fs/aufs/module.c 2017-07-29 12:14:25.903042072 +0200
22251@@ -0,0 +1,266 @@
1facf9fc 22252+/*
a2654f78 22253+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 22254+ *
22255+ * This program, aufs is free software; you can redistribute it and/or modify
22256+ * it under the terms of the GNU General Public License as published by
22257+ * the Free Software Foundation; either version 2 of the License, or
22258+ * (at your option) any later version.
dece6358
AM
22259+ *
22260+ * This program is distributed in the hope that it will be useful,
22261+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22262+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22263+ * GNU General Public License for more details.
22264+ *
22265+ * You should have received a copy of the GNU General Public License
523b37e3 22266+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22267+ */
22268+
22269+/*
22270+ * module global variables and operations
22271+ */
22272+
22273+#include <linux/module.h>
22274+#include <linux/seq_file.h>
22275+#include "aufs.h"
22276+
e2f27e51
AM
22277+/* shrinkable realloc */
22278+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink)
1facf9fc 22279+{
e2f27e51
AM
22280+ size_t sz;
22281+ int diff;
1facf9fc 22282+
e2f27e51
AM
22283+ sz = 0;
22284+ diff = -1;
22285+ if (p) {
22286+#if 0 /* unused */
22287+ if (!new_sz) {
1c60b727 22288+ kfree(p);
e2f27e51
AM
22289+ p = NULL;
22290+ goto out;
22291+ }
22292+#else
22293+ AuDebugOn(!new_sz);
22294+#endif
22295+ sz = ksize(p);
22296+ diff = au_kmidx_sub(sz, new_sz);
22297+ }
22298+ if (sz && !diff)
22299+ goto out;
22300+
22301+ if (sz < new_sz)
22302+ /* expand or SLOB */
22303+ p = krealloc(p, new_sz, gfp);
22304+ else if (new_sz < sz && may_shrink) {
22305+ /* shrink */
22306+ void *q;
22307+
22308+ q = kmalloc(new_sz, gfp);
22309+ if (q) {
22310+ if (p) {
22311+ memcpy(q, p, new_sz);
1c60b727 22312+ kfree(p);
e2f27e51
AM
22313+ }
22314+ p = q;
22315+ } else
22316+ p = NULL;
22317+ }
22318+
22319+out:
22320+ return p;
22321+}
22322+
22323+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
22324+ int may_shrink)
22325+{
22326+ p = au_krealloc(p, new_sz, gfp, may_shrink);
22327+ if (p && new_sz > nused)
1facf9fc 22328+ memset(p + nused, 0, new_sz - nused);
22329+ return p;
22330+}
22331+
22332+/* ---------------------------------------------------------------------- */
1facf9fc 22333+/*
22334+ * aufs caches
22335+ */
1c60b727 22336+struct kmem_cache *au_cache[AuCache_Last];
5afbbe0d
AM
22337+
22338+static void au_cache_fin(void)
22339+{
22340+ int i;
22341+
22342+ /*
22343+ * Make sure all delayed rcu free inodes are flushed before we
22344+ * destroy cache.
22345+ */
22346+ rcu_barrier();
22347+
22348+ /* excluding AuCache_HNOTIFY */
22349+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
22350+ for (i = 0; i < AuCache_HNOTIFY; i++) {
1c60b727
AM
22351+ kmem_cache_destroy(au_cache[i]);
22352+ au_cache[i] = NULL;
5afbbe0d
AM
22353+ }
22354+}
22355+
1facf9fc 22356+static int __init au_cache_init(void)
22357+{
1c60b727
AM
22358+ au_cache[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
22359+ if (au_cache[AuCache_DINFO])
027c5e7a 22360+ /* SLAB_DESTROY_BY_RCU */
1c60b727 22361+ au_cache[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
f0c0a007 22362+ au_icntnr_init_once);
1c60b727
AM
22363+ if (au_cache[AuCache_ICNTNR])
22364+ au_cache[AuCache_FINFO] = AuCacheCtor(au_finfo,
f0c0a007 22365+ au_fi_init_once);
1c60b727
AM
22366+ if (au_cache[AuCache_FINFO])
22367+ au_cache[AuCache_VDIR] = AuCache(au_vdir);
22368+ if (au_cache[AuCache_VDIR])
22369+ au_cache[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
22370+ if (au_cache[AuCache_DEHSTR])
1facf9fc 22371+ return 0;
22372+
5afbbe0d 22373+ au_cache_fin();
1facf9fc 22374+ return -ENOMEM;
22375+}
22376+
1facf9fc 22377+/* ---------------------------------------------------------------------- */
22378+
22379+int au_dir_roflags;
22380+
e49829fe 22381+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
22382+/*
22383+ * iterate_supers_type() doesn't protect us from
22384+ * remounting (branch management)
22385+ */
5afbbe0d 22386+struct au_sphlhead au_sbilist;
e49829fe
JR
22387+#endif
22388+
1facf9fc 22389+/*
22390+ * functions for module interface.
22391+ */
22392+MODULE_LICENSE("GPL");
22393+/* MODULE_LICENSE("GPL v2"); */
dece6358 22394+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 22395+MODULE_DESCRIPTION(AUFS_NAME
22396+ " -- Advanced multi layered unification filesystem");
22397+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 22398+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 22399+
1facf9fc 22400+/* this module parameter has no meaning when SYSFS is disabled */
22401+int sysaufs_brs = 1;
22402+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
22403+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
22404+
076b876e 22405+/* this module parameter has no meaning when USER_NS is disabled */
8cdd5066 22406+bool au_userns;
076b876e
AM
22407+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
22408+module_param_named(allow_userns, au_userns, bool, S_IRUGO);
22409+
1facf9fc 22410+/* ---------------------------------------------------------------------- */
22411+
22412+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
22413+
22414+int au_seq_path(struct seq_file *seq, struct path *path)
22415+{
79b8bda9
AM
22416+ int err;
22417+
22418+ err = seq_path(seq, path, au_esc_chars);
1c60b727 22419+ if (err >= 0)
79b8bda9 22420+ err = 0;
1c60b727 22421+ else
79b8bda9
AM
22422+ err = -ENOMEM;
22423+
22424+ return err;
1facf9fc 22425+}
22426+
22427+/* ---------------------------------------------------------------------- */
22428+
22429+static int __init aufs_init(void)
22430+{
22431+ int err, i;
22432+ char *p;
22433+
22434+ p = au_esc_chars;
22435+ for (i = 1; i <= ' '; i++)
22436+ *p++ = i;
22437+ *p++ = '\\';
22438+ *p++ = '\x7f';
22439+ *p = 0;
22440+
22441+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
22442+
b95c5147
AM
22443+ memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop));
22444+ for (i = 0; i < AuIop_Last; i++)
22445+ aufs_iop_nogetattr[i].getattr = NULL;
22446+
1c60b727 22447+ memset(au_cache, 0, sizeof(au_cache)); /* including hnotify */
f0c0a007 22448+
e49829fe 22449+ au_sbilist_init();
1facf9fc 22450+ sysaufs_brs_init();
22451+ au_debug_init();
4a4d8108 22452+ au_dy_init();
1facf9fc 22453+ err = sysaufs_init();
22454+ if (unlikely(err))
22455+ goto out;
e49829fe 22456+ err = au_procfs_init();
4f0767ce 22457+ if (unlikely(err))
953406b4 22458+ goto out_sysaufs;
e49829fe
JR
22459+ err = au_wkq_init();
22460+ if (unlikely(err))
22461+ goto out_procfs;
87a755f4 22462+ err = au_loopback_init();
1facf9fc 22463+ if (unlikely(err))
22464+ goto out_wkq;
87a755f4
AM
22465+ err = au_hnotify_init();
22466+ if (unlikely(err))
22467+ goto out_loopback;
1facf9fc 22468+ err = au_sysrq_init();
22469+ if (unlikely(err))
22470+ goto out_hin;
22471+ err = au_cache_init();
22472+ if (unlikely(err))
22473+ goto out_sysrq;
076b876e
AM
22474+
22475+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
1facf9fc 22476+ err = register_filesystem(&aufs_fs_type);
22477+ if (unlikely(err))
22478+ goto out_cache;
076b876e 22479+
4a4d8108
AM
22480+ /* since we define pr_fmt, call printk directly */
22481+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 22482+ goto out; /* success */
22483+
4f0767ce 22484+out_cache:
1facf9fc 22485+ au_cache_fin();
4f0767ce 22486+out_sysrq:
1facf9fc 22487+ au_sysrq_fin();
4f0767ce 22488+out_hin:
4a4d8108 22489+ au_hnotify_fin();
87a755f4
AM
22490+out_loopback:
22491+ au_loopback_fin();
4f0767ce 22492+out_wkq:
1facf9fc 22493+ au_wkq_fin();
e49829fe
JR
22494+out_procfs:
22495+ au_procfs_fin();
4f0767ce 22496+out_sysaufs:
1facf9fc 22497+ sysaufs_fin();
4a4d8108 22498+ au_dy_fin();
4f0767ce 22499+out:
1facf9fc 22500+ return err;
22501+}
22502+
22503+static void __exit aufs_exit(void)
22504+{
22505+ unregister_filesystem(&aufs_fs_type);
22506+ au_cache_fin();
22507+ au_sysrq_fin();
4a4d8108 22508+ au_hnotify_fin();
87a755f4 22509+ au_loopback_fin();
1facf9fc 22510+ au_wkq_fin();
e49829fe 22511+ au_procfs_fin();
1facf9fc 22512+ sysaufs_fin();
4a4d8108 22513+ au_dy_fin();
1facf9fc 22514+}
22515+
22516+module_init(aufs_init);
22517+module_exit(aufs_exit);
7f207e10
AM
22518diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
22519--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
22520+++ linux/fs/aufs/module.h 2017-07-29 12:14:25.903042072 +0200
22521@@ -0,0 +1,101 @@
1facf9fc 22522+/*
a2654f78 22523+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 22524+ *
22525+ * This program, aufs is free software; you can redistribute it and/or modify
22526+ * it under the terms of the GNU General Public License as published by
22527+ * the Free Software Foundation; either version 2 of the License, or
22528+ * (at your option) any later version.
dece6358
AM
22529+ *
22530+ * This program is distributed in the hope that it will be useful,
22531+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22532+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22533+ * GNU General Public License for more details.
22534+ *
22535+ * You should have received a copy of the GNU General Public License
523b37e3 22536+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22537+ */
22538+
22539+/*
22540+ * module initialization and module-global
22541+ */
22542+
22543+#ifndef __AUFS_MODULE_H__
22544+#define __AUFS_MODULE_H__
22545+
22546+#ifdef __KERNEL__
22547+
22548+#include <linux/slab.h>
22549+
dece6358
AM
22550+struct path;
22551+struct seq_file;
22552+
1facf9fc 22553+/* module parameters */
1facf9fc 22554+extern int sysaufs_brs;
8cdd5066 22555+extern bool au_userns;
1facf9fc 22556+
22557+/* ---------------------------------------------------------------------- */
22558+
22559+extern int au_dir_roflags;
22560+
e2f27e51
AM
22561+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink);
22562+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
22563+ int may_shrink);
22564+
22565+static inline int au_kmidx_sub(size_t sz, size_t new_sz)
22566+{
22567+#ifndef CONFIG_SLOB
22568+ return kmalloc_index(sz) - kmalloc_index(new_sz);
22569+#else
22570+ return -1; /* SLOB is untested */
22571+#endif
22572+}
22573+
1facf9fc 22574+int au_seq_path(struct seq_file *seq, struct path *path);
22575+
e49829fe
JR
22576+#ifdef CONFIG_PROC_FS
22577+/* procfs.c */
22578+int __init au_procfs_init(void);
22579+void au_procfs_fin(void);
22580+#else
22581+AuStubInt0(au_procfs_init, void);
22582+AuStubVoid(au_procfs_fin, void);
22583+#endif
22584+
4f0767ce
JR
22585+/* ---------------------------------------------------------------------- */
22586+
1c60b727 22587+/* kmem cache */
1facf9fc 22588+enum {
22589+ AuCache_DINFO,
22590+ AuCache_ICNTNR,
22591+ AuCache_FINFO,
22592+ AuCache_VDIR,
22593+ AuCache_DEHSTR,
7eafdf33 22594+ AuCache_HNOTIFY, /* must be last */
1facf9fc 22595+ AuCache_Last
22596+};
22597+
1c60b727 22598+extern struct kmem_cache *au_cache[AuCache_Last];
f0c0a007 22599+
4a4d8108
AM
22600+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
22601+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
22602+#define AuCacheCtor(type, ctor) \
22603+ kmem_cache_create(#type, sizeof(struct type), \
22604+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 22605+
1facf9fc 22606+#define AuCacheFuncs(name, index) \
4a4d8108 22607+static inline struct au_##name *au_cache_alloc_##name(void) \
1c60b727 22608+{ return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \
4a4d8108 22609+static inline void au_cache_free_##name(struct au_##name *p) \
1c60b727 22610+{ kmem_cache_free(au_cache[AuCache_##index], p); }
1facf9fc 22611+
22612+AuCacheFuncs(dinfo, DINFO);
22613+AuCacheFuncs(icntnr, ICNTNR);
22614+AuCacheFuncs(finfo, FINFO);
22615+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
22616+AuCacheFuncs(vdir_dehstr, DEHSTR);
22617+#ifdef CONFIG_AUFS_HNOTIFY
22618+AuCacheFuncs(hnotify, HNOTIFY);
22619+#endif
1facf9fc 22620+
4a4d8108
AM
22621+#endif /* __KERNEL__ */
22622+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
22623diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
22624--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 22625+++ linux/fs/aufs/mvdown.c 2017-07-29 12:14:25.903042072 +0200
5afbbe0d 22626@@ -0,0 +1,704 @@
c2b27bf2 22627+/*
a2654f78 22628+ * Copyright (C) 2011-2017 Junjiro R. Okajima
c2b27bf2
AM
22629+ *
22630+ * This program, aufs is free software; you can redistribute it and/or modify
22631+ * it under the terms of the GNU General Public License as published by
22632+ * the Free Software Foundation; either version 2 of the License, or
22633+ * (at your option) any later version.
22634+ *
22635+ * This program is distributed in the hope that it will be useful,
22636+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22637+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22638+ * GNU General Public License for more details.
22639+ *
22640+ * You should have received a copy of the GNU General Public License
523b37e3
AM
22641+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
22642+ */
22643+
22644+/*
22645+ * move-down, opposite of copy-up
c2b27bf2
AM
22646+ */
22647+
22648+#include "aufs.h"
22649+
c2b27bf2
AM
22650+struct au_mvd_args {
22651+ struct {
c2b27bf2
AM
22652+ struct super_block *h_sb;
22653+ struct dentry *h_parent;
22654+ struct au_hinode *hdir;
392086de 22655+ struct inode *h_dir, *h_inode;
c1595e42 22656+ struct au_pin pin;
c2b27bf2
AM
22657+ } info[AUFS_MVDOWN_NARRAY];
22658+
22659+ struct aufs_mvdown mvdown;
22660+ struct dentry *dentry, *parent;
22661+ struct inode *inode, *dir;
22662+ struct super_block *sb;
22663+ aufs_bindex_t bopq, bwh, bfound;
22664+ unsigned char rename_lock;
c2b27bf2
AM
22665+};
22666+
392086de 22667+#define mvd_errno mvdown.au_errno
076b876e
AM
22668+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
22669+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid
22670+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
22671+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid
c2b27bf2 22672+
392086de
AM
22673+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
22674+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
22675+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
22676+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
22677+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
c1595e42 22678+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin
392086de
AM
22679+
22680+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
22681+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
22682+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
22683+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
22684+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c1595e42 22685+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin
c2b27bf2
AM
22686+
22687+#define AU_MVD_PR(flag, ...) do { \
22688+ if (flag) \
22689+ pr_err(__VA_ARGS__); \
22690+ } while (0)
22691+
076b876e
AM
22692+static int find_lower_writable(struct au_mvd_args *a)
22693+{
22694+ struct super_block *sb;
5afbbe0d 22695+ aufs_bindex_t bindex, bbot;
076b876e
AM
22696+ struct au_branch *br;
22697+
22698+ sb = a->sb;
22699+ bindex = a->mvd_bsrc;
5afbbe0d 22700+ bbot = au_sbbot(sb);
076b876e 22701+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
5afbbe0d 22702+ for (bindex++; bindex <= bbot; bindex++) {
076b876e
AM
22703+ br = au_sbr(sb, bindex);
22704+ if (au_br_fhsm(br->br_perm)
22705+ && (!(au_br_sb(br)->s_flags & MS_RDONLY)))
22706+ return bindex;
22707+ }
22708+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
5afbbe0d 22709+ for (bindex++; bindex <= bbot; bindex++) {
076b876e
AM
22710+ br = au_sbr(sb, bindex);
22711+ if (!au_br_rdonly(br))
22712+ return bindex;
22713+ }
22714+ else
5afbbe0d 22715+ for (bindex++; bindex <= bbot; bindex++) {
076b876e
AM
22716+ br = au_sbr(sb, bindex);
22717+ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
22718+ if (au_br_rdonly(br))
22719+ a->mvdown.flags
22720+ |= AUFS_MVDOWN_ROLOWER_R;
22721+ return bindex;
22722+ }
22723+ }
22724+
22725+ return -1;
22726+}
22727+
c2b27bf2 22728+/* make the parent dir on bdst */
392086de 22729+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22730+{
22731+ int err;
22732+
22733+ err = 0;
22734+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
22735+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
22736+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
22737+ a->mvd_h_dst_parent = NULL;
5afbbe0d 22738+ if (au_dbbot(a->parent) >= a->mvd_bdst)
c2b27bf2
AM
22739+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
22740+ if (!a->mvd_h_dst_parent) {
22741+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
22742+ if (unlikely(err)) {
392086de 22743+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
22744+ goto out;
22745+ }
22746+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
22747+ }
22748+
22749+out:
22750+ AuTraceErr(err);
22751+ return err;
22752+}
22753+
22754+/* lock them all */
392086de 22755+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22756+{
22757+ int err;
22758+ struct dentry *h_trap;
22759+
22760+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
22761+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
c1595e42
JR
22762+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst,
22763+ au_opt_udba(a->sb),
22764+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
22765+ AuTraceErr(err);
22766+ if (unlikely(err)) {
22767+ AU_MVD_PR(dmsg, "pin_dst failed\n");
22768+ goto out;
22769+ }
22770+
c2b27bf2
AM
22771+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
22772+ a->rename_lock = 0;
c1595e42
JR
22773+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
22774+ AuLsc_DI_PARENT, AuLsc_I_PARENT3,
22775+ au_opt_udba(a->sb),
22776+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
22777+ err = au_do_pin(&a->mvd_pin_src);
22778+ AuTraceErr(err);
5527c038 22779+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
c1595e42
JR
22780+ if (unlikely(err)) {
22781+ AU_MVD_PR(dmsg, "pin_src failed\n");
22782+ goto out_dst;
22783+ }
22784+ goto out; /* success */
c2b27bf2
AM
22785+ }
22786+
c2b27bf2 22787+ a->rename_lock = 1;
c1595e42
JR
22788+ au_pin_hdir_unlock(&a->mvd_pin_dst);
22789+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
22790+ au_opt_udba(a->sb),
22791+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
22792+ AuTraceErr(err);
5527c038 22793+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
c1595e42
JR
22794+ if (unlikely(err)) {
22795+ AU_MVD_PR(dmsg, "pin_src failed\n");
22796+ au_pin_hdir_lock(&a->mvd_pin_dst);
22797+ goto out_dst;
22798+ }
22799+ au_pin_hdir_unlock(&a->mvd_pin_src);
c2b27bf2
AM
22800+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
22801+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
22802+ if (h_trap) {
22803+ err = (h_trap != a->mvd_h_src_parent);
22804+ if (err)
22805+ err = (h_trap != a->mvd_h_dst_parent);
22806+ }
22807+ BUG_ON(err); /* it should never happen */
c1595e42
JR
22808+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) {
22809+ err = -EBUSY;
22810+ AuTraceErr(err);
22811+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
22812+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
22813+ au_pin_hdir_lock(&a->mvd_pin_src);
22814+ au_unpin(&a->mvd_pin_src);
22815+ au_pin_hdir_lock(&a->mvd_pin_dst);
22816+ goto out_dst;
22817+ }
22818+ goto out; /* success */
c2b27bf2 22819+
c1595e42
JR
22820+out_dst:
22821+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
22822+out:
22823+ AuTraceErr(err);
22824+ return err;
22825+}
22826+
392086de 22827+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2 22828+{
c1595e42
JR
22829+ if (!a->rename_lock)
22830+ au_unpin(&a->mvd_pin_src);
22831+ else {
c2b27bf2
AM
22832+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
22833+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
c1595e42
JR
22834+ au_pin_hdir_lock(&a->mvd_pin_src);
22835+ au_unpin(&a->mvd_pin_src);
22836+ au_pin_hdir_lock(&a->mvd_pin_dst);
22837+ }
22838+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
22839+}
22840+
22841+/* copy-down the file */
392086de 22842+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22843+{
22844+ int err;
22845+ struct au_cp_generic cpg = {
22846+ .dentry = a->dentry,
22847+ .bdst = a->mvd_bdst,
22848+ .bsrc = a->mvd_bsrc,
22849+ .len = -1,
c1595e42 22850+ .pin = &a->mvd_pin_dst,
c2b27bf2
AM
22851+ .flags = AuCpup_DTIME | AuCpup_HOPEN
22852+ };
22853+
22854+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
22855+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
22856+ au_fset_cpup(cpg.flags, OVERWRITE);
22857+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
22858+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
22859+ err = au_sio_cpdown_simple(&cpg);
22860+ if (unlikely(err))
392086de 22861+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
22862+
22863+ AuTraceErr(err);
22864+ return err;
22865+}
22866+
22867+/*
22868+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
22869+ * were sleeping
22870+ */
392086de 22871+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22872+{
22873+ int err;
22874+ struct path h_path;
22875+ struct au_branch *br;
523b37e3 22876+ struct inode *delegated;
c2b27bf2
AM
22877+
22878+ br = au_sbr(a->sb, a->mvd_bdst);
22879+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
22880+ err = PTR_ERR(h_path.dentry);
22881+ if (IS_ERR(h_path.dentry)) {
392086de 22882+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
22883+ goto out;
22884+ }
22885+
22886+ err = 0;
5527c038 22887+ if (d_is_positive(h_path.dentry)) {
c2b27bf2 22888+ h_path.mnt = au_br_mnt(br);
523b37e3 22889+ delegated = NULL;
5527c038 22890+ err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path,
523b37e3
AM
22891+ &delegated, /*force*/0);
22892+ if (unlikely(err == -EWOULDBLOCK)) {
22893+ pr_warn("cannot retry for NFSv4 delegation"
22894+ " for an internal unlink\n");
22895+ iput(delegated);
22896+ }
c2b27bf2 22897+ if (unlikely(err))
392086de 22898+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
22899+ }
22900+ dput(h_path.dentry);
22901+
22902+out:
22903+ AuTraceErr(err);
22904+ return err;
22905+}
22906+
22907+/*
22908+ * unlink the topmost h_dentry
c2b27bf2 22909+ */
392086de 22910+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22911+{
22912+ int err;
22913+ struct path h_path;
523b37e3 22914+ struct inode *delegated;
c2b27bf2
AM
22915+
22916+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
22917+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
22918+ delegated = NULL;
22919+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
22920+ if (unlikely(err == -EWOULDBLOCK)) {
22921+ pr_warn("cannot retry for NFSv4 delegation"
22922+ " for an internal unlink\n");
22923+ iput(delegated);
22924+ }
c2b27bf2 22925+ if (unlikely(err))
392086de 22926+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
22927+
22928+ AuTraceErr(err);
22929+ return err;
22930+}
22931+
076b876e
AM
22932+/* Since mvdown succeeded, we ignore an error of this function */
22933+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
22934+{
22935+ int err;
22936+ struct au_branch *br;
22937+
22938+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
22939+ br = au_sbr(a->sb, a->mvd_bsrc);
22940+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
22941+ if (!err) {
22942+ br = au_sbr(a->sb, a->mvd_bdst);
22943+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
22944+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
22945+ }
22946+ if (!err)
22947+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
22948+ else
22949+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
22950+}
22951+
c2b27bf2
AM
22952+/*
22953+ * copy-down the file and unlink the bsrc file.
22954+ * - unlink the bdst whout if exist
22955+ * - copy-down the file (with whtmp name and rename)
22956+ * - unlink the bsrc file
22957+ */
392086de 22958+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22959+{
22960+ int err;
22961+
392086de 22962+ err = au_do_mkdir(dmsg, a);
c2b27bf2 22963+ if (!err)
392086de 22964+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
22965+ if (unlikely(err))
22966+ goto out;
22967+
22968+ /*
22969+ * do not revert the activities we made on bdst since they should be
22970+ * harmless in aufs.
22971+ */
22972+
392086de 22973+ err = au_do_cpdown(dmsg, a);
c2b27bf2 22974+ if (!err)
392086de
AM
22975+ err = au_do_unlink_wh(dmsg, a);
22976+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
22977+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
22978+ if (unlikely(err))
22979+ goto out_unlock;
22980+
c1595e42
JR
22981+ AuDbg("%pd2, 0x%x, %d --> %d\n",
22982+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst);
076b876e
AM
22983+ if (find_lower_writable(a) < 0)
22984+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
22985+
22986+ if (a->mvdown.flags & AUFS_MVDOWN_STFS)
22987+ au_do_stfs(dmsg, a);
22988+
c2b27bf2 22989+ /* maintain internal array */
392086de
AM
22990+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
22991+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
5afbbe0d 22992+ au_set_dbtop(a->dentry, a->mvd_bdst);
392086de 22993+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
5afbbe0d 22994+ au_set_ibtop(a->inode, a->mvd_bdst);
79b8bda9
AM
22995+ } else {
22996+ /* hide the lower */
22997+ au_set_h_dptr(a->dentry, a->mvd_bdst, NULL);
5afbbe0d 22998+ au_set_dbbot(a->dentry, a->mvd_bsrc);
79b8bda9 22999+ au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0);
5afbbe0d 23000+ au_set_ibbot(a->inode, a->mvd_bsrc);
392086de 23001+ }
5afbbe0d
AM
23002+ if (au_dbbot(a->dentry) < a->mvd_bdst)
23003+ au_set_dbbot(a->dentry, a->mvd_bdst);
23004+ if (au_ibbot(a->inode) < a->mvd_bdst)
23005+ au_set_ibbot(a->inode, a->mvd_bdst);
c2b27bf2
AM
23006+
23007+out_unlock:
392086de 23008+ au_do_unlock(dmsg, a);
c2b27bf2
AM
23009+out:
23010+ AuTraceErr(err);
23011+ return err;
23012+}
23013+
23014+/* ---------------------------------------------------------------------- */
23015+
c2b27bf2 23016+/* make sure the file is idle */
392086de 23017+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
23018+{
23019+ int err, plinked;
c2b27bf2
AM
23020+
23021+ err = 0;
c2b27bf2 23022+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
5afbbe0d 23023+ if (au_dbtop(a->dentry) == a->mvd_bsrc
c1595e42 23024+ && au_dcount(a->dentry) == 1
c2b27bf2 23025+ && atomic_read(&a->inode->i_count) == 1
392086de 23026+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
23027+ && (!plinked || !au_plink_test(a->inode))
23028+ && a->inode->i_nlink == 1)
23029+ goto out;
23030+
23031+ err = -EBUSY;
392086de 23032+ AU_MVD_PR(dmsg,
c1595e42 23033+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
5afbbe0d 23034+ a->mvd_bsrc, au_dbtop(a->dentry), au_dcount(a->dentry),
c2b27bf2 23035+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 23036+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
23037+ plinked, plinked ? au_plink_test(a->inode) : 0);
23038+
23039+out:
23040+ AuTraceErr(err);
23041+ return err;
23042+}
23043+
23044+/* make sure the parent dir is fine */
392086de 23045+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
23046+ struct au_mvd_args *a)
23047+{
23048+ int err;
23049+ aufs_bindex_t bindex;
23050+
23051+ err = 0;
23052+ if (unlikely(au_alive_dir(a->parent))) {
23053+ err = -ENOENT;
392086de 23054+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
23055+ goto out;
23056+ }
23057+
23058+ a->bopq = au_dbdiropq(a->parent);
23059+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
23060+ AuDbg("b%d\n", bindex);
23061+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
23062+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
23063+ err = -EINVAL;
392086de
AM
23064+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
23065+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
23066+ a->bopq, a->mvd_bdst);
23067+ }
23068+
23069+out:
23070+ AuTraceErr(err);
23071+ return err;
23072+}
23073+
392086de 23074+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
23075+ struct au_mvd_args *a)
23076+{
23077+ int err;
23078+ struct au_dinfo *dinfo, *tmp;
23079+
23080+ /* lookup the next lower positive entry */
23081+ err = -ENOMEM;
23082+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
23083+ if (unlikely(!tmp))
23084+ goto out;
23085+
23086+ a->bfound = -1;
23087+ a->bwh = -1;
23088+ dinfo = au_di(a->dentry);
23089+ au_di_cp(tmp, dinfo);
23090+ au_di_swap(tmp, dinfo);
23091+
23092+ /* returns the number of positive dentries */
5afbbe0d
AM
23093+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1,
23094+ /* AuLkup_IGNORE_PERM */ 0);
c2b27bf2
AM
23095+ if (!err)
23096+ a->bwh = au_dbwh(a->dentry);
23097+ else if (err > 0)
5afbbe0d 23098+ a->bfound = au_dbtop(a->dentry);
c2b27bf2
AM
23099+
23100+ au_di_swap(tmp, dinfo);
23101+ au_rw_write_unlock(&tmp->di_rwsem);
23102+ au_di_free(tmp);
23103+ if (unlikely(err < 0))
392086de 23104+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
23105+
23106+ /*
23107+ * here, we have these cases.
23108+ * bfound == -1
23109+ * no positive dentry under bsrc. there are more sub-cases.
23110+ * bwh < 0
23111+ * there no whiteout, we can safely move-down.
23112+ * bwh <= bsrc
23113+ * impossible
23114+ * bsrc < bwh && bwh < bdst
23115+ * there is a whiteout on RO branch. cannot proceed.
23116+ * bwh == bdst
23117+ * there is a whiteout on the RW target branch. it should
23118+ * be removed.
23119+ * bdst < bwh
23120+ * there is a whiteout somewhere unrelated branch.
23121+ * -1 < bfound && bfound <= bsrc
23122+ * impossible.
23123+ * bfound < bdst
23124+ * found, but it is on RO branch between bsrc and bdst. cannot
23125+ * proceed.
23126+ * bfound == bdst
23127+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
23128+ * error.
23129+ * bdst < bfound
23130+ * found, after we create the file on bdst, it will be hidden.
23131+ */
23132+
23133+ AuDebugOn(a->bfound == -1
23134+ && a->bwh != -1
23135+ && a->bwh <= a->mvd_bsrc);
23136+ AuDebugOn(-1 < a->bfound
23137+ && a->bfound <= a->mvd_bsrc);
23138+
23139+ err = -EINVAL;
23140+ if (a->bfound == -1
23141+ && a->mvd_bsrc < a->bwh
23142+ && a->bwh != -1
23143+ && a->bwh < a->mvd_bdst) {
392086de
AM
23144+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
23145+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
23146+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
23147+ goto out;
23148+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
23149+ a->mvd_errno = EAU_MVDOWN_UPPER;
23150+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
23151+ a->mvd_bdst, a->bfound);
23152+ goto out;
23153+ }
23154+
23155+ err = 0; /* success */
23156+
23157+out:
23158+ AuTraceErr(err);
23159+ return err;
23160+}
23161+
392086de 23162+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
23163+{
23164+ int err;
23165+
392086de
AM
23166+ err = 0;
23167+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
23168+ && a->bfound == a->mvd_bdst)
23169+ err = -EEXIST;
c2b27bf2
AM
23170+ AuTraceErr(err);
23171+ return err;
23172+}
23173+
392086de 23174+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
23175+{
23176+ int err;
23177+ struct au_branch *br;
23178+
23179+ err = -EISDIR;
23180+ if (unlikely(S_ISDIR(a->inode->i_mode)))
23181+ goto out;
23182+
23183+ err = -EINVAL;
392086de 23184+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
5afbbe0d 23185+ a->mvd_bsrc = au_ibtop(a->inode);
392086de
AM
23186+ else {
23187+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
23188+ if (unlikely(a->mvd_bsrc < 0
5afbbe0d
AM
23189+ || (a->mvd_bsrc < au_dbtop(a->dentry)
23190+ || au_dbbot(a->dentry) < a->mvd_bsrc
392086de 23191+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
5afbbe0d
AM
23192+ || (a->mvd_bsrc < au_ibtop(a->inode)
23193+ || au_ibbot(a->inode) < a->mvd_bsrc
392086de
AM
23194+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
23195+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
23196+ AU_MVD_PR(dmsg, "no upper\n");
23197+ goto out;
23198+ }
23199+ }
5afbbe0d 23200+ if (unlikely(a->mvd_bsrc == au_sbbot(a->sb))) {
392086de
AM
23201+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
23202+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
23203+ goto out;
23204+ }
392086de 23205+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
23206+ br = au_sbr(a->sb, a->mvd_bsrc);
23207+ err = au_br_rdonly(br);
392086de
AM
23208+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
23209+ if (unlikely(err))
23210+ goto out;
23211+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
23212+ || IS_APPEND(a->mvd_h_src_inode))) {
23213+ if (err)
23214+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
23215+ /* go on */
23216+ } else
c2b27bf2
AM
23217+ goto out;
23218+
23219+ err = -EINVAL;
392086de
AM
23220+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
23221+ a->mvd_bdst = find_lower_writable(a);
23222+ if (unlikely(a->mvd_bdst < 0)) {
23223+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
23224+ AU_MVD_PR(dmsg, "no writable lower branch\n");
23225+ goto out;
23226+ }
23227+ } else {
23228+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
23229+ if (unlikely(a->mvd_bdst < 0
5afbbe0d 23230+ || au_sbbot(a->sb) < a->mvd_bdst)) {
392086de
AM
23231+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
23232+ AU_MVD_PR(dmsg, "no lower brid\n");
23233+ goto out;
23234+ }
c2b27bf2
AM
23235+ }
23236+
392086de 23237+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 23238+ if (!err)
392086de 23239+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 23240+ if (!err)
392086de 23241+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 23242+ if (!err)
392086de 23243+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
23244+ if (!err)
23245+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
23246+
23247+out:
23248+ AuTraceErr(err);
23249+ return err;
23250+}
23251+
23252+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
23253+{
392086de
AM
23254+ int err, e;
23255+ unsigned char dmsg;
23256+ struct au_mvd_args *args;
79b8bda9 23257+ struct inode *inode;
c2b27bf2 23258+
79b8bda9 23259+ inode = d_inode(dentry);
c2b27bf2
AM
23260+ err = -EPERM;
23261+ if (unlikely(!capable(CAP_SYS_ADMIN)))
23262+ goto out;
23263+
392086de
AM
23264+ err = -ENOMEM;
23265+ args = kmalloc(sizeof(*args), GFP_NOFS);
23266+ if (unlikely(!args))
23267+ goto out;
23268+
23269+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
23270+ if (!err)
23271+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
23272+ if (unlikely(err)) {
23273+ err = -EFAULT;
392086de
AM
23274+ AuTraceErr(err);
23275+ goto out_free;
c2b27bf2 23276+ }
392086de
AM
23277+ AuDbg("flags 0x%x\n", args->mvdown.flags);
23278+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
23279+ args->mvdown.au_errno = 0;
23280+ args->dentry = dentry;
79b8bda9 23281+ args->inode = inode;
392086de 23282+ args->sb = dentry->d_sb;
c2b27bf2 23283+
392086de
AM
23284+ err = -ENOENT;
23285+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
23286+ args->parent = dget_parent(dentry);
5527c038 23287+ args->dir = d_inode(args->parent);
febd17d6 23288+ inode_lock_nested(args->dir, I_MUTEX_PARENT);
392086de
AM
23289+ dput(args->parent);
23290+ if (unlikely(args->parent != dentry->d_parent)) {
23291+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
23292+ goto out_dir;
23293+ }
23294+
febd17d6 23295+ inode_lock_nested(inode, I_MUTEX_CHILD);
b95c5147 23296+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW);
c2b27bf2
AM
23297+ if (unlikely(err))
23298+ goto out_inode;
23299+
392086de
AM
23300+ di_write_lock_parent(args->parent);
23301+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
23302+ if (unlikely(err))
23303+ goto out_parent;
23304+
392086de 23305+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
23306+ if (unlikely(err))
23307+ goto out_parent;
c2b27bf2 23308+
392086de 23309+ au_cpup_attr_timesizes(args->dir);
79b8bda9
AM
23310+ au_cpup_attr_timesizes(inode);
23311+ if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER))
23312+ au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst));
c2b27bf2
AM
23313+ /* au_digen_dec(dentry); */
23314+
23315+out_parent:
392086de 23316+ di_write_unlock(args->parent);
c2b27bf2
AM
23317+ aufs_read_unlock(dentry, AuLock_DW);
23318+out_inode:
febd17d6 23319+ inode_unlock(inode);
c2b27bf2 23320+out_dir:
febd17d6 23321+ inode_unlock(args->dir);
392086de
AM
23322+out_free:
23323+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
23324+ if (unlikely(e))
23325+ err = -EFAULT;
1c60b727 23326+ kfree(args);
c2b27bf2
AM
23327+out:
23328+ AuTraceErr(err);
23329+ return err;
23330+}
23331diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
23332--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
23333+++ linux/fs/aufs/opts.c 2017-07-29 12:14:25.903042072 +0200
23334@@ -0,0 +1,1846 @@
1facf9fc 23335+/*
a2654f78 23336+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 23337+ *
23338+ * This program, aufs is free software; you can redistribute it and/or modify
23339+ * it under the terms of the GNU General Public License as published by
23340+ * the Free Software Foundation; either version 2 of the License, or
23341+ * (at your option) any later version.
dece6358
AM
23342+ *
23343+ * This program is distributed in the hope that it will be useful,
23344+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23345+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23346+ * GNU General Public License for more details.
23347+ *
23348+ * You should have received a copy of the GNU General Public License
523b37e3 23349+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 23350+ */
23351+
23352+/*
23353+ * mount options/flags
23354+ */
23355+
dece6358 23356+#include <linux/namei.h>
1facf9fc 23357+#include <linux/types.h> /* a distribution requires */
23358+#include <linux/parser.h>
23359+#include "aufs.h"
23360+
23361+/* ---------------------------------------------------------------------- */
23362+
23363+enum {
23364+ Opt_br,
7e9cd9fe
AM
23365+ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
23366+ Opt_idel, Opt_imod,
23367+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
dece6358 23368+ Opt_rdblk_def, Opt_rdhash_def,
7e9cd9fe 23369+ Opt_xino, Opt_noxino,
1facf9fc 23370+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
23371+ Opt_trunc_xino_path, Opt_itrunc_xino,
23372+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 23373+ Opt_shwh, Opt_noshwh,
1facf9fc 23374+ Opt_plink, Opt_noplink, Opt_list_plink,
23375+ Opt_udba,
4a4d8108 23376+ Opt_dio, Opt_nodio,
1facf9fc 23377+ Opt_diropq_a, Opt_diropq_w,
23378+ Opt_warn_perm, Opt_nowarn_perm,
23379+ Opt_wbr_copyup, Opt_wbr_create,
076b876e 23380+ Opt_fhsm_sec,
1facf9fc 23381+ Opt_verbose, Opt_noverbose,
23382+ Opt_sum, Opt_nosum, Opt_wsum,
076b876e 23383+ Opt_dirperm1, Opt_nodirperm1,
c1595e42 23384+ Opt_acl, Opt_noacl,
1facf9fc 23385+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
23386+};
23387+
23388+static match_table_t options = {
23389+ {Opt_br, "br=%s"},
23390+ {Opt_br, "br:%s"},
23391+
23392+ {Opt_add, "add=%d:%s"},
23393+ {Opt_add, "add:%d:%s"},
23394+ {Opt_add, "ins=%d:%s"},
23395+ {Opt_add, "ins:%d:%s"},
23396+ {Opt_append, "append=%s"},
23397+ {Opt_append, "append:%s"},
23398+ {Opt_prepend, "prepend=%s"},
23399+ {Opt_prepend, "prepend:%s"},
23400+
23401+ {Opt_del, "del=%s"},
23402+ {Opt_del, "del:%s"},
23403+ /* {Opt_idel, "idel:%d"}, */
23404+ {Opt_mod, "mod=%s"},
23405+ {Opt_mod, "mod:%s"},
23406+ /* {Opt_imod, "imod:%d:%s"}, */
23407+
23408+ {Opt_dirwh, "dirwh=%d"},
23409+
23410+ {Opt_xino, "xino=%s"},
23411+ {Opt_noxino, "noxino"},
23412+ {Opt_trunc_xino, "trunc_xino"},
23413+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
23414+ {Opt_notrunc_xino, "notrunc_xino"},
23415+ {Opt_trunc_xino_path, "trunc_xino=%s"},
23416+ {Opt_itrunc_xino, "itrunc_xino=%d"},
23417+ /* {Opt_zxino, "zxino=%s"}, */
23418+ {Opt_trunc_xib, "trunc_xib"},
23419+ {Opt_notrunc_xib, "notrunc_xib"},
23420+
e49829fe 23421+#ifdef CONFIG_PROC_FS
1facf9fc 23422+ {Opt_plink, "plink"},
e49829fe
JR
23423+#else
23424+ {Opt_ignore_silent, "plink"},
23425+#endif
23426+
1facf9fc 23427+ {Opt_noplink, "noplink"},
e49829fe 23428+
1facf9fc 23429+#ifdef CONFIG_AUFS_DEBUG
23430+ {Opt_list_plink, "list_plink"},
23431+#endif
23432+
23433+ {Opt_udba, "udba=%s"},
23434+
4a4d8108
AM
23435+ {Opt_dio, "dio"},
23436+ {Opt_nodio, "nodio"},
23437+
076b876e
AM
23438+#ifdef CONFIG_AUFS_FHSM
23439+ {Opt_fhsm_sec, "fhsm_sec=%d"},
23440+#else
23441+ {Opt_ignore_silent, "fhsm_sec=%d"},
23442+#endif
23443+
1facf9fc 23444+ {Opt_diropq_a, "diropq=always"},
23445+ {Opt_diropq_a, "diropq=a"},
23446+ {Opt_diropq_w, "diropq=whiteouted"},
23447+ {Opt_diropq_w, "diropq=w"},
23448+
23449+ {Opt_warn_perm, "warn_perm"},
23450+ {Opt_nowarn_perm, "nowarn_perm"},
23451+
23452+ /* keep them temporary */
1facf9fc 23453+ {Opt_ignore_silent, "nodlgt"},
1facf9fc 23454+ {Opt_ignore_silent, "clean_plink"},
23455+
dece6358
AM
23456+#ifdef CONFIG_AUFS_SHWH
23457+ {Opt_shwh, "shwh"},
23458+#endif
23459+ {Opt_noshwh, "noshwh"},
23460+
076b876e
AM
23461+ {Opt_dirperm1, "dirperm1"},
23462+ {Opt_nodirperm1, "nodirperm1"},
23463+
1facf9fc 23464+ {Opt_verbose, "verbose"},
23465+ {Opt_verbose, "v"},
23466+ {Opt_noverbose, "noverbose"},
23467+ {Opt_noverbose, "quiet"},
23468+ {Opt_noverbose, "q"},
23469+ {Opt_noverbose, "silent"},
23470+
23471+ {Opt_sum, "sum"},
23472+ {Opt_nosum, "nosum"},
23473+ {Opt_wsum, "wsum"},
23474+
23475+ {Opt_rdcache, "rdcache=%d"},
23476+ {Opt_rdblk, "rdblk=%d"},
dece6358 23477+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 23478+ {Opt_rdhash, "rdhash=%d"},
dece6358 23479+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 23480+
23481+ {Opt_wbr_create, "create=%s"},
23482+ {Opt_wbr_create, "create_policy=%s"},
23483+ {Opt_wbr_copyup, "cpup=%s"},
23484+ {Opt_wbr_copyup, "copyup=%s"},
23485+ {Opt_wbr_copyup, "copyup_policy=%s"},
23486+
c1595e42
JR
23487+ /* generic VFS flag */
23488+#ifdef CONFIG_FS_POSIX_ACL
23489+ {Opt_acl, "acl"},
23490+ {Opt_noacl, "noacl"},
23491+#else
23492+ {Opt_ignore_silent, "acl"},
23493+ {Opt_ignore_silent, "noacl"},
23494+#endif
23495+
1facf9fc 23496+ /* internal use for the scripts */
23497+ {Opt_ignore_silent, "si=%s"},
23498+
23499+ {Opt_br, "dirs=%s"},
23500+ {Opt_ignore, "debug=%d"},
23501+ {Opt_ignore, "delete=whiteout"},
23502+ {Opt_ignore, "delete=all"},
23503+ {Opt_ignore, "imap=%s"},
23504+
1308ab2a 23505+ /* temporary workaround, due to old mount(8)? */
23506+ {Opt_ignore_silent, "relatime"},
23507+
1facf9fc 23508+ {Opt_err, NULL}
23509+};
23510+
23511+/* ---------------------------------------------------------------------- */
23512+
076b876e 23513+static const char *au_parser_pattern(int val, match_table_t tbl)
1facf9fc 23514+{
076b876e
AM
23515+ struct match_token *p;
23516+
23517+ p = tbl;
23518+ while (p->pattern) {
23519+ if (p->token == val)
23520+ return p->pattern;
23521+ p++;
1facf9fc 23522+ }
23523+ BUG();
23524+ return "??";
23525+}
23526+
076b876e
AM
23527+static const char *au_optstr(int *val, match_table_t tbl)
23528+{
23529+ struct match_token *p;
23530+ int v;
23531+
23532+ v = *val;
2000de60
JR
23533+ if (!v)
23534+ goto out;
076b876e 23535+ p = tbl;
2000de60
JR
23536+ while (p->pattern) {
23537+ if (p->token
23538+ && (v & p->token) == p->token) {
076b876e
AM
23539+ *val &= ~p->token;
23540+ return p->pattern;
23541+ }
23542+ p++;
23543+ }
2000de60
JR
23544+
23545+out:
076b876e
AM
23546+ return NULL;
23547+}
23548+
1facf9fc 23549+/* ---------------------------------------------------------------------- */
23550+
1e00d052 23551+static match_table_t brperm = {
1facf9fc 23552+ {AuBrPerm_RO, AUFS_BRPERM_RO},
23553+ {AuBrPerm_RR, AUFS_BRPERM_RR},
23554+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
23555+ {0, NULL}
23556+};
1facf9fc 23557+
86dc4139 23558+static match_table_t brattr = {
076b876e
AM
23559+ /* general */
23560+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
23561+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
c1595e42 23562+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
86dc4139 23563+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
2000de60 23564+#ifdef CONFIG_AUFS_FHSM
076b876e 23565+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
2000de60
JR
23566+#endif
23567+#ifdef CONFIG_AUFS_XATTR
c1595e42
JR
23568+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
23569+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
23570+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
23571+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
23572+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
23573+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
2000de60 23574+#endif
076b876e
AM
23575+
23576+ /* ro/rr branch */
1e00d052 23577+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
076b876e
AM
23578+
23579+ /* rw branch */
23580+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
1e00d052 23581+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
076b876e 23582+
1e00d052 23583+ {0, NULL}
1facf9fc 23584+};
23585+
1e00d052
AM
23586+static int br_attr_val(char *str, match_table_t table, substring_t args[])
23587+{
23588+ int attr, v;
23589+ char *p;
23590+
23591+ attr = 0;
23592+ do {
23593+ p = strchr(str, '+');
23594+ if (p)
23595+ *p = 0;
23596+ v = match_token(str, table, args);
076b876e
AM
23597+ if (v) {
23598+ if (v & AuBrAttr_CMOO_Mask)
23599+ attr &= ~AuBrAttr_CMOO_Mask;
1e00d052 23600+ attr |= v;
076b876e 23601+ } else {
1e00d052
AM
23602+ if (p)
23603+ *p = '+';
0c3ec466 23604+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
23605+ break;
23606+ }
23607+ if (p)
23608+ str = p + 1;
23609+ } while (p);
23610+
23611+ return attr;
23612+}
23613+
076b876e
AM
23614+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
23615+{
23616+ int sz;
23617+ const char *p;
23618+ char *q;
23619+
076b876e
AM
23620+ q = str->a;
23621+ *q = 0;
23622+ p = au_optstr(&perm, brattr);
23623+ if (p) {
23624+ sz = strlen(p);
23625+ memcpy(q, p, sz + 1);
23626+ q += sz;
23627+ } else
23628+ goto out;
23629+
23630+ do {
23631+ p = au_optstr(&perm, brattr);
23632+ if (p) {
23633+ *q++ = '+';
23634+ sz = strlen(p);
23635+ memcpy(q, p, sz + 1);
23636+ q += sz;
23637+ }
23638+ } while (p);
23639+
23640+out:
c1595e42 23641+ return q - str->a;
076b876e
AM
23642+}
23643+
4a4d8108 23644+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 23645+{
076b876e
AM
23646+ int val, bad, sz;
23647+ char *p;
1facf9fc 23648+ substring_t args[MAX_OPT_ARGS];
076b876e 23649+ au_br_perm_str_t attr;
1facf9fc 23650+
1e00d052
AM
23651+ p = strchr(perm, '+');
23652+ if (p)
23653+ *p = 0;
23654+ val = match_token(perm, brperm, args);
23655+ if (!val) {
23656+ if (p)
23657+ *p = '+';
0c3ec466 23658+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
23659+ val = AuBrPerm_RO;
23660+ goto out;
23661+ }
23662+ if (!p)
23663+ goto out;
23664+
076b876e
AM
23665+ val |= br_attr_val(p + 1, brattr, args);
23666+
23667+ bad = 0;
86dc4139 23668+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
23669+ case AuBrPerm_RO:
23670+ case AuBrPerm_RR:
076b876e
AM
23671+ bad = val & AuBrWAttr_Mask;
23672+ val &= ~AuBrWAttr_Mask;
1e00d052
AM
23673+ break;
23674+ case AuBrPerm_RW:
076b876e
AM
23675+ bad = val & AuBrRAttr_Mask;
23676+ val &= ~AuBrRAttr_Mask;
1e00d052
AM
23677+ break;
23678+ }
c1595e42
JR
23679+
23680+ /*
23681+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
23682+ * does not treat it as an error, just warning.
23683+ * this is a tiny guard for the user operation.
23684+ */
23685+ if (val & AuBrAttr_UNPIN) {
23686+ bad |= AuBrAttr_UNPIN;
23687+ val &= ~AuBrAttr_UNPIN;
23688+ }
23689+
076b876e
AM
23690+ if (unlikely(bad)) {
23691+ sz = au_do_optstr_br_attr(&attr, bad);
23692+ AuDebugOn(!sz);
23693+ pr_warn("ignored branch attribute %s\n", attr.a);
23694+ }
1e00d052
AM
23695+
23696+out:
1facf9fc 23697+ return val;
23698+}
23699+
076b876e 23700+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
1facf9fc 23701+{
076b876e
AM
23702+ au_br_perm_str_t attr;
23703+ const char *p;
23704+ char *q;
1e00d052
AM
23705+ int sz;
23706+
076b876e
AM
23707+ q = str->a;
23708+ p = au_optstr(&perm, brperm);
23709+ AuDebugOn(!p || !*p);
23710+ sz = strlen(p);
23711+ memcpy(q, p, sz + 1);
23712+ q += sz;
1e00d052 23713+
076b876e
AM
23714+ sz = au_do_optstr_br_attr(&attr, perm);
23715+ if (sz) {
23716+ *q++ = '+';
23717+ memcpy(q, attr.a, sz + 1);
1e00d052
AM
23718+ }
23719+
076b876e 23720+ AuDebugOn(strlen(str->a) >= sizeof(str->a));
1facf9fc 23721+}
23722+
23723+/* ---------------------------------------------------------------------- */
23724+
23725+static match_table_t udbalevel = {
23726+ {AuOpt_UDBA_REVAL, "reval"},
23727+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
23728+#ifdef CONFIG_AUFS_HNOTIFY
23729+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
23730+#ifdef CONFIG_AUFS_HFSNOTIFY
23731+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 23732+#endif
1facf9fc 23733+#endif
23734+ {-1, NULL}
23735+};
23736+
4a4d8108 23737+static int noinline_for_stack udba_val(char *str)
1facf9fc 23738+{
23739+ substring_t args[MAX_OPT_ARGS];
23740+
7f207e10 23741+ return match_token(str, udbalevel, args);
1facf9fc 23742+}
23743+
23744+const char *au_optstr_udba(int udba)
23745+{
076b876e 23746+ return au_parser_pattern(udba, udbalevel);
1facf9fc 23747+}
23748+
23749+/* ---------------------------------------------------------------------- */
23750+
23751+static match_table_t au_wbr_create_policy = {
23752+ {AuWbrCreate_TDP, "tdp"},
23753+ {AuWbrCreate_TDP, "top-down-parent"},
23754+ {AuWbrCreate_RR, "rr"},
23755+ {AuWbrCreate_RR, "round-robin"},
23756+ {AuWbrCreate_MFS, "mfs"},
23757+ {AuWbrCreate_MFS, "most-free-space"},
23758+ {AuWbrCreate_MFSV, "mfs:%d"},
23759+ {AuWbrCreate_MFSV, "most-free-space:%d"},
23760+
f2c43d5f
AM
23761+ /* top-down regardless the parent, and then mfs */
23762+ {AuWbrCreate_TDMFS, "tdmfs:%d"},
23763+ {AuWbrCreate_TDMFSV, "tdmfs:%d:%d"},
23764+
1facf9fc 23765+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
23766+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
23767+ {AuWbrCreate_PMFS, "pmfs"},
23768+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
23769+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
23770+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 23771+
23772+ {-1, NULL}
23773+};
23774+
1facf9fc 23775+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
23776+ struct au_opt_wbr_create *create)
23777+{
23778+ int err;
23779+ unsigned long long ull;
23780+
23781+ err = 0;
a2654f78 23782+ if (!match_u64(arg, &ull))
1facf9fc 23783+ create->mfsrr_watermark = ull;
23784+ else {
4a4d8108 23785+ pr_err("bad integer in %s\n", str);
1facf9fc 23786+ err = -EINVAL;
23787+ }
23788+
23789+ return err;
23790+}
23791+
23792+static int au_wbr_mfs_sec(substring_t *arg, char *str,
23793+ struct au_opt_wbr_create *create)
23794+{
23795+ int n, err;
23796+
23797+ err = 0;
027c5e7a 23798+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 23799+ create->mfs_second = n;
23800+ else {
4a4d8108 23801+ pr_err("bad integer in %s\n", str);
1facf9fc 23802+ err = -EINVAL;
23803+ }
23804+
23805+ return err;
23806+}
23807+
4a4d8108
AM
23808+static int noinline_for_stack
23809+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 23810+{
23811+ int err, e;
23812+ substring_t args[MAX_OPT_ARGS];
23813+
23814+ err = match_token(str, au_wbr_create_policy, args);
23815+ create->wbr_create = err;
23816+ switch (err) {
23817+ case AuWbrCreate_MFSRRV:
f2c43d5f 23818+ case AuWbrCreate_TDMFSV:
392086de 23819+ case AuWbrCreate_PMFSRRV:
1facf9fc 23820+ e = au_wbr_mfs_wmark(&args[0], str, create);
23821+ if (!e)
23822+ e = au_wbr_mfs_sec(&args[1], str, create);
23823+ if (unlikely(e))
23824+ err = e;
23825+ break;
23826+ case AuWbrCreate_MFSRR:
f2c43d5f 23827+ case AuWbrCreate_TDMFS:
392086de 23828+ case AuWbrCreate_PMFSRR:
1facf9fc 23829+ e = au_wbr_mfs_wmark(&args[0], str, create);
23830+ if (unlikely(e)) {
23831+ err = e;
23832+ break;
23833+ }
23834+ /*FALLTHROUGH*/
23835+ case AuWbrCreate_MFS:
23836+ case AuWbrCreate_PMFS:
027c5e7a 23837+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 23838+ break;
23839+ case AuWbrCreate_MFSV:
23840+ case AuWbrCreate_PMFSV:
23841+ e = au_wbr_mfs_sec(&args[0], str, create);
23842+ if (unlikely(e))
23843+ err = e;
23844+ break;
23845+ }
23846+
23847+ return err;
23848+}
23849+
23850+const char *au_optstr_wbr_create(int wbr_create)
23851+{
076b876e 23852+ return au_parser_pattern(wbr_create, au_wbr_create_policy);
1facf9fc 23853+}
23854+
23855+static match_table_t au_wbr_copyup_policy = {
23856+ {AuWbrCopyup_TDP, "tdp"},
23857+ {AuWbrCopyup_TDP, "top-down-parent"},
23858+ {AuWbrCopyup_BUP, "bup"},
23859+ {AuWbrCopyup_BUP, "bottom-up-parent"},
23860+ {AuWbrCopyup_BU, "bu"},
23861+ {AuWbrCopyup_BU, "bottom-up"},
23862+ {-1, NULL}
23863+};
23864+
4a4d8108 23865+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 23866+{
23867+ substring_t args[MAX_OPT_ARGS];
23868+
23869+ return match_token(str, au_wbr_copyup_policy, args);
23870+}
23871+
23872+const char *au_optstr_wbr_copyup(int wbr_copyup)
23873+{
076b876e 23874+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
1facf9fc 23875+}
23876+
23877+/* ---------------------------------------------------------------------- */
23878+
23879+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
23880+
23881+static void dump_opts(struct au_opts *opts)
23882+{
23883+#ifdef CONFIG_AUFS_DEBUG
23884+ /* reduce stack space */
23885+ union {
23886+ struct au_opt_add *add;
23887+ struct au_opt_del *del;
23888+ struct au_opt_mod *mod;
23889+ struct au_opt_xino *xino;
23890+ struct au_opt_xino_itrunc *xino_itrunc;
23891+ struct au_opt_wbr_create *create;
23892+ } u;
23893+ struct au_opt *opt;
23894+
23895+ opt = opts->opt;
23896+ while (opt->type != Opt_tail) {
23897+ switch (opt->type) {
23898+ case Opt_add:
23899+ u.add = &opt->add;
23900+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
23901+ u.add->bindex, u.add->pathname, u.add->perm,
23902+ u.add->path.dentry);
23903+ break;
23904+ case Opt_del:
23905+ case Opt_idel:
23906+ u.del = &opt->del;
23907+ AuDbg("del {%s, %p}\n",
23908+ u.del->pathname, u.del->h_path.dentry);
23909+ break;
23910+ case Opt_mod:
23911+ case Opt_imod:
23912+ u.mod = &opt->mod;
23913+ AuDbg("mod {%s, 0x%x, %p}\n",
23914+ u.mod->path, u.mod->perm, u.mod->h_root);
23915+ break;
23916+ case Opt_append:
23917+ u.add = &opt->add;
23918+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
23919+ u.add->bindex, u.add->pathname, u.add->perm,
23920+ u.add->path.dentry);
23921+ break;
23922+ case Opt_prepend:
23923+ u.add = &opt->add;
23924+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
23925+ u.add->bindex, u.add->pathname, u.add->perm,
23926+ u.add->path.dentry);
23927+ break;
23928+ case Opt_dirwh:
23929+ AuDbg("dirwh %d\n", opt->dirwh);
23930+ break;
23931+ case Opt_rdcache:
23932+ AuDbg("rdcache %d\n", opt->rdcache);
23933+ break;
23934+ case Opt_rdblk:
23935+ AuDbg("rdblk %u\n", opt->rdblk);
23936+ break;
dece6358
AM
23937+ case Opt_rdblk_def:
23938+ AuDbg("rdblk_def\n");
23939+ break;
1facf9fc 23940+ case Opt_rdhash:
23941+ AuDbg("rdhash %u\n", opt->rdhash);
23942+ break;
dece6358
AM
23943+ case Opt_rdhash_def:
23944+ AuDbg("rdhash_def\n");
23945+ break;
1facf9fc 23946+ case Opt_xino:
23947+ u.xino = &opt->xino;
523b37e3 23948+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 23949+ break;
23950+ case Opt_trunc_xino:
23951+ AuLabel(trunc_xino);
23952+ break;
23953+ case Opt_notrunc_xino:
23954+ AuLabel(notrunc_xino);
23955+ break;
23956+ case Opt_trunc_xino_path:
23957+ case Opt_itrunc_xino:
23958+ u.xino_itrunc = &opt->xino_itrunc;
23959+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
23960+ break;
1facf9fc 23961+ case Opt_noxino:
23962+ AuLabel(noxino);
23963+ break;
23964+ case Opt_trunc_xib:
23965+ AuLabel(trunc_xib);
23966+ break;
23967+ case Opt_notrunc_xib:
23968+ AuLabel(notrunc_xib);
23969+ break;
dece6358
AM
23970+ case Opt_shwh:
23971+ AuLabel(shwh);
23972+ break;
23973+ case Opt_noshwh:
23974+ AuLabel(noshwh);
23975+ break;
076b876e
AM
23976+ case Opt_dirperm1:
23977+ AuLabel(dirperm1);
23978+ break;
23979+ case Opt_nodirperm1:
23980+ AuLabel(nodirperm1);
23981+ break;
1facf9fc 23982+ case Opt_plink:
23983+ AuLabel(plink);
23984+ break;
23985+ case Opt_noplink:
23986+ AuLabel(noplink);
23987+ break;
23988+ case Opt_list_plink:
23989+ AuLabel(list_plink);
23990+ break;
23991+ case Opt_udba:
23992+ AuDbg("udba %d, %s\n",
23993+ opt->udba, au_optstr_udba(opt->udba));
23994+ break;
4a4d8108
AM
23995+ case Opt_dio:
23996+ AuLabel(dio);
23997+ break;
23998+ case Opt_nodio:
23999+ AuLabel(nodio);
24000+ break;
1facf9fc 24001+ case Opt_diropq_a:
24002+ AuLabel(diropq_a);
24003+ break;
24004+ case Opt_diropq_w:
24005+ AuLabel(diropq_w);
24006+ break;
24007+ case Opt_warn_perm:
24008+ AuLabel(warn_perm);
24009+ break;
24010+ case Opt_nowarn_perm:
24011+ AuLabel(nowarn_perm);
24012+ break;
1facf9fc 24013+ case Opt_verbose:
24014+ AuLabel(verbose);
24015+ break;
24016+ case Opt_noverbose:
24017+ AuLabel(noverbose);
24018+ break;
24019+ case Opt_sum:
24020+ AuLabel(sum);
24021+ break;
24022+ case Opt_nosum:
24023+ AuLabel(nosum);
24024+ break;
24025+ case Opt_wsum:
24026+ AuLabel(wsum);
24027+ break;
24028+ case Opt_wbr_create:
24029+ u.create = &opt->wbr_create;
24030+ AuDbg("create %d, %s\n", u.create->wbr_create,
24031+ au_optstr_wbr_create(u.create->wbr_create));
24032+ switch (u.create->wbr_create) {
24033+ case AuWbrCreate_MFSV:
24034+ case AuWbrCreate_PMFSV:
24035+ AuDbg("%d sec\n", u.create->mfs_second);
24036+ break;
24037+ case AuWbrCreate_MFSRR:
f2c43d5f 24038+ case AuWbrCreate_TDMFS:
1facf9fc 24039+ AuDbg("%llu watermark\n",
24040+ u.create->mfsrr_watermark);
24041+ break;
24042+ case AuWbrCreate_MFSRRV:
f2c43d5f 24043+ case AuWbrCreate_TDMFSV:
392086de 24044+ case AuWbrCreate_PMFSRRV:
1facf9fc 24045+ AuDbg("%llu watermark, %d sec\n",
24046+ u.create->mfsrr_watermark,
24047+ u.create->mfs_second);
24048+ break;
24049+ }
24050+ break;
24051+ case Opt_wbr_copyup:
24052+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
24053+ au_optstr_wbr_copyup(opt->wbr_copyup));
24054+ break;
076b876e
AM
24055+ case Opt_fhsm_sec:
24056+ AuDbg("fhsm_sec %u\n", opt->fhsm_second);
24057+ break;
c1595e42
JR
24058+ case Opt_acl:
24059+ AuLabel(acl);
24060+ break;
24061+ case Opt_noacl:
24062+ AuLabel(noacl);
24063+ break;
1facf9fc 24064+ default:
24065+ BUG();
24066+ }
24067+ opt++;
24068+ }
24069+#endif
24070+}
24071+
24072+void au_opts_free(struct au_opts *opts)
24073+{
24074+ struct au_opt *opt;
24075+
24076+ opt = opts->opt;
24077+ while (opt->type != Opt_tail) {
24078+ switch (opt->type) {
24079+ case Opt_add:
24080+ case Opt_append:
24081+ case Opt_prepend:
24082+ path_put(&opt->add.path);
24083+ break;
24084+ case Opt_del:
24085+ case Opt_idel:
24086+ path_put(&opt->del.h_path);
24087+ break;
24088+ case Opt_mod:
24089+ case Opt_imod:
24090+ dput(opt->mod.h_root);
24091+ break;
24092+ case Opt_xino:
24093+ fput(opt->xino.file);
24094+ break;
24095+ }
24096+ opt++;
24097+ }
24098+}
24099+
24100+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
24101+ aufs_bindex_t bindex)
24102+{
24103+ int err;
24104+ struct au_opt_add *add = &opt->add;
24105+ char *p;
24106+
24107+ add->bindex = bindex;
1e00d052 24108+ add->perm = AuBrPerm_RO;
1facf9fc 24109+ add->pathname = opt_str;
24110+ p = strchr(opt_str, '=');
24111+ if (p) {
24112+ *p++ = 0;
24113+ if (*p)
24114+ add->perm = br_perm_val(p);
24115+ }
24116+
24117+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
24118+ if (!err) {
24119+ if (!p) {
24120+ add->perm = AuBrPerm_RO;
24121+ if (au_test_fs_rr(add->path.dentry->d_sb))
24122+ add->perm = AuBrPerm_RR;
24123+ else if (!bindex && !(sb_flags & MS_RDONLY))
24124+ add->perm = AuBrPerm_RW;
24125+ }
24126+ opt->type = Opt_add;
24127+ goto out;
24128+ }
4a4d8108 24129+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 24130+ err = -EINVAL;
24131+
4f0767ce 24132+out:
1facf9fc 24133+ return err;
24134+}
24135+
24136+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
24137+{
24138+ int err;
24139+
24140+ del->pathname = args[0].from;
24141+ AuDbg("del path %s\n", del->pathname);
24142+
24143+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
24144+ if (unlikely(err))
4a4d8108 24145+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 24146+
24147+ return err;
24148+}
24149+
24150+#if 0 /* reserved for future use */
24151+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
24152+ struct au_opt_del *del, substring_t args[])
24153+{
24154+ int err;
24155+ struct dentry *root;
24156+
24157+ err = -EINVAL;
24158+ root = sb->s_root;
24159+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 24160+ if (bindex < 0 || au_sbbot(sb) < bindex) {
4a4d8108 24161+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 24162+ goto out;
24163+ }
24164+
24165+ err = 0;
24166+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
24167+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
24168+
4f0767ce 24169+out:
1facf9fc 24170+ aufs_read_unlock(root, !AuLock_IR);
24171+ return err;
24172+}
24173+#endif
24174+
4a4d8108
AM
24175+static int noinline_for_stack
24176+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 24177+{
24178+ int err;
24179+ struct path path;
24180+ char *p;
24181+
24182+ err = -EINVAL;
24183+ mod->path = args[0].from;
24184+ p = strchr(mod->path, '=');
24185+ if (unlikely(!p)) {
4a4d8108 24186+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 24187+ goto out;
24188+ }
24189+
24190+ *p++ = 0;
24191+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
24192+ if (unlikely(err)) {
4a4d8108 24193+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 24194+ goto out;
24195+ }
24196+
24197+ mod->perm = br_perm_val(p);
24198+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
24199+ mod->h_root = dget(path.dentry);
24200+ path_put(&path);
24201+
4f0767ce 24202+out:
1facf9fc 24203+ return err;
24204+}
24205+
24206+#if 0 /* reserved for future use */
24207+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
24208+ struct au_opt_mod *mod, substring_t args[])
24209+{
24210+ int err;
24211+ struct dentry *root;
24212+
24213+ err = -EINVAL;
24214+ root = sb->s_root;
24215+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 24216+ if (bindex < 0 || au_sbbot(sb) < bindex) {
4a4d8108 24217+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 24218+ goto out;
24219+ }
24220+
24221+ err = 0;
24222+ mod->perm = br_perm_val(args[1].from);
24223+ AuDbg("mod path %s, perm 0x%x, %s\n",
24224+ mod->path, mod->perm, args[1].from);
24225+ mod->h_root = dget(au_h_dptr(root, bindex));
24226+
4f0767ce 24227+out:
1facf9fc 24228+ aufs_read_unlock(root, !AuLock_IR);
24229+ return err;
24230+}
24231+#endif
24232+
24233+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
24234+ substring_t args[])
24235+{
24236+ int err;
24237+ struct file *file;
24238+
24239+ file = au_xino_create(sb, args[0].from, /*silent*/0);
24240+ err = PTR_ERR(file);
24241+ if (IS_ERR(file))
24242+ goto out;
24243+
24244+ err = -EINVAL;
2000de60 24245+ if (unlikely(file->f_path.dentry->d_sb == sb)) {
1facf9fc 24246+ fput(file);
4a4d8108 24247+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 24248+ goto out;
24249+ }
24250+
24251+ err = 0;
24252+ xino->file = file;
24253+ xino->path = args[0].from;
24254+
4f0767ce 24255+out:
1facf9fc 24256+ return err;
24257+}
24258+
4a4d8108
AM
24259+static int noinline_for_stack
24260+au_opts_parse_xino_itrunc_path(struct super_block *sb,
24261+ struct au_opt_xino_itrunc *xino_itrunc,
24262+ substring_t args[])
1facf9fc 24263+{
24264+ int err;
5afbbe0d 24265+ aufs_bindex_t bbot, bindex;
1facf9fc 24266+ struct path path;
24267+ struct dentry *root;
24268+
24269+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
24270+ if (unlikely(err)) {
4a4d8108 24271+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 24272+ goto out;
24273+ }
24274+
24275+ xino_itrunc->bindex = -1;
24276+ root = sb->s_root;
24277+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d
AM
24278+ bbot = au_sbbot(sb);
24279+ for (bindex = 0; bindex <= bbot; bindex++) {
1facf9fc 24280+ if (au_h_dptr(root, bindex) == path.dentry) {
24281+ xino_itrunc->bindex = bindex;
24282+ break;
24283+ }
24284+ }
24285+ aufs_read_unlock(root, !AuLock_IR);
24286+ path_put(&path);
24287+
24288+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 24289+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 24290+ err = -EINVAL;
24291+ }
24292+
4f0767ce 24293+out:
1facf9fc 24294+ return err;
24295+}
24296+
24297+/* called without aufs lock */
24298+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
24299+{
24300+ int err, n, token;
24301+ aufs_bindex_t bindex;
24302+ unsigned char skipped;
24303+ struct dentry *root;
24304+ struct au_opt *opt, *opt_tail;
24305+ char *opt_str;
24306+ /* reduce the stack space */
24307+ union {
24308+ struct au_opt_xino_itrunc *xino_itrunc;
24309+ struct au_opt_wbr_create *create;
24310+ } u;
24311+ struct {
24312+ substring_t args[MAX_OPT_ARGS];
24313+ } *a;
24314+
24315+ err = -ENOMEM;
24316+ a = kmalloc(sizeof(*a), GFP_NOFS);
24317+ if (unlikely(!a))
24318+ goto out;
24319+
24320+ root = sb->s_root;
24321+ err = 0;
24322+ bindex = 0;
24323+ opt = opts->opt;
24324+ opt_tail = opt + opts->max_opt - 1;
24325+ opt->type = Opt_tail;
24326+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
24327+ err = -EINVAL;
24328+ skipped = 0;
24329+ token = match_token(opt_str, options, a->args);
24330+ switch (token) {
24331+ case Opt_br:
24332+ err = 0;
24333+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
24334+ && *opt_str) {
24335+ err = opt_add(opt, opt_str, opts->sb_flags,
24336+ bindex++);
24337+ if (unlikely(!err && ++opt > opt_tail)) {
24338+ err = -E2BIG;
24339+ break;
24340+ }
24341+ opt->type = Opt_tail;
24342+ skipped = 1;
24343+ }
24344+ break;
24345+ case Opt_add:
24346+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 24347+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 24348+ break;
24349+ }
24350+ bindex = n;
24351+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
24352+ bindex);
24353+ if (!err)
24354+ opt->type = token;
24355+ break;
24356+ case Opt_append:
24357+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
24358+ /*dummy bindex*/1);
24359+ if (!err)
24360+ opt->type = token;
24361+ break;
24362+ case Opt_prepend:
24363+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
24364+ /*bindex*/0);
24365+ if (!err)
24366+ opt->type = token;
24367+ break;
24368+ case Opt_del:
24369+ err = au_opts_parse_del(&opt->del, a->args);
24370+ if (!err)
24371+ opt->type = token;
24372+ break;
24373+#if 0 /* reserved for future use */
24374+ case Opt_idel:
24375+ del->pathname = "(indexed)";
24376+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 24377+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 24378+ break;
24379+ }
24380+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
24381+ if (!err)
24382+ opt->type = token;
24383+ break;
24384+#endif
24385+ case Opt_mod:
24386+ err = au_opts_parse_mod(&opt->mod, a->args);
24387+ if (!err)
24388+ opt->type = token;
24389+ break;
24390+#ifdef IMOD /* reserved for future use */
24391+ case Opt_imod:
24392+ u.mod->path = "(indexed)";
24393+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 24394+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 24395+ break;
24396+ }
24397+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
24398+ if (!err)
24399+ opt->type = token;
24400+ break;
24401+#endif
24402+ case Opt_xino:
24403+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
24404+ if (!err)
24405+ opt->type = token;
24406+ break;
24407+
24408+ case Opt_trunc_xino_path:
24409+ err = au_opts_parse_xino_itrunc_path
24410+ (sb, &opt->xino_itrunc, a->args);
24411+ if (!err)
24412+ opt->type = token;
24413+ break;
24414+
24415+ case Opt_itrunc_xino:
24416+ u.xino_itrunc = &opt->xino_itrunc;
24417+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 24418+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 24419+ break;
24420+ }
24421+ u.xino_itrunc->bindex = n;
24422+ aufs_read_lock(root, AuLock_FLUSH);
5afbbe0d 24423+ if (n < 0 || au_sbbot(sb) < n) {
4a4d8108 24424+ pr_err("out of bounds, %d\n", n);
1facf9fc 24425+ aufs_read_unlock(root, !AuLock_IR);
24426+ break;
24427+ }
24428+ aufs_read_unlock(root, !AuLock_IR);
24429+ err = 0;
24430+ opt->type = token;
24431+ break;
24432+
24433+ case Opt_dirwh:
24434+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
24435+ break;
24436+ err = 0;
24437+ opt->type = token;
24438+ break;
24439+
24440+ case Opt_rdcache:
027c5e7a
AM
24441+ if (unlikely(match_int(&a->args[0], &n))) {
24442+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 24443+ break;
027c5e7a
AM
24444+ }
24445+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
24446+ pr_err("rdcache must be smaller than %d\n",
24447+ AUFS_RDCACHE_MAX);
24448+ break;
24449+ }
24450+ opt->rdcache = n;
1facf9fc 24451+ err = 0;
24452+ opt->type = token;
24453+ break;
24454+ case Opt_rdblk:
24455+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 24456+ || n < 0
1facf9fc 24457+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 24458+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 24459+ break;
24460+ }
1308ab2a 24461+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
24462+ pr_err("rdblk must be larger than %d\n",
24463+ NAME_MAX);
1facf9fc 24464+ break;
24465+ }
24466+ opt->rdblk = n;
24467+ err = 0;
24468+ opt->type = token;
24469+ break;
24470+ case Opt_rdhash:
24471+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 24472+ || n < 0
1facf9fc 24473+ || n * sizeof(struct hlist_head)
24474+ > KMALLOC_MAX_SIZE)) {
4a4d8108 24475+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 24476+ break;
24477+ }
24478+ opt->rdhash = n;
24479+ err = 0;
24480+ opt->type = token;
24481+ break;
24482+
24483+ case Opt_trunc_xino:
24484+ case Opt_notrunc_xino:
24485+ case Opt_noxino:
24486+ case Opt_trunc_xib:
24487+ case Opt_notrunc_xib:
dece6358
AM
24488+ case Opt_shwh:
24489+ case Opt_noshwh:
076b876e
AM
24490+ case Opt_dirperm1:
24491+ case Opt_nodirperm1:
1facf9fc 24492+ case Opt_plink:
24493+ case Opt_noplink:
24494+ case Opt_list_plink:
4a4d8108
AM
24495+ case Opt_dio:
24496+ case Opt_nodio:
1facf9fc 24497+ case Opt_diropq_a:
24498+ case Opt_diropq_w:
24499+ case Opt_warn_perm:
24500+ case Opt_nowarn_perm:
1facf9fc 24501+ case Opt_verbose:
24502+ case Opt_noverbose:
24503+ case Opt_sum:
24504+ case Opt_nosum:
24505+ case Opt_wsum:
dece6358
AM
24506+ case Opt_rdblk_def:
24507+ case Opt_rdhash_def:
c1595e42
JR
24508+ case Opt_acl:
24509+ case Opt_noacl:
1facf9fc 24510+ err = 0;
24511+ opt->type = token;
24512+ break;
24513+
24514+ case Opt_udba:
24515+ opt->udba = udba_val(a->args[0].from);
24516+ if (opt->udba >= 0) {
24517+ err = 0;
24518+ opt->type = token;
24519+ } else
4a4d8108 24520+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 24521+ break;
24522+
24523+ case Opt_wbr_create:
24524+ u.create = &opt->wbr_create;
24525+ u.create->wbr_create
24526+ = au_wbr_create_val(a->args[0].from, u.create);
24527+ if (u.create->wbr_create >= 0) {
24528+ err = 0;
24529+ opt->type = token;
24530+ } else
4a4d8108 24531+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 24532+ break;
24533+ case Opt_wbr_copyup:
24534+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
24535+ if (opt->wbr_copyup >= 0) {
24536+ err = 0;
24537+ opt->type = token;
24538+ } else
4a4d8108 24539+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 24540+ break;
24541+
076b876e
AM
24542+ case Opt_fhsm_sec:
24543+ if (unlikely(match_int(&a->args[0], &n)
24544+ || n < 0)) {
24545+ pr_err("bad integer in %s\n", opt_str);
24546+ break;
24547+ }
24548+ if (sysaufs_brs) {
24549+ opt->fhsm_second = n;
24550+ opt->type = token;
24551+ } else
24552+ pr_warn("ignored %s\n", opt_str);
24553+ err = 0;
24554+ break;
24555+
1facf9fc 24556+ case Opt_ignore:
0c3ec466 24557+ pr_warn("ignored %s\n", opt_str);
1facf9fc 24558+ /*FALLTHROUGH*/
24559+ case Opt_ignore_silent:
24560+ skipped = 1;
24561+ err = 0;
24562+ break;
24563+ case Opt_err:
4a4d8108 24564+ pr_err("unknown option %s\n", opt_str);
1facf9fc 24565+ break;
24566+ }
24567+
24568+ if (!err && !skipped) {
24569+ if (unlikely(++opt > opt_tail)) {
24570+ err = -E2BIG;
24571+ opt--;
24572+ opt->type = Opt_tail;
24573+ break;
24574+ }
24575+ opt->type = Opt_tail;
24576+ }
24577+ }
24578+
1c60b727 24579+ kfree(a);
1facf9fc 24580+ dump_opts(opts);
24581+ if (unlikely(err))
24582+ au_opts_free(opts);
24583+
4f0767ce 24584+out:
1facf9fc 24585+ return err;
24586+}
24587+
24588+static int au_opt_wbr_create(struct super_block *sb,
24589+ struct au_opt_wbr_create *create)
24590+{
24591+ int err;
24592+ struct au_sbinfo *sbinfo;
24593+
dece6358
AM
24594+ SiMustWriteLock(sb);
24595+
1facf9fc 24596+ err = 1; /* handled */
24597+ sbinfo = au_sbi(sb);
24598+ if (sbinfo->si_wbr_create_ops->fin) {
24599+ err = sbinfo->si_wbr_create_ops->fin(sb);
24600+ if (!err)
24601+ err = 1;
24602+ }
24603+
24604+ sbinfo->si_wbr_create = create->wbr_create;
24605+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
24606+ switch (create->wbr_create) {
24607+ case AuWbrCreate_MFSRRV:
24608+ case AuWbrCreate_MFSRR:
f2c43d5f
AM
24609+ case AuWbrCreate_TDMFS:
24610+ case AuWbrCreate_TDMFSV:
392086de
AM
24611+ case AuWbrCreate_PMFSRR:
24612+ case AuWbrCreate_PMFSRRV:
1facf9fc 24613+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
24614+ /*FALLTHROUGH*/
24615+ case AuWbrCreate_MFS:
24616+ case AuWbrCreate_MFSV:
24617+ case AuWbrCreate_PMFS:
24618+ case AuWbrCreate_PMFSV:
e49829fe
JR
24619+ sbinfo->si_wbr_mfs.mfs_expire
24620+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 24621+ break;
24622+ }
24623+
24624+ if (sbinfo->si_wbr_create_ops->init)
24625+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
24626+
24627+ return err;
24628+}
24629+
24630+/*
24631+ * returns,
24632+ * plus: processed without an error
24633+ * zero: unprocessed
24634+ */
24635+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
24636+ struct au_opts *opts)
24637+{
24638+ int err;
24639+ struct au_sbinfo *sbinfo;
24640+
dece6358
AM
24641+ SiMustWriteLock(sb);
24642+
1facf9fc 24643+ err = 1; /* handled */
24644+ sbinfo = au_sbi(sb);
24645+ switch (opt->type) {
24646+ case Opt_udba:
24647+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
24648+ sbinfo->si_mntflags |= opt->udba;
24649+ opts->given_udba |= opt->udba;
24650+ break;
24651+
24652+ case Opt_plink:
24653+ au_opt_set(sbinfo->si_mntflags, PLINK);
24654+ break;
24655+ case Opt_noplink:
24656+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 24657+ au_plink_put(sb, /*verbose*/1);
1facf9fc 24658+ au_opt_clr(sbinfo->si_mntflags, PLINK);
24659+ break;
24660+ case Opt_list_plink:
24661+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
24662+ au_plink_list(sb);
24663+ break;
24664+
4a4d8108
AM
24665+ case Opt_dio:
24666+ au_opt_set(sbinfo->si_mntflags, DIO);
24667+ au_fset_opts(opts->flags, REFRESH_DYAOP);
24668+ break;
24669+ case Opt_nodio:
24670+ au_opt_clr(sbinfo->si_mntflags, DIO);
24671+ au_fset_opts(opts->flags, REFRESH_DYAOP);
24672+ break;
24673+
076b876e
AM
24674+ case Opt_fhsm_sec:
24675+ au_fhsm_set(sbinfo, opt->fhsm_second);
24676+ break;
24677+
1facf9fc 24678+ case Opt_diropq_a:
24679+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
24680+ break;
24681+ case Opt_diropq_w:
24682+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
24683+ break;
24684+
24685+ case Opt_warn_perm:
24686+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
24687+ break;
24688+ case Opt_nowarn_perm:
24689+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
24690+ break;
24691+
1facf9fc 24692+ case Opt_verbose:
24693+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
24694+ break;
24695+ case Opt_noverbose:
24696+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
24697+ break;
24698+
24699+ case Opt_sum:
24700+ au_opt_set(sbinfo->si_mntflags, SUM);
24701+ break;
24702+ case Opt_wsum:
24703+ au_opt_clr(sbinfo->si_mntflags, SUM);
24704+ au_opt_set(sbinfo->si_mntflags, SUM_W);
24705+ case Opt_nosum:
24706+ au_opt_clr(sbinfo->si_mntflags, SUM);
24707+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
24708+ break;
24709+
24710+ case Opt_wbr_create:
24711+ err = au_opt_wbr_create(sb, &opt->wbr_create);
24712+ break;
24713+ case Opt_wbr_copyup:
24714+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
24715+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
24716+ break;
24717+
24718+ case Opt_dirwh:
24719+ sbinfo->si_dirwh = opt->dirwh;
24720+ break;
24721+
24722+ case Opt_rdcache:
e49829fe
JR
24723+ sbinfo->si_rdcache
24724+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 24725+ break;
24726+ case Opt_rdblk:
24727+ sbinfo->si_rdblk = opt->rdblk;
24728+ break;
dece6358
AM
24729+ case Opt_rdblk_def:
24730+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
24731+ break;
1facf9fc 24732+ case Opt_rdhash:
24733+ sbinfo->si_rdhash = opt->rdhash;
24734+ break;
dece6358
AM
24735+ case Opt_rdhash_def:
24736+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
24737+ break;
24738+
24739+ case Opt_shwh:
24740+ au_opt_set(sbinfo->si_mntflags, SHWH);
24741+ break;
24742+ case Opt_noshwh:
24743+ au_opt_clr(sbinfo->si_mntflags, SHWH);
24744+ break;
1facf9fc 24745+
076b876e
AM
24746+ case Opt_dirperm1:
24747+ au_opt_set(sbinfo->si_mntflags, DIRPERM1);
24748+ break;
24749+ case Opt_nodirperm1:
24750+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
24751+ break;
24752+
1facf9fc 24753+ case Opt_trunc_xino:
24754+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
24755+ break;
24756+ case Opt_notrunc_xino:
24757+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
24758+ break;
24759+
24760+ case Opt_trunc_xino_path:
24761+ case Opt_itrunc_xino:
24762+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
24763+ if (!err)
24764+ err = 1;
24765+ break;
24766+
24767+ case Opt_trunc_xib:
24768+ au_fset_opts(opts->flags, TRUNC_XIB);
24769+ break;
24770+ case Opt_notrunc_xib:
24771+ au_fclr_opts(opts->flags, TRUNC_XIB);
24772+ break;
24773+
c1595e42
JR
24774+ case Opt_acl:
24775+ sb->s_flags |= MS_POSIXACL;
24776+ break;
24777+ case Opt_noacl:
24778+ sb->s_flags &= ~MS_POSIXACL;
24779+ break;
24780+
1facf9fc 24781+ default:
24782+ err = 0;
24783+ break;
24784+ }
24785+
24786+ return err;
24787+}
24788+
24789+/*
24790+ * returns tri-state.
24791+ * plus: processed without an error
24792+ * zero: unprocessed
24793+ * minus: error
24794+ */
24795+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
24796+ struct au_opts *opts)
24797+{
24798+ int err, do_refresh;
24799+
24800+ err = 0;
24801+ switch (opt->type) {
24802+ case Opt_append:
5afbbe0d 24803+ opt->add.bindex = au_sbbot(sb) + 1;
1facf9fc 24804+ if (opt->add.bindex < 0)
24805+ opt->add.bindex = 0;
24806+ goto add;
24807+ case Opt_prepend:
24808+ opt->add.bindex = 0;
f6b6e03d 24809+ add: /* indented label */
1facf9fc 24810+ case Opt_add:
24811+ err = au_br_add(sb, &opt->add,
24812+ au_ftest_opts(opts->flags, REMOUNT));
24813+ if (!err) {
24814+ err = 1;
027c5e7a 24815+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 24816+ }
24817+ break;
24818+
24819+ case Opt_del:
24820+ case Opt_idel:
24821+ err = au_br_del(sb, &opt->del,
24822+ au_ftest_opts(opts->flags, REMOUNT));
24823+ if (!err) {
24824+ err = 1;
24825+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 24826+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 24827+ }
24828+ break;
24829+
24830+ case Opt_mod:
24831+ case Opt_imod:
24832+ err = au_br_mod(sb, &opt->mod,
24833+ au_ftest_opts(opts->flags, REMOUNT),
24834+ &do_refresh);
24835+ if (!err) {
24836+ err = 1;
027c5e7a
AM
24837+ if (do_refresh)
24838+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 24839+ }
24840+ break;
24841+ }
1facf9fc 24842+ return err;
24843+}
24844+
24845+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
24846+ struct au_opt_xino **opt_xino,
24847+ struct au_opts *opts)
24848+{
24849+ int err;
5afbbe0d 24850+ aufs_bindex_t bbot, bindex;
1facf9fc 24851+ struct dentry *root, *parent, *h_root;
24852+
24853+ err = 0;
24854+ switch (opt->type) {
24855+ case Opt_xino:
24856+ err = au_xino_set(sb, &opt->xino,
24857+ !!au_ftest_opts(opts->flags, REMOUNT));
24858+ if (unlikely(err))
24859+ break;
24860+
24861+ *opt_xino = &opt->xino;
24862+ au_xino_brid_set(sb, -1);
24863+
24864+ /* safe d_parent access */
2000de60 24865+ parent = opt->xino.file->f_path.dentry->d_parent;
1facf9fc 24866+ root = sb->s_root;
5afbbe0d
AM
24867+ bbot = au_sbbot(sb);
24868+ for (bindex = 0; bindex <= bbot; bindex++) {
1facf9fc 24869+ h_root = au_h_dptr(root, bindex);
24870+ if (h_root == parent) {
24871+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
24872+ break;
24873+ }
24874+ }
24875+ break;
24876+
24877+ case Opt_noxino:
24878+ au_xino_clr(sb);
24879+ au_xino_brid_set(sb, -1);
24880+ *opt_xino = (void *)-1;
24881+ break;
24882+ }
24883+
24884+ return err;
24885+}
24886+
24887+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
24888+ unsigned int pending)
24889+{
076b876e 24890+ int err, fhsm;
5afbbe0d 24891+ aufs_bindex_t bindex, bbot;
79b8bda9 24892+ unsigned char do_plink, skip, do_free, can_no_dreval;
1facf9fc 24893+ struct au_branch *br;
24894+ struct au_wbr *wbr;
79b8bda9 24895+ struct dentry *root, *dentry;
1facf9fc 24896+ struct inode *dir, *h_dir;
24897+ struct au_sbinfo *sbinfo;
24898+ struct au_hinode *hdir;
24899+
dece6358
AM
24900+ SiMustAnyLock(sb);
24901+
1facf9fc 24902+ sbinfo = au_sbi(sb);
24903+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
24904+
dece6358
AM
24905+ if (!(sb_flags & MS_RDONLY)) {
24906+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 24907+ pr_warn("first branch should be rw\n");
dece6358 24908+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
febd17d6 24909+ pr_warn_once("shwh should be used with ro\n");
dece6358 24910+ }
1facf9fc 24911+
4a4d8108 24912+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 24913+ && !au_opt_test(sbinfo->si_mntflags, XINO))
febd17d6 24914+ pr_warn_once("udba=*notify requires xino\n");
1facf9fc 24915+
076b876e 24916+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
febd17d6
JR
24917+ pr_warn_once("dirperm1 breaks the protection"
24918+ " by the permission bits on the lower branch\n");
076b876e 24919+
1facf9fc 24920+ err = 0;
076b876e 24921+ fhsm = 0;
1facf9fc 24922+ root = sb->s_root;
5527c038 24923+ dir = d_inode(root);
1facf9fc 24924+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
79b8bda9
AM
24925+ can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending),
24926+ UDBA_NONE);
5afbbe0d
AM
24927+ bbot = au_sbbot(sb);
24928+ for (bindex = 0; !err && bindex <= bbot; bindex++) {
1facf9fc 24929+ skip = 0;
24930+ h_dir = au_h_iptr(dir, bindex);
24931+ br = au_sbr(sb, bindex);
1facf9fc 24932+
c1595e42
JR
24933+ if ((br->br_perm & AuBrAttr_ICEX)
24934+ && !h_dir->i_op->listxattr)
24935+ br->br_perm &= ~AuBrAttr_ICEX;
24936+#if 0
24937+ if ((br->br_perm & AuBrAttr_ICEX_SEC)
24938+ && (au_br_sb(br)->s_flags & MS_NOSEC))
24939+ br->br_perm &= ~AuBrAttr_ICEX_SEC;
24940+#endif
24941+
24942+ do_free = 0;
1facf9fc 24943+ wbr = br->br_wbr;
24944+ if (wbr)
24945+ wbr_wh_read_lock(wbr);
24946+
1e00d052 24947+ if (!au_br_writable(br->br_perm)) {
1facf9fc 24948+ do_free = !!wbr;
24949+ skip = (!wbr
24950+ || (!wbr->wbr_whbase
24951+ && !wbr->wbr_plink
24952+ && !wbr->wbr_orph));
1e00d052 24953+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 24954+ /* skip = (!br->br_whbase && !br->br_orph); */
24955+ skip = (!wbr || !wbr->wbr_whbase);
24956+ if (skip && wbr) {
24957+ if (do_plink)
24958+ skip = !!wbr->wbr_plink;
24959+ else
24960+ skip = !wbr->wbr_plink;
24961+ }
1e00d052 24962+ } else {
1facf9fc 24963+ /* skip = (br->br_whbase && br->br_ohph); */
24964+ skip = (wbr && wbr->wbr_whbase);
24965+ if (skip) {
24966+ if (do_plink)
24967+ skip = !!wbr->wbr_plink;
24968+ else
24969+ skip = !wbr->wbr_plink;
24970+ }
1facf9fc 24971+ }
24972+ if (wbr)
24973+ wbr_wh_read_unlock(wbr);
24974+
79b8bda9
AM
24975+ if (can_no_dreval) {
24976+ dentry = br->br_path.dentry;
24977+ spin_lock(&dentry->d_lock);
24978+ if (dentry->d_flags &
24979+ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE))
24980+ can_no_dreval = 0;
24981+ spin_unlock(&dentry->d_lock);
24982+ }
24983+
076b876e
AM
24984+ if (au_br_fhsm(br->br_perm)) {
24985+ fhsm++;
24986+ AuDebugOn(!br->br_fhsm);
24987+ }
24988+
1facf9fc 24989+ if (skip)
24990+ continue;
24991+
24992+ hdir = au_hi(dir, bindex);
5afbbe0d 24993+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 24994+ if (wbr)
24995+ wbr_wh_write_lock(wbr);
86dc4139 24996+ err = au_wh_init(br, sb);
1facf9fc 24997+ if (wbr)
24998+ wbr_wh_write_unlock(wbr);
5afbbe0d 24999+ au_hn_inode_unlock(hdir);
1facf9fc 25000+
25001+ if (!err && do_free) {
1c60b727 25002+ kfree(wbr);
1facf9fc 25003+ br->br_wbr = NULL;
25004+ }
25005+ }
25006+
79b8bda9
AM
25007+ if (can_no_dreval)
25008+ au_fset_si(sbinfo, NO_DREVAL);
25009+ else
25010+ au_fclr_si(sbinfo, NO_DREVAL);
25011+
c1595e42 25012+ if (fhsm >= 2) {
076b876e 25013+ au_fset_si(sbinfo, FHSM);
5afbbe0d 25014+ for (bindex = bbot; bindex >= 0; bindex--) {
c1595e42
JR
25015+ br = au_sbr(sb, bindex);
25016+ if (au_br_fhsm(br->br_perm)) {
25017+ au_fhsm_set_bottom(sb, bindex);
25018+ break;
25019+ }
25020+ }
25021+ } else {
076b876e 25022+ au_fclr_si(sbinfo, FHSM);
c1595e42
JR
25023+ au_fhsm_set_bottom(sb, -1);
25024+ }
076b876e 25025+
1facf9fc 25026+ return err;
25027+}
25028+
25029+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
25030+{
25031+ int err;
25032+ unsigned int tmp;
5afbbe0d 25033+ aufs_bindex_t bindex, bbot;
1facf9fc 25034+ struct au_opt *opt;
25035+ struct au_opt_xino *opt_xino, xino;
25036+ struct au_sbinfo *sbinfo;
027c5e7a 25037+ struct au_branch *br;
076b876e 25038+ struct inode *dir;
1facf9fc 25039+
dece6358
AM
25040+ SiMustWriteLock(sb);
25041+
1facf9fc 25042+ err = 0;
25043+ opt_xino = NULL;
25044+ opt = opts->opt;
25045+ while (err >= 0 && opt->type != Opt_tail)
25046+ err = au_opt_simple(sb, opt++, opts);
25047+ if (err > 0)
25048+ err = 0;
25049+ else if (unlikely(err < 0))
25050+ goto out;
25051+
25052+ /* disable xino and udba temporary */
25053+ sbinfo = au_sbi(sb);
25054+ tmp = sbinfo->si_mntflags;
25055+ au_opt_clr(sbinfo->si_mntflags, XINO);
25056+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
25057+
25058+ opt = opts->opt;
25059+ while (err >= 0 && opt->type != Opt_tail)
25060+ err = au_opt_br(sb, opt++, opts);
25061+ if (err > 0)
25062+ err = 0;
25063+ else if (unlikely(err < 0))
25064+ goto out;
25065+
5afbbe0d
AM
25066+ bbot = au_sbbot(sb);
25067+ if (unlikely(bbot < 0)) {
1facf9fc 25068+ err = -EINVAL;
4a4d8108 25069+ pr_err("no branches\n");
1facf9fc 25070+ goto out;
25071+ }
25072+
25073+ if (au_opt_test(tmp, XINO))
25074+ au_opt_set(sbinfo->si_mntflags, XINO);
25075+ opt = opts->opt;
25076+ while (!err && opt->type != Opt_tail)
25077+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
25078+ if (unlikely(err))
25079+ goto out;
25080+
25081+ err = au_opts_verify(sb, sb->s_flags, tmp);
25082+ if (unlikely(err))
25083+ goto out;
25084+
25085+ /* restore xino */
25086+ if (au_opt_test(tmp, XINO) && !opt_xino) {
25087+ xino.file = au_xino_def(sb);
25088+ err = PTR_ERR(xino.file);
25089+ if (IS_ERR(xino.file))
25090+ goto out;
25091+
25092+ err = au_xino_set(sb, &xino, /*remount*/0);
25093+ fput(xino.file);
25094+ if (unlikely(err))
25095+ goto out;
25096+ }
25097+
25098+ /* restore udba */
027c5e7a 25099+ tmp &= AuOptMask_UDBA;
1facf9fc 25100+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a 25101+ sbinfo->si_mntflags |= tmp;
5afbbe0d
AM
25102+ bbot = au_sbbot(sb);
25103+ for (bindex = 0; bindex <= bbot; bindex++) {
027c5e7a
AM
25104+ br = au_sbr(sb, bindex);
25105+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
25106+ if (unlikely(err))
25107+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
25108+ bindex, err);
25109+ /* go on even if err */
25110+ }
4a4d8108 25111+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
5527c038 25112+ dir = d_inode(sb->s_root);
4a4d8108 25113+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 25114+ }
25115+
4f0767ce 25116+out:
1facf9fc 25117+ return err;
25118+}
25119+
25120+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
25121+{
25122+ int err, rerr;
79b8bda9 25123+ unsigned char no_dreval;
1facf9fc 25124+ struct inode *dir;
25125+ struct au_opt_xino *opt_xino;
25126+ struct au_opt *opt;
25127+ struct au_sbinfo *sbinfo;
25128+
dece6358
AM
25129+ SiMustWriteLock(sb);
25130+
79b8bda9 25131+ err = 0;
5527c038 25132+ dir = d_inode(sb->s_root);
1facf9fc 25133+ sbinfo = au_sbi(sb);
1facf9fc 25134+ opt_xino = NULL;
25135+ opt = opts->opt;
25136+ while (err >= 0 && opt->type != Opt_tail) {
25137+ err = au_opt_simple(sb, opt, opts);
25138+ if (!err)
25139+ err = au_opt_br(sb, opt, opts);
25140+ if (!err)
25141+ err = au_opt_xino(sb, opt, &opt_xino, opts);
25142+ opt++;
25143+ }
25144+ if (err > 0)
25145+ err = 0;
25146+ AuTraceErr(err);
25147+ /* go on even err */
25148+
79b8bda9 25149+ no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
1facf9fc 25150+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
25151+ if (unlikely(rerr && !err))
25152+ err = rerr;
25153+
79b8bda9 25154+ if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
b95c5147 25155+ au_fset_opts(opts->flags, REFRESH_IDOP);
79b8bda9 25156+
1facf9fc 25157+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
25158+ rerr = au_xib_trunc(sb);
25159+ if (unlikely(rerr && !err))
25160+ err = rerr;
25161+ }
25162+
25163+ /* will be handled by the caller */
027c5e7a 25164+ if (!au_ftest_opts(opts->flags, REFRESH)
79b8bda9
AM
25165+ && (opts->given_udba
25166+ || au_opt_test(sbinfo->si_mntflags, XINO)
b95c5147 25167+ || au_ftest_opts(opts->flags, REFRESH_IDOP)
79b8bda9 25168+ ))
027c5e7a 25169+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 25170+
25171+ AuDbg("status 0x%x\n", opts->flags);
25172+ return err;
25173+}
25174+
25175+/* ---------------------------------------------------------------------- */
25176+
25177+unsigned int au_opt_udba(struct super_block *sb)
25178+{
25179+ return au_mntflags(sb) & AuOptMask_UDBA;
25180+}
7f207e10
AM
25181diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
25182--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
3c1bdaff
AM
25183+++ linux/fs/aufs/opts.h 2017-09-05 10:42:11.058755349 +0200
25184@@ -0,0 +1,213 @@
1facf9fc 25185+/*
a2654f78 25186+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 25187+ *
25188+ * This program, aufs is free software; you can redistribute it and/or modify
25189+ * it under the terms of the GNU General Public License as published by
25190+ * the Free Software Foundation; either version 2 of the License, or
25191+ * (at your option) any later version.
dece6358
AM
25192+ *
25193+ * This program is distributed in the hope that it will be useful,
25194+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25195+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25196+ * GNU General Public License for more details.
25197+ *
25198+ * You should have received a copy of the GNU General Public License
523b37e3 25199+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25200+ */
25201+
25202+/*
25203+ * mount options/flags
25204+ */
25205+
25206+#ifndef __AUFS_OPTS_H__
25207+#define __AUFS_OPTS_H__
25208+
25209+#ifdef __KERNEL__
25210+
dece6358 25211+#include <linux/path.h>
1facf9fc 25212+
dece6358 25213+struct file;
dece6358 25214+
1facf9fc 25215+/* ---------------------------------------------------------------------- */
25216+
25217+/* mount flags */
25218+#define AuOpt_XINO 1 /* external inode number bitmap
25219+ and translation table */
25220+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
25221+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
25222+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 25223+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
25224+#define AuOpt_SHWH (1 << 5) /* show whiteout */
25225+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
076b876e
AM
25226+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
25227+ bits */
dece6358
AM
25228+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
25229+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
25230+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
25231+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
25232+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 25233+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 25234+
4a4d8108
AM
25235+#ifndef CONFIG_AUFS_HNOTIFY
25236+#undef AuOpt_UDBA_HNOTIFY
25237+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 25238+#endif
dece6358
AM
25239+#ifndef CONFIG_AUFS_SHWH
25240+#undef AuOpt_SHWH
25241+#define AuOpt_SHWH 0
25242+#endif
1facf9fc 25243+
25244+#define AuOpt_Def (AuOpt_XINO \
25245+ | AuOpt_UDBA_REVAL \
25246+ | AuOpt_PLINK \
25247+ /* | AuOpt_DIRPERM1 */ \
25248+ | AuOpt_WARN_PERM)
25249+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
25250+ | AuOpt_UDBA_REVAL \
4a4d8108 25251+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 25252+
25253+#define au_opt_test(flags, name) (flags & AuOpt_##name)
25254+#define au_opt_set(flags, name) do { \
25255+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
25256+ ((flags) |= AuOpt_##name); \
25257+} while (0)
25258+#define au_opt_set_udba(flags, name) do { \
25259+ (flags) &= ~AuOptMask_UDBA; \
25260+ ((flags) |= AuOpt_##name); \
25261+} while (0)
7f207e10
AM
25262+#define au_opt_clr(flags, name) do { \
25263+ ((flags) &= ~AuOpt_##name); \
25264+} while (0)
1facf9fc 25265+
e49829fe
JR
25266+static inline unsigned int au_opts_plink(unsigned int mntflags)
25267+{
25268+#ifdef CONFIG_PROC_FS
25269+ return mntflags;
25270+#else
25271+ return mntflags & ~AuOpt_PLINK;
25272+#endif
25273+}
25274+
1facf9fc 25275+/* ---------------------------------------------------------------------- */
25276+
25277+/* policies to select one among multiple writable branches */
25278+enum {
25279+ AuWbrCreate_TDP, /* top down parent */
25280+ AuWbrCreate_RR, /* round robin */
25281+ AuWbrCreate_MFS, /* most free space */
25282+ AuWbrCreate_MFSV, /* mfs with seconds */
25283+ AuWbrCreate_MFSRR, /* mfs then rr */
25284+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
f2c43d5f
AM
25285+ AuWbrCreate_TDMFS, /* top down regardless parent and mfs */
25286+ AuWbrCreate_TDMFSV, /* top down regardless parent and mfs */
1facf9fc 25287+ AuWbrCreate_PMFS, /* parent and mfs */
25288+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
25289+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
25290+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 25291+
25292+ AuWbrCreate_Def = AuWbrCreate_TDP
25293+};
25294+
25295+enum {
25296+ AuWbrCopyup_TDP, /* top down parent */
25297+ AuWbrCopyup_BUP, /* bottom up parent */
25298+ AuWbrCopyup_BU, /* bottom up */
25299+
25300+ AuWbrCopyup_Def = AuWbrCopyup_TDP
25301+};
25302+
25303+/* ---------------------------------------------------------------------- */
25304+
25305+struct au_opt_add {
25306+ aufs_bindex_t bindex;
25307+ char *pathname;
25308+ int perm;
25309+ struct path path;
25310+};
25311+
25312+struct au_opt_del {
25313+ char *pathname;
25314+ struct path h_path;
25315+};
25316+
25317+struct au_opt_mod {
25318+ char *path;
25319+ int perm;
25320+ struct dentry *h_root;
25321+};
25322+
25323+struct au_opt_xino {
25324+ char *path;
25325+ struct file *file;
25326+};
25327+
25328+struct au_opt_xino_itrunc {
25329+ aufs_bindex_t bindex;
25330+};
25331+
25332+struct au_opt_wbr_create {
25333+ int wbr_create;
25334+ int mfs_second;
25335+ unsigned long long mfsrr_watermark;
25336+};
25337+
25338+struct au_opt {
25339+ int type;
25340+ union {
25341+ struct au_opt_xino xino;
25342+ struct au_opt_xino_itrunc xino_itrunc;
25343+ struct au_opt_add add;
25344+ struct au_opt_del del;
25345+ struct au_opt_mod mod;
25346+ int dirwh;
25347+ int rdcache;
25348+ unsigned int rdblk;
25349+ unsigned int rdhash;
25350+ int udba;
25351+ struct au_opt_wbr_create wbr_create;
25352+ int wbr_copyup;
076b876e 25353+ unsigned int fhsm_second;
1facf9fc 25354+ };
25355+};
25356+
25357+/* opts flags */
25358+#define AuOpts_REMOUNT 1
027c5e7a
AM
25359+#define AuOpts_REFRESH (1 << 1)
25360+#define AuOpts_TRUNC_XIB (1 << 2)
25361+#define AuOpts_REFRESH_DYAOP (1 << 3)
b95c5147 25362+#define AuOpts_REFRESH_IDOP (1 << 4)
1facf9fc 25363+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
25364+#define au_fset_opts(flags, name) \
25365+ do { (flags) |= AuOpts_##name; } while (0)
25366+#define au_fclr_opts(flags, name) \
25367+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 25368+
25369+struct au_opts {
25370+ struct au_opt *opt;
25371+ int max_opt;
25372+
25373+ unsigned int given_udba;
25374+ unsigned int flags;
25375+ unsigned long sb_flags;
25376+};
25377+
25378+/* ---------------------------------------------------------------------- */
25379+
7e9cd9fe 25380+/* opts.c */
076b876e 25381+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
1facf9fc 25382+const char *au_optstr_udba(int udba);
25383+const char *au_optstr_wbr_copyup(int wbr_copyup);
25384+const char *au_optstr_wbr_create(int wbr_create);
25385+
25386+void au_opts_free(struct au_opts *opts);
3c1bdaff 25387+struct super_block;
1facf9fc 25388+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
25389+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
25390+ unsigned int pending);
25391+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
25392+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
25393+
25394+unsigned int au_opt_udba(struct super_block *sb);
25395+
1facf9fc 25396+#endif /* __KERNEL__ */
25397+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
25398diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
25399--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
3c1bdaff 25400+++ linux/fs/aufs/plink.c 2017-09-05 10:42:11.058755349 +0200
f0c0a007 25401@@ -0,0 +1,514 @@
1facf9fc 25402+/*
a2654f78 25403+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 25404+ *
25405+ * This program, aufs is free software; you can redistribute it and/or modify
25406+ * it under the terms of the GNU General Public License as published by
25407+ * the Free Software Foundation; either version 2 of the License, or
25408+ * (at your option) any later version.
dece6358
AM
25409+ *
25410+ * This program is distributed in the hope that it will be useful,
25411+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25412+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25413+ * GNU General Public License for more details.
25414+ *
25415+ * You should have received a copy of the GNU General Public License
523b37e3 25416+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25417+ */
25418+
25419+/*
25420+ * pseudo-link
25421+ */
25422+
25423+#include "aufs.h"
25424+
25425+/*
e49829fe 25426+ * the pseudo-link maintenance mode.
1facf9fc 25427+ * during a user process maintains the pseudo-links,
25428+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
25429+ *
25430+ * Flags
25431+ * NOPLM:
25432+ * For entry functions which will handle plink, and i_mutex is already held
25433+ * in VFS.
25434+ * They cannot wait and should return an error at once.
25435+ * Callers has to check the error.
25436+ * NOPLMW:
25437+ * For entry functions which will handle plink, but i_mutex is not held
25438+ * in VFS.
25439+ * They can wait the plink maintenance mode to finish.
25440+ *
25441+ * They behave like F_SETLK and F_SETLKW.
25442+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 25443+ */
e49829fe
JR
25444+
25445+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 25446+{
e49829fe
JR
25447+ int err;
25448+ pid_t pid, ppid;
f0c0a007 25449+ struct task_struct *parent, *prev;
e49829fe 25450+ struct au_sbinfo *sbi;
dece6358
AM
25451+
25452+ SiMustAnyLock(sb);
25453+
e49829fe
JR
25454+ err = 0;
25455+ if (!au_opt_test(au_mntflags(sb), PLINK))
25456+ goto out;
25457+
25458+ sbi = au_sbi(sb);
25459+ pid = sbi->si_plink_maint_pid;
25460+ if (!pid || pid == current->pid)
25461+ goto out;
25462+
25463+ /* todo: it highly depends upon /sbin/mount.aufs */
f0c0a007
AM
25464+ prev = NULL;
25465+ parent = current;
25466+ ppid = 0;
e49829fe 25467+ rcu_read_lock();
f0c0a007
AM
25468+ while (1) {
25469+ parent = rcu_dereference(parent->real_parent);
25470+ if (parent == prev)
25471+ break;
25472+ ppid = task_pid_vnr(parent);
25473+ if (pid == ppid) {
25474+ rcu_read_unlock();
25475+ goto out;
25476+ }
25477+ prev = parent;
25478+ }
e49829fe 25479+ rcu_read_unlock();
e49829fe
JR
25480+
25481+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
25482+ /* if there is no i_mutex lock in VFS, we don't need to wait */
25483+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
25484+ while (sbi->si_plink_maint_pid) {
25485+ si_read_unlock(sb);
25486+ /* gave up wake_up_bit() */
25487+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
25488+
25489+ if (au_ftest_lock(flags, FLUSH))
25490+ au_nwt_flush(&sbi->si_nowait);
25491+ si_noflush_read_lock(sb);
25492+ }
25493+ } else if (au_ftest_lock(flags, NOPLM)) {
25494+ AuDbg("ppid %d, pid %d\n", ppid, pid);
25495+ err = -EAGAIN;
25496+ }
25497+
25498+out:
25499+ return err;
4a4d8108
AM
25500+}
25501+
e49829fe 25502+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 25503+{
4a4d8108 25504+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 25505+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 25506+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 25507+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
25508+}
25509+
e49829fe 25510+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
25511+{
25512+ int err;
4a4d8108
AM
25513+ struct au_sbinfo *sbinfo;
25514+
25515+ err = 0;
4a4d8108
AM
25516+ sbinfo = au_sbi(sb);
25517+ /* make sure i am the only one in this fs */
e49829fe
JR
25518+ si_write_lock(sb, AuLock_FLUSH);
25519+ if (au_opt_test(au_mntflags(sb), PLINK)) {
25520+ spin_lock(&sbinfo->si_plink_maint_lock);
25521+ if (!sbinfo->si_plink_maint_pid)
25522+ sbinfo->si_plink_maint_pid = current->pid;
25523+ else
25524+ err = -EBUSY;
25525+ spin_unlock(&sbinfo->si_plink_maint_lock);
25526+ }
4a4d8108
AM
25527+ si_write_unlock(sb);
25528+
25529+ return err;
1facf9fc 25530+}
25531+
25532+/* ---------------------------------------------------------------------- */
25533+
1facf9fc 25534+#ifdef CONFIG_AUFS_DEBUG
25535+void au_plink_list(struct super_block *sb)
25536+{
86dc4139 25537+ int i;
1facf9fc 25538+ struct au_sbinfo *sbinfo;
86dc4139 25539+ struct hlist_head *plink_hlist;
5afbbe0d 25540+ struct au_icntnr *icntnr;
1facf9fc 25541+
dece6358
AM
25542+ SiMustAnyLock(sb);
25543+
1facf9fc 25544+ sbinfo = au_sbi(sb);
25545+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 25546+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 25547+
86dc4139
AM
25548+ for (i = 0; i < AuPlink_NHASH; i++) {
25549+ plink_hlist = &sbinfo->si_plink[i].head;
25550+ rcu_read_lock();
5afbbe0d
AM
25551+ hlist_for_each_entry_rcu(icntnr, plink_hlist, plink)
25552+ AuDbg("%lu\n", icntnr->vfs_inode.i_ino);
86dc4139
AM
25553+ rcu_read_unlock();
25554+ }
1facf9fc 25555+}
25556+#endif
25557+
25558+/* is the inode pseudo-linked? */
25559+int au_plink_test(struct inode *inode)
25560+{
86dc4139 25561+ int found, i;
1facf9fc 25562+ struct au_sbinfo *sbinfo;
86dc4139 25563+ struct hlist_head *plink_hlist;
5afbbe0d 25564+ struct au_icntnr *icntnr;
1facf9fc 25565+
25566+ sbinfo = au_sbi(inode->i_sb);
dece6358 25567+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 25568+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 25569+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 25570+
25571+ found = 0;
86dc4139
AM
25572+ i = au_plink_hash(inode->i_ino);
25573+ plink_hlist = &sbinfo->si_plink[i].head;
4a4d8108 25574+ rcu_read_lock();
5afbbe0d
AM
25575+ hlist_for_each_entry_rcu(icntnr, plink_hlist, plink)
25576+ if (&icntnr->vfs_inode == inode) {
1facf9fc 25577+ found = 1;
25578+ break;
25579+ }
4a4d8108 25580+ rcu_read_unlock();
1facf9fc 25581+ return found;
25582+}
25583+
25584+/* ---------------------------------------------------------------------- */
25585+
25586+/*
25587+ * generate a name for plink.
25588+ * the file will be stored under AUFS_WH_PLINKDIR.
25589+ */
25590+/* 20 is max digits length of ulong 64 */
25591+#define PLINK_NAME_LEN ((20 + 1) * 2)
25592+
25593+static int plink_name(char *name, int len, struct inode *inode,
25594+ aufs_bindex_t bindex)
25595+{
25596+ int rlen;
25597+ struct inode *h_inode;
25598+
25599+ h_inode = au_h_iptr(inode, bindex);
25600+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
25601+ return rlen;
25602+}
25603+
7f207e10
AM
25604+struct au_do_plink_lkup_args {
25605+ struct dentry **errp;
25606+ struct qstr *tgtname;
25607+ struct dentry *h_parent;
25608+ struct au_branch *br;
25609+};
25610+
25611+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
25612+ struct dentry *h_parent,
25613+ struct au_branch *br)
25614+{
25615+ struct dentry *h_dentry;
febd17d6 25616+ struct inode *h_inode;
7f207e10 25617+
febd17d6 25618+ h_inode = d_inode(h_parent);
3c1bdaff 25619+ vfsub_inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2);
b4510431 25620+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
3c1bdaff 25621+ inode_unlock_shared(h_inode);
7f207e10
AM
25622+ return h_dentry;
25623+}
25624+
25625+static void au_call_do_plink_lkup(void *args)
25626+{
25627+ struct au_do_plink_lkup_args *a = args;
25628+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
25629+}
25630+
1facf9fc 25631+/* lookup the plink-ed @inode under the branch at @bindex */
25632+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
25633+{
25634+ struct dentry *h_dentry, *h_parent;
25635+ struct au_branch *br;
7f207e10 25636+ int wkq_err;
1facf9fc 25637+ char a[PLINK_NAME_LEN];
0c3ec466 25638+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 25639+
e49829fe
JR
25640+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
25641+
1facf9fc 25642+ br = au_sbr(inode->i_sb, bindex);
25643+ h_parent = br->br_wbr->wbr_plink;
1facf9fc 25644+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
25645+
2dfbb274 25646+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
25647+ struct au_do_plink_lkup_args args = {
25648+ .errp = &h_dentry,
25649+ .tgtname = &tgtname,
25650+ .h_parent = h_parent,
25651+ .br = br
25652+ };
25653+
25654+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
25655+ if (unlikely(wkq_err))
25656+ h_dentry = ERR_PTR(wkq_err);
25657+ } else
25658+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
25659+
1facf9fc 25660+ return h_dentry;
25661+}
25662+
25663+/* create a pseudo-link */
25664+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
25665+ struct dentry *h_dentry, struct au_branch *br)
25666+{
25667+ int err;
25668+ struct path h_path = {
86dc4139 25669+ .mnt = au_br_mnt(br)
1facf9fc 25670+ };
523b37e3 25671+ struct inode *h_dir, *delegated;
1facf9fc 25672+
5527c038 25673+ h_dir = d_inode(h_parent);
febd17d6 25674+ inode_lock_nested(h_dir, AuLsc_I_CHILD2);
4f0767ce 25675+again:
b4510431 25676+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 25677+ err = PTR_ERR(h_path.dentry);
25678+ if (IS_ERR(h_path.dentry))
25679+ goto out;
25680+
25681+ err = 0;
25682+ /* wh.plink dir is not monitored */
7f207e10 25683+ /* todo: is it really safe? */
5527c038
JR
25684+ if (d_is_positive(h_path.dentry)
25685+ && d_inode(h_path.dentry) != d_inode(h_dentry)) {
523b37e3
AM
25686+ delegated = NULL;
25687+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
25688+ if (unlikely(err == -EWOULDBLOCK)) {
25689+ pr_warn("cannot retry for NFSv4 delegation"
25690+ " for an internal unlink\n");
25691+ iput(delegated);
25692+ }
1facf9fc 25693+ dput(h_path.dentry);
25694+ h_path.dentry = NULL;
25695+ if (!err)
25696+ goto again;
25697+ }
5527c038 25698+ if (!err && d_is_negative(h_path.dentry)) {
523b37e3
AM
25699+ delegated = NULL;
25700+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
25701+ if (unlikely(err == -EWOULDBLOCK)) {
25702+ pr_warn("cannot retry for NFSv4 delegation"
25703+ " for an internal link\n");
25704+ iput(delegated);
25705+ }
25706+ }
1facf9fc 25707+ dput(h_path.dentry);
25708+
4f0767ce 25709+out:
febd17d6 25710+ inode_unlock(h_dir);
1facf9fc 25711+ return err;
25712+}
25713+
25714+struct do_whplink_args {
25715+ int *errp;
25716+ struct qstr *tgt;
25717+ struct dentry *h_parent;
25718+ struct dentry *h_dentry;
25719+ struct au_branch *br;
25720+};
25721+
25722+static void call_do_whplink(void *args)
25723+{
25724+ struct do_whplink_args *a = args;
25725+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
25726+}
25727+
25728+static int whplink(struct dentry *h_dentry, struct inode *inode,
25729+ aufs_bindex_t bindex, struct au_branch *br)
25730+{
25731+ int err, wkq_err;
25732+ struct au_wbr *wbr;
25733+ struct dentry *h_parent;
1facf9fc 25734+ char a[PLINK_NAME_LEN];
0c3ec466 25735+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 25736+
25737+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
25738+ h_parent = wbr->wbr_plink;
1facf9fc 25739+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
25740+
25741+ /* always superio. */
2dfbb274 25742+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 25743+ struct do_whplink_args args = {
25744+ .errp = &err,
25745+ .tgt = &tgtname,
25746+ .h_parent = h_parent,
25747+ .h_dentry = h_dentry,
25748+ .br = br
25749+ };
25750+ wkq_err = au_wkq_wait(call_do_whplink, &args);
25751+ if (unlikely(wkq_err))
25752+ err = wkq_err;
25753+ } else
25754+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 25755+
25756+ return err;
25757+}
25758+
1facf9fc 25759+/*
25760+ * create a new pseudo-link for @h_dentry on @bindex.
25761+ * the linked inode is held in aufs @inode.
25762+ */
25763+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
25764+ struct dentry *h_dentry)
25765+{
25766+ struct super_block *sb;
25767+ struct au_sbinfo *sbinfo;
86dc4139 25768+ struct hlist_head *plink_hlist;
5afbbe0d 25769+ struct au_icntnr *icntnr;
86dc4139
AM
25770+ struct au_sphlhead *sphl;
25771+ int found, err, cnt, i;
1facf9fc 25772+
25773+ sb = inode->i_sb;
25774+ sbinfo = au_sbi(sb);
25775+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 25776+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 25777+
86dc4139 25778+ found = au_plink_test(inode);
4a4d8108 25779+ if (found)
1facf9fc 25780+ return;
4a4d8108 25781+
86dc4139
AM
25782+ i = au_plink_hash(inode->i_ino);
25783+ sphl = sbinfo->si_plink + i;
25784+ plink_hlist = &sphl->head;
5afbbe0d 25785+ au_igrab(inode);
1facf9fc 25786+
86dc4139 25787+ spin_lock(&sphl->spin);
5afbbe0d
AM
25788+ hlist_for_each_entry(icntnr, plink_hlist, plink) {
25789+ if (&icntnr->vfs_inode == inode) {
4a4d8108
AM
25790+ found = 1;
25791+ break;
25792+ }
1facf9fc 25793+ }
5afbbe0d
AM
25794+ if (!found) {
25795+ icntnr = container_of(inode, struct au_icntnr, vfs_inode);
25796+ hlist_add_head_rcu(&icntnr->plink, plink_hlist);
25797+ }
86dc4139 25798+ spin_unlock(&sphl->spin);
4a4d8108 25799+ if (!found) {
86dc4139
AM
25800+ cnt = au_sphl_count(sphl);
25801+#define msg "unexpectedly unblanced or too many pseudo-links"
25802+ if (cnt > AUFS_PLINK_WARN)
25803+ AuWarn1(msg ", %d\n", cnt);
25804+#undef msg
1facf9fc 25805+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
5afbbe0d
AM
25806+ if (unlikely(err)) {
25807+ pr_warn("err %d, damaged pseudo link.\n", err);
25808+ au_sphl_del_rcu(&icntnr->plink, sphl);
25809+ iput(&icntnr->vfs_inode);
4a4d8108 25810+ }
5afbbe0d
AM
25811+ } else
25812+ iput(&icntnr->vfs_inode);
1facf9fc 25813+}
25814+
25815+/* free all plinks */
e49829fe 25816+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 25817+{
86dc4139 25818+ int i, warned;
1facf9fc 25819+ struct au_sbinfo *sbinfo;
86dc4139
AM
25820+ struct hlist_head *plink_hlist;
25821+ struct hlist_node *tmp;
5afbbe0d 25822+ struct au_icntnr *icntnr;
1facf9fc 25823+
dece6358
AM
25824+ SiMustWriteLock(sb);
25825+
1facf9fc 25826+ sbinfo = au_sbi(sb);
25827+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 25828+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 25829+
1facf9fc 25830+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
25831+ warned = 0;
25832+ for (i = 0; i < AuPlink_NHASH; i++) {
25833+ plink_hlist = &sbinfo->si_plink[i].head;
25834+ if (!warned && verbose && !hlist_empty(plink_hlist)) {
25835+ pr_warn("pseudo-link is not flushed");
25836+ warned = 1;
25837+ }
5afbbe0d
AM
25838+ hlist_for_each_entry_safe(icntnr, tmp, plink_hlist, plink)
25839+ iput(&icntnr->vfs_inode);
86dc4139
AM
25840+ INIT_HLIST_HEAD(plink_hlist);
25841+ }
1facf9fc 25842+}
25843+
e49829fe
JR
25844+void au_plink_clean(struct super_block *sb, int verbose)
25845+{
25846+ struct dentry *root;
25847+
25848+ root = sb->s_root;
25849+ aufs_write_lock(root);
25850+ if (au_opt_test(au_mntflags(sb), PLINK))
25851+ au_plink_put(sb, verbose);
25852+ aufs_write_unlock(root);
25853+}
25854+
86dc4139
AM
25855+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
25856+{
25857+ int do_put;
5afbbe0d 25858+ aufs_bindex_t btop, bbot, bindex;
86dc4139
AM
25859+
25860+ do_put = 0;
5afbbe0d
AM
25861+ btop = au_ibtop(inode);
25862+ bbot = au_ibbot(inode);
25863+ if (btop >= 0) {
25864+ for (bindex = btop; bindex <= bbot; bindex++) {
86dc4139
AM
25865+ if (!au_h_iptr(inode, bindex)
25866+ || au_ii_br_id(inode, bindex) != br_id)
25867+ continue;
25868+ au_set_h_iptr(inode, bindex, NULL, 0);
25869+ do_put = 1;
25870+ break;
25871+ }
25872+ if (do_put)
5afbbe0d 25873+ for (bindex = btop; bindex <= bbot; bindex++)
86dc4139
AM
25874+ if (au_h_iptr(inode, bindex)) {
25875+ do_put = 0;
25876+ break;
25877+ }
25878+ } else
25879+ do_put = 1;
25880+
25881+ return do_put;
25882+}
25883+
1facf9fc 25884+/* free the plinks on a branch specified by @br_id */
25885+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
25886+{
25887+ struct au_sbinfo *sbinfo;
86dc4139
AM
25888+ struct hlist_head *plink_hlist;
25889+ struct hlist_node *tmp;
5afbbe0d 25890+ struct au_icntnr *icntnr;
1facf9fc 25891+ struct inode *inode;
86dc4139 25892+ int i, do_put;
1facf9fc 25893+
dece6358
AM
25894+ SiMustWriteLock(sb);
25895+
1facf9fc 25896+ sbinfo = au_sbi(sb);
25897+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 25898+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 25899+
1facf9fc 25900+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
25901+ for (i = 0; i < AuPlink_NHASH; i++) {
25902+ plink_hlist = &sbinfo->si_plink[i].head;
5afbbe0d
AM
25903+ hlist_for_each_entry_safe(icntnr, tmp, plink_hlist, plink) {
25904+ inode = au_igrab(&icntnr->vfs_inode);
86dc4139
AM
25905+ ii_write_lock_child(inode);
25906+ do_put = au_plink_do_half_refresh(inode, br_id);
5afbbe0d
AM
25907+ if (do_put) {
25908+ hlist_del(&icntnr->plink);
25909+ iput(inode);
25910+ }
86dc4139
AM
25911+ ii_write_unlock(inode);
25912+ iput(inode);
dece6358 25913+ }
dece6358
AM
25914+ }
25915+}
7f207e10
AM
25916diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
25917--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 25918+++ linux/fs/aufs/poll.c 2017-07-29 12:14:25.906375514 +0200
b912730e 25919@@ -0,0 +1,52 @@
dece6358 25920+/*
a2654f78 25921+ * Copyright (C) 2005-2017 Junjiro R. Okajima
dece6358
AM
25922+ *
25923+ * This program, aufs is free software; you can redistribute it and/or modify
25924+ * it under the terms of the GNU General Public License as published by
25925+ * the Free Software Foundation; either version 2 of the License, or
25926+ * (at your option) any later version.
25927+ *
25928+ * This program is distributed in the hope that it will be useful,
25929+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25930+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25931+ * GNU General Public License for more details.
25932+ *
25933+ * You should have received a copy of the GNU General Public License
523b37e3 25934+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
25935+ */
25936+
1308ab2a 25937+/*
25938+ * poll operation
25939+ * There is only one filesystem which implements ->poll operation, currently.
25940+ */
25941+
25942+#include "aufs.h"
25943+
25944+unsigned int aufs_poll(struct file *file, poll_table *wait)
25945+{
25946+ unsigned int mask;
25947+ int err;
25948+ struct file *h_file;
1308ab2a 25949+ struct super_block *sb;
25950+
25951+ /* We should pretend an error happened. */
25952+ mask = POLLERR /* | POLLIN | POLLOUT */;
b912730e 25953+ sb = file->f_path.dentry->d_sb;
e49829fe 25954+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e 25955+
521ced18 25956+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0);
b912730e
AM
25957+ err = PTR_ERR(h_file);
25958+ if (IS_ERR(h_file))
1308ab2a 25959+ goto out;
25960+
25961+ /* it is not an error if h_file has no operation */
25962+ mask = DEFAULT_POLLMASK;
523b37e3 25963+ if (h_file->f_op->poll)
1308ab2a 25964+ mask = h_file->f_op->poll(h_file, wait);
b912730e 25965+ fput(h_file); /* instead of au_read_post() */
1308ab2a 25966+
4f0767ce 25967+out:
1308ab2a 25968+ si_read_unlock(sb);
25969+ AuTraceErr((int)mask);
25970+ return mask;
25971+}
c1595e42
JR
25972diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
25973--- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 25974+++ linux/fs/aufs/posix_acl.c 2017-07-29 12:14:25.906375514 +0200
a2654f78 25975@@ -0,0 +1,102 @@
c1595e42 25976+/*
a2654f78 25977+ * Copyright (C) 2014-2017 Junjiro R. Okajima
c1595e42
JR
25978+ *
25979+ * This program, aufs is free software; you can redistribute it and/or modify
25980+ * it under the terms of the GNU General Public License as published by
25981+ * the Free Software Foundation; either version 2 of the License, or
25982+ * (at your option) any later version.
25983+ *
25984+ * This program is distributed in the hope that it will be useful,
25985+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25986+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25987+ * GNU General Public License for more details.
25988+ *
25989+ * You should have received a copy of the GNU General Public License
25990+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
25991+ */
25992+
25993+/*
25994+ * posix acl operations
25995+ */
25996+
25997+#include <linux/fs.h>
c1595e42
JR
25998+#include "aufs.h"
25999+
26000+struct posix_acl *aufs_get_acl(struct inode *inode, int type)
26001+{
26002+ struct posix_acl *acl;
26003+ int err;
26004+ aufs_bindex_t bindex;
26005+ struct inode *h_inode;
26006+ struct super_block *sb;
26007+
26008+ acl = NULL;
26009+ sb = inode->i_sb;
26010+ si_read_lock(sb, AuLock_FLUSH);
26011+ ii_read_lock_child(inode);
26012+ if (!(sb->s_flags & MS_POSIXACL))
26013+ goto out;
26014+
5afbbe0d 26015+ bindex = au_ibtop(inode);
c1595e42
JR
26016+ h_inode = au_h_iptr(inode, bindex);
26017+ if (unlikely(!h_inode
26018+ || ((h_inode->i_mode & S_IFMT)
26019+ != (inode->i_mode & S_IFMT)))) {
26020+ err = au_busy_or_stale();
26021+ acl = ERR_PTR(err);
26022+ goto out;
26023+ }
26024+
26025+ /* always topmost only */
26026+ acl = get_acl(h_inode, type);
a2654f78
AM
26027+ if (!IS_ERR_OR_NULL(acl))
26028+ set_cached_acl(inode, type, acl);
c1595e42
JR
26029+
26030+out:
26031+ ii_read_unlock(inode);
26032+ si_read_unlock(sb);
26033+
26034+ AuTraceErrPtr(acl);
26035+ return acl;
26036+}
26037+
26038+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
26039+{
26040+ int err;
26041+ ssize_t ssz;
26042+ struct dentry *dentry;
f2c43d5f 26043+ struct au_sxattr arg = {
c1595e42
JR
26044+ .type = AU_ACL_SET,
26045+ .u.acl_set = {
26046+ .acl = acl,
26047+ .type = type
26048+ },
26049+ };
26050+
5afbbe0d
AM
26051+ IMustLock(inode);
26052+
c1595e42
JR
26053+ if (inode->i_ino == AUFS_ROOT_INO)
26054+ dentry = dget(inode->i_sb->s_root);
26055+ else {
26056+ dentry = d_find_alias(inode);
26057+ if (!dentry)
26058+ dentry = d_find_any_alias(inode);
26059+ if (!dentry) {
26060+ pr_warn("cannot handle this inode, "
26061+ "please report to aufs-users ML\n");
26062+ err = -ENOENT;
26063+ goto out;
26064+ }
26065+ }
26066+
f2c43d5f 26067+ ssz = au_sxattr(dentry, inode, &arg);
c1595e42
JR
26068+ dput(dentry);
26069+ err = ssz;
a2654f78 26070+ if (ssz >= 0) {
c1595e42 26071+ err = 0;
a2654f78
AM
26072+ set_cached_acl(inode, type, acl);
26073+ }
c1595e42
JR
26074+
26075+out:
c1595e42
JR
26076+ return err;
26077+}
7f207e10
AM
26078diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
26079--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 26080+++ linux/fs/aufs/procfs.c 2017-07-29 12:14:25.906375514 +0200
523b37e3 26081@@ -0,0 +1,169 @@
e49829fe 26082+/*
a2654f78 26083+ * Copyright (C) 2010-2017 Junjiro R. Okajima
e49829fe
JR
26084+ *
26085+ * This program, aufs is free software; you can redistribute it and/or modify
26086+ * it under the terms of the GNU General Public License as published by
26087+ * the Free Software Foundation; either version 2 of the License, or
26088+ * (at your option) any later version.
26089+ *
26090+ * This program is distributed in the hope that it will be useful,
26091+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26092+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26093+ * GNU General Public License for more details.
26094+ *
26095+ * You should have received a copy of the GNU General Public License
523b37e3 26096+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
26097+ */
26098+
26099+/*
26100+ * procfs interfaces
26101+ */
26102+
26103+#include <linux/proc_fs.h>
26104+#include "aufs.h"
26105+
26106+static int au_procfs_plm_release(struct inode *inode, struct file *file)
26107+{
26108+ struct au_sbinfo *sbinfo;
26109+
26110+ sbinfo = file->private_data;
26111+ if (sbinfo) {
26112+ au_plink_maint_leave(sbinfo);
26113+ kobject_put(&sbinfo->si_kobj);
26114+ }
26115+
26116+ return 0;
26117+}
26118+
26119+static void au_procfs_plm_write_clean(struct file *file)
26120+{
26121+ struct au_sbinfo *sbinfo;
26122+
26123+ sbinfo = file->private_data;
26124+ if (sbinfo)
26125+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
26126+}
26127+
26128+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
26129+{
26130+ int err;
26131+ struct super_block *sb;
26132+ struct au_sbinfo *sbinfo;
26133+
26134+ err = -EBUSY;
26135+ if (unlikely(file->private_data))
26136+ goto out;
26137+
26138+ sb = NULL;
53392da6 26139+ /* don't use au_sbilist_lock() here */
e49829fe 26140+ spin_lock(&au_sbilist.spin);
5afbbe0d 26141+ hlist_for_each_entry(sbinfo, &au_sbilist.head, si_list)
e49829fe
JR
26142+ if (id == sysaufs_si_id(sbinfo)) {
26143+ kobject_get(&sbinfo->si_kobj);
26144+ sb = sbinfo->si_sb;
26145+ break;
26146+ }
26147+ spin_unlock(&au_sbilist.spin);
26148+
26149+ err = -EINVAL;
26150+ if (unlikely(!sb))
26151+ goto out;
26152+
26153+ err = au_plink_maint_enter(sb);
26154+ if (!err)
26155+ /* keep kobject_get() */
26156+ file->private_data = sbinfo;
26157+ else
26158+ kobject_put(&sbinfo->si_kobj);
26159+out:
26160+ return err;
26161+}
26162+
26163+/*
26164+ * Accept a valid "si=xxxx" only.
26165+ * Once it is accepted successfully, accept "clean" too.
26166+ */
26167+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
26168+ size_t count, loff_t *ppos)
26169+{
26170+ ssize_t err;
26171+ unsigned long id;
26172+ /* last newline is allowed */
26173+ char buf[3 + sizeof(unsigned long) * 2 + 1];
26174+
26175+ err = -EACCES;
26176+ if (unlikely(!capable(CAP_SYS_ADMIN)))
26177+ goto out;
26178+
26179+ err = -EINVAL;
26180+ if (unlikely(count > sizeof(buf)))
26181+ goto out;
26182+
26183+ err = copy_from_user(buf, ubuf, count);
26184+ if (unlikely(err)) {
26185+ err = -EFAULT;
26186+ goto out;
26187+ }
26188+ buf[count] = 0;
26189+
26190+ err = -EINVAL;
26191+ if (!strcmp("clean", buf)) {
26192+ au_procfs_plm_write_clean(file);
26193+ goto out_success;
26194+ } else if (unlikely(strncmp("si=", buf, 3)))
26195+ goto out;
26196+
9dbd164d 26197+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
26198+ if (unlikely(err))
26199+ goto out;
26200+
26201+ err = au_procfs_plm_write_si(file, id);
26202+ if (unlikely(err))
26203+ goto out;
26204+
26205+out_success:
26206+ err = count; /* success */
26207+out:
26208+ return err;
26209+}
26210+
26211+static const struct file_operations au_procfs_plm_fop = {
26212+ .write = au_procfs_plm_write,
26213+ .release = au_procfs_plm_release,
26214+ .owner = THIS_MODULE
26215+};
26216+
26217+/* ---------------------------------------------------------------------- */
26218+
26219+static struct proc_dir_entry *au_procfs_dir;
26220+
26221+void au_procfs_fin(void)
26222+{
26223+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
26224+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
26225+}
26226+
26227+int __init au_procfs_init(void)
26228+{
26229+ int err;
26230+ struct proc_dir_entry *entry;
26231+
26232+ err = -ENOMEM;
26233+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
26234+ if (unlikely(!au_procfs_dir))
26235+ goto out;
26236+
26237+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
26238+ au_procfs_dir, &au_procfs_plm_fop);
26239+ if (unlikely(!entry))
26240+ goto out_dir;
26241+
26242+ err = 0;
26243+ goto out; /* success */
26244+
26245+
26246+out_dir:
26247+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
26248+out:
26249+ return err;
26250+}
7f207e10
AM
26251diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
26252--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 26253+++ linux/fs/aufs/rdu.c 2017-07-29 12:14:25.906375514 +0200
5afbbe0d 26254@@ -0,0 +1,381 @@
1308ab2a 26255+/*
a2654f78 26256+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1308ab2a 26257+ *
26258+ * This program, aufs is free software; you can redistribute it and/or modify
26259+ * it under the terms of the GNU General Public License as published by
26260+ * the Free Software Foundation; either version 2 of the License, or
26261+ * (at your option) any later version.
26262+ *
26263+ * This program is distributed in the hope that it will be useful,
26264+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26265+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26266+ * GNU General Public License for more details.
26267+ *
26268+ * You should have received a copy of the GNU General Public License
523b37e3 26269+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 26270+ */
26271+
26272+/*
26273+ * readdir in userspace.
26274+ */
26275+
b752ccd1 26276+#include <linux/compat.h>
4a4d8108 26277+#include <linux/fs_stack.h>
1308ab2a 26278+#include <linux/security.h>
1308ab2a 26279+#include "aufs.h"
26280+
26281+/* bits for struct aufs_rdu.flags */
26282+#define AuRdu_CALLED 1
26283+#define AuRdu_CONT (1 << 1)
26284+#define AuRdu_FULL (1 << 2)
26285+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
26286+#define au_fset_rdu(flags, name) \
26287+ do { (flags) |= AuRdu_##name; } while (0)
26288+#define au_fclr_rdu(flags, name) \
26289+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 26290+
26291+struct au_rdu_arg {
392086de 26292+ struct dir_context ctx;
1308ab2a 26293+ struct aufs_rdu *rdu;
26294+ union au_rdu_ent_ul ent;
26295+ unsigned long end;
26296+
26297+ struct super_block *sb;
26298+ int err;
26299+};
26300+
392086de 26301+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 26302+ loff_t offset, u64 h_ino, unsigned int d_type)
26303+{
26304+ int err, len;
392086de 26305+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 26306+ struct aufs_rdu *rdu = arg->rdu;
26307+ struct au_rdu_ent ent;
26308+
26309+ err = 0;
26310+ arg->err = 0;
26311+ au_fset_rdu(rdu->cookie.flags, CALLED);
26312+ len = au_rdu_len(nlen);
26313+ if (arg->ent.ul + len < arg->end) {
26314+ ent.ino = h_ino;
26315+ ent.bindex = rdu->cookie.bindex;
26316+ ent.type = d_type;
26317+ ent.nlen = nlen;
4a4d8108
AM
26318+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
26319+ ent.type = DT_UNKNOWN;
1308ab2a 26320+
9dbd164d 26321+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 26322+ err = -EFAULT;
26323+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
26324+ goto out;
26325+ if (copy_to_user(arg->ent.e->name, name, nlen))
26326+ goto out;
26327+ /* the terminating NULL */
26328+ if (__put_user(0, arg->ent.e->name + nlen))
26329+ goto out;
26330+ err = 0;
26331+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
26332+ arg->ent.ul += len;
26333+ rdu->rent++;
26334+ } else {
26335+ err = -EFAULT;
26336+ au_fset_rdu(rdu->cookie.flags, FULL);
26337+ rdu->full = 1;
26338+ rdu->tail = arg->ent;
26339+ }
26340+
4f0767ce 26341+out:
1308ab2a 26342+ /* AuTraceErr(err); */
26343+ return err;
26344+}
26345+
26346+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
26347+{
26348+ int err;
26349+ loff_t offset;
26350+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
26351+
92d182d2 26352+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 26353+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
26354+ err = offset;
26355+ if (unlikely(offset != cookie->h_pos))
26356+ goto out;
26357+
26358+ err = 0;
26359+ do {
26360+ arg->err = 0;
26361+ au_fclr_rdu(cookie->flags, CALLED);
26362+ /* smp_mb(); */
392086de 26363+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 26364+ if (err >= 0)
26365+ err = arg->err;
26366+ } while (!err
26367+ && au_ftest_rdu(cookie->flags, CALLED)
26368+ && !au_ftest_rdu(cookie->flags, FULL));
26369+ cookie->h_pos = h_file->f_pos;
26370+
4f0767ce 26371+out:
1308ab2a 26372+ AuTraceErr(err);
26373+ return err;
26374+}
26375+
26376+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
26377+{
26378+ int err;
5afbbe0d 26379+ aufs_bindex_t bbot;
392086de
AM
26380+ struct au_rdu_arg arg = {
26381+ .ctx = {
2000de60 26382+ .actor = au_rdu_fill
392086de
AM
26383+ }
26384+ };
1308ab2a 26385+ struct dentry *dentry;
26386+ struct inode *inode;
26387+ struct file *h_file;
26388+ struct au_rdu_cookie *cookie = &rdu->cookie;
26389+
26390+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
26391+ if (unlikely(err)) {
26392+ err = -EFAULT;
26393+ AuTraceErr(err);
26394+ goto out;
26395+ }
26396+ rdu->rent = 0;
26397+ rdu->tail = rdu->ent;
26398+ rdu->full = 0;
26399+ arg.rdu = rdu;
26400+ arg.ent = rdu->ent;
26401+ arg.end = arg.ent.ul;
26402+ arg.end += rdu->sz;
26403+
26404+ err = -ENOTDIR;
5afbbe0d 26405+ if (unlikely(!file->f_op->iterate && !file->f_op->iterate_shared))
1308ab2a 26406+ goto out;
26407+
26408+ err = security_file_permission(file, MAY_READ);
26409+ AuTraceErr(err);
26410+ if (unlikely(err))
26411+ goto out;
26412+
2000de60 26413+ dentry = file->f_path.dentry;
5527c038 26414+ inode = d_inode(dentry);
5afbbe0d 26415+ inode_lock_shared(inode);
1308ab2a 26416+
26417+ arg.sb = inode->i_sb;
e49829fe
JR
26418+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
26419+ if (unlikely(err))
26420+ goto out_mtx;
027c5e7a
AM
26421+ err = au_alive_dir(dentry);
26422+ if (unlikely(err))
26423+ goto out_si;
e49829fe 26424+ /* todo: reval? */
1308ab2a 26425+ fi_read_lock(file);
26426+
26427+ err = -EAGAIN;
26428+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
26429+ && cookie->generation != au_figen(file)))
26430+ goto out_unlock;
26431+
26432+ err = 0;
26433+ if (!rdu->blk) {
26434+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
26435+ if (!rdu->blk)
26436+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
26437+ }
5afbbe0d
AM
26438+ bbot = au_fbtop(file);
26439+ if (cookie->bindex < bbot)
26440+ cookie->bindex = bbot;
26441+ bbot = au_fbbot_dir(file);
26442+ /* AuDbg("b%d, b%d\n", cookie->bindex, bbot); */
26443+ for (; !err && cookie->bindex <= bbot;
1308ab2a 26444+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 26445+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 26446+ if (!h_file)
26447+ continue;
26448+
26449+ au_fclr_rdu(cookie->flags, FULL);
26450+ err = au_rdu_do(h_file, &arg);
26451+ AuTraceErr(err);
26452+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
26453+ break;
26454+ }
26455+ AuDbg("rent %llu\n", rdu->rent);
26456+
26457+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
26458+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
26459+ au_fset_rdu(cookie->flags, CONT);
26460+ cookie->generation = au_figen(file);
26461+ }
26462+
26463+ ii_read_lock_child(inode);
5afbbe0d 26464+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibtop(inode)));
1308ab2a 26465+ ii_read_unlock(inode);
26466+
4f0767ce 26467+out_unlock:
1308ab2a 26468+ fi_read_unlock(file);
027c5e7a 26469+out_si:
1308ab2a 26470+ si_read_unlock(arg.sb);
4f0767ce 26471+out_mtx:
5afbbe0d 26472+ inode_unlock_shared(inode);
4f0767ce 26473+out:
1308ab2a 26474+ AuTraceErr(err);
26475+ return err;
26476+}
26477+
26478+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
26479+{
26480+ int err;
26481+ ino_t ino;
26482+ unsigned long long nent;
26483+ union au_rdu_ent_ul *u;
26484+ struct au_rdu_ent ent;
26485+ struct super_block *sb;
26486+
26487+ err = 0;
26488+ nent = rdu->nent;
26489+ u = &rdu->ent;
2000de60 26490+ sb = file->f_path.dentry->d_sb;
1308ab2a 26491+ si_read_lock(sb, AuLock_FLUSH);
26492+ while (nent-- > 0) {
9dbd164d 26493+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 26494+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
26495+ if (!err)
26496+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 26497+ if (unlikely(err)) {
26498+ err = -EFAULT;
26499+ AuTraceErr(err);
26500+ break;
26501+ }
26502+
26503+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
26504+ if (!ent.wh)
26505+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
26506+ else
26507+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
26508+ &ino);
26509+ if (unlikely(err)) {
26510+ AuTraceErr(err);
26511+ break;
26512+ }
26513+
26514+ err = __put_user(ino, &u->e->ino);
26515+ if (unlikely(err)) {
26516+ err = -EFAULT;
26517+ AuTraceErr(err);
26518+ break;
26519+ }
26520+ u->ul += au_rdu_len(ent.nlen);
26521+ }
26522+ si_read_unlock(sb);
26523+
26524+ return err;
26525+}
26526+
26527+/* ---------------------------------------------------------------------- */
26528+
26529+static int au_rdu_verify(struct aufs_rdu *rdu)
26530+{
b752ccd1 26531+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 26532+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 26533+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 26534+ rdu->blk,
26535+ rdu->rent, rdu->shwh, rdu->full,
26536+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
26537+ rdu->cookie.generation);
dece6358 26538+
b752ccd1 26539+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 26540+ return 0;
dece6358 26541+
b752ccd1
AM
26542+ AuDbg("%u:%u\n",
26543+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 26544+ return -EINVAL;
26545+}
26546+
26547+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 26548+{
1308ab2a 26549+ long err, e;
26550+ struct aufs_rdu rdu;
26551+ void __user *p = (void __user *)arg;
dece6358 26552+
1308ab2a 26553+ err = copy_from_user(&rdu, p, sizeof(rdu));
26554+ if (unlikely(err)) {
26555+ err = -EFAULT;
26556+ AuTraceErr(err);
26557+ goto out;
26558+ }
26559+ err = au_rdu_verify(&rdu);
dece6358
AM
26560+ if (unlikely(err))
26561+ goto out;
26562+
1308ab2a 26563+ switch (cmd) {
26564+ case AUFS_CTL_RDU:
26565+ err = au_rdu(file, &rdu);
26566+ if (unlikely(err))
26567+ break;
dece6358 26568+
1308ab2a 26569+ e = copy_to_user(p, &rdu, sizeof(rdu));
26570+ if (unlikely(e)) {
26571+ err = -EFAULT;
26572+ AuTraceErr(err);
26573+ }
26574+ break;
26575+ case AUFS_CTL_RDU_INO:
26576+ err = au_rdu_ino(file, &rdu);
26577+ break;
26578+
26579+ default:
4a4d8108 26580+ /* err = -ENOTTY; */
1308ab2a 26581+ err = -EINVAL;
26582+ }
dece6358 26583+
4f0767ce 26584+out:
1308ab2a 26585+ AuTraceErr(err);
26586+ return err;
1facf9fc 26587+}
b752ccd1
AM
26588+
26589+#ifdef CONFIG_COMPAT
26590+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
26591+{
26592+ long err, e;
26593+ struct aufs_rdu rdu;
26594+ void __user *p = compat_ptr(arg);
26595+
26596+ /* todo: get_user()? */
26597+ err = copy_from_user(&rdu, p, sizeof(rdu));
26598+ if (unlikely(err)) {
26599+ err = -EFAULT;
26600+ AuTraceErr(err);
26601+ goto out;
26602+ }
26603+ rdu.ent.e = compat_ptr(rdu.ent.ul);
26604+ err = au_rdu_verify(&rdu);
26605+ if (unlikely(err))
26606+ goto out;
26607+
26608+ switch (cmd) {
26609+ case AUFS_CTL_RDU:
26610+ err = au_rdu(file, &rdu);
26611+ if (unlikely(err))
26612+ break;
26613+
26614+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
26615+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
26616+ e = copy_to_user(p, &rdu, sizeof(rdu));
26617+ if (unlikely(e)) {
26618+ err = -EFAULT;
26619+ AuTraceErr(err);
26620+ }
26621+ break;
26622+ case AUFS_CTL_RDU_INO:
26623+ err = au_rdu_ino(file, &rdu);
26624+ break;
26625+
26626+ default:
26627+ /* err = -ENOTTY; */
26628+ err = -EINVAL;
26629+ }
26630+
4f0767ce 26631+out:
b752ccd1
AM
26632+ AuTraceErr(err);
26633+ return err;
26634+}
26635+#endif
7f207e10
AM
26636diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
26637--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 26638+++ linux/fs/aufs/rwsem.h 2017-07-29 12:14:25.906375514 +0200
5afbbe0d 26639@@ -0,0 +1,198 @@
1facf9fc 26640+/*
a2654f78 26641+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 26642+ *
26643+ * This program, aufs is free software; you can redistribute it and/or modify
26644+ * it under the terms of the GNU General Public License as published by
26645+ * the Free Software Foundation; either version 2 of the License, or
26646+ * (at your option) any later version.
dece6358
AM
26647+ *
26648+ * This program is distributed in the hope that it will be useful,
26649+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26650+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26651+ * GNU General Public License for more details.
26652+ *
26653+ * You should have received a copy of the GNU General Public License
523b37e3 26654+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26655+ */
26656+
26657+/*
26658+ * simple read-write semaphore wrappers
26659+ */
26660+
26661+#ifndef __AUFS_RWSEM_H__
26662+#define __AUFS_RWSEM_H__
26663+
26664+#ifdef __KERNEL__
26665+
4a4d8108 26666+#include "debug.h"
dece6358
AM
26667+
26668+struct au_rwsem {
26669+ struct rw_semaphore rwsem;
26670+#ifdef CONFIG_AUFS_DEBUG
26671+ /* just for debugging, not almighty counter */
26672+ atomic_t rcnt, wcnt;
26673+#endif
26674+};
26675+
5afbbe0d
AM
26676+#ifdef CONFIG_LOCKDEP
26677+#define au_lockdep_set_name(rw) \
26678+ lockdep_set_class_and_name(&(rw)->rwsem, \
26679+ /*original key*/(rw)->rwsem.dep_map.key, \
26680+ /*name*/#rw)
26681+#else
26682+#define au_lockdep_set_name(rw) do {} while (0)
26683+#endif
26684+
dece6358
AM
26685+#ifdef CONFIG_AUFS_DEBUG
26686+#define AuDbgCntInit(rw) do { \
26687+ atomic_set(&(rw)->rcnt, 0); \
26688+ atomic_set(&(rw)->wcnt, 0); \
26689+ smp_mb(); /* atomic set */ \
26690+} while (0)
26691+
5afbbe0d
AM
26692+#define AuDbgCnt(rw, cnt) atomic_read(&(rw)->cnt)
26693+#define AuDbgCntInc(rw, cnt) atomic_inc(&(rw)->cnt)
26694+#define AuDbgCntDec(rw, cnt) WARN_ON(atomic_dec_return(&(rw)->cnt) < 0)
26695+#define AuDbgRcntInc(rw) AuDbgCntInc(rw, rcnt)
26696+#define AuDbgRcntDec(rw) AuDbgCntDec(rw, rcnt)
26697+#define AuDbgWcntInc(rw) AuDbgCntInc(rw, wcnt)
26698+#define AuDbgWcntDec(rw) AuDbgCntDec(rw, wcnt)
dece6358 26699+#else
5afbbe0d 26700+#define AuDbgCnt(rw, cnt) 0
dece6358
AM
26701+#define AuDbgCntInit(rw) do {} while (0)
26702+#define AuDbgRcntInc(rw) do {} while (0)
26703+#define AuDbgRcntDec(rw) do {} while (0)
26704+#define AuDbgWcntInc(rw) do {} while (0)
26705+#define AuDbgWcntDec(rw) do {} while (0)
26706+#endif /* CONFIG_AUFS_DEBUG */
26707+
26708+/* to debug easier, do not make them inlined functions */
5afbbe0d 26709+#define AuRwMustNoWaiters(rw) AuDebugOn(rwsem_is_contended(&(rw)->rwsem))
dece6358 26710+/* rwsem_is_locked() is unusable */
5afbbe0d
AM
26711+#define AuRwMustReadLock(rw) AuDebugOn(AuDbgCnt(rw, rcnt) <= 0)
26712+#define AuRwMustWriteLock(rw) AuDebugOn(AuDbgCnt(rw, wcnt) <= 0)
26713+#define AuRwMustAnyLock(rw) AuDebugOn(AuDbgCnt(rw, rcnt) <= 0 \
26714+ && AuDbgCnt(rw, wcnt) <= 0)
26715+#define AuRwDestroy(rw) AuDebugOn(AuDbgCnt(rw, rcnt) \
26716+ || AuDbgCnt(rw, wcnt))
26717+
26718+#define au_rw_init(rw) do { \
26719+ AuDbgCntInit(rw); \
26720+ init_rwsem(&(rw)->rwsem); \
26721+ au_lockdep_set_name(rw); \
26722+ } while (0)
dece6358 26723+
5afbbe0d
AM
26724+#define au_rw_init_wlock(rw) do { \
26725+ au_rw_init(rw); \
26726+ down_write(&(rw)->rwsem); \
26727+ AuDbgWcntInc(rw); \
26728+ } while (0)
dece6358 26729+
5afbbe0d
AM
26730+#define au_rw_init_wlock_nested(rw, lsc) do { \
26731+ au_rw_init(rw); \
26732+ down_write_nested(&(rw)->rwsem, lsc); \
26733+ AuDbgWcntInc(rw); \
26734+ } while (0)
dece6358
AM
26735+
26736+static inline void au_rw_read_lock(struct au_rwsem *rw)
26737+{
26738+ down_read(&rw->rwsem);
26739+ AuDbgRcntInc(rw);
26740+}
26741+
26742+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
26743+{
26744+ down_read_nested(&rw->rwsem, lsc);
26745+ AuDbgRcntInc(rw);
26746+}
26747+
26748+static inline void au_rw_read_unlock(struct au_rwsem *rw)
26749+{
26750+ AuRwMustReadLock(rw);
26751+ AuDbgRcntDec(rw);
26752+ up_read(&rw->rwsem);
26753+}
26754+
26755+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
26756+{
26757+ AuRwMustWriteLock(rw);
26758+ AuDbgRcntInc(rw);
26759+ AuDbgWcntDec(rw);
26760+ downgrade_write(&rw->rwsem);
26761+}
26762+
26763+static inline void au_rw_write_lock(struct au_rwsem *rw)
26764+{
26765+ down_write(&rw->rwsem);
26766+ AuDbgWcntInc(rw);
26767+}
26768+
26769+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
26770+ unsigned int lsc)
26771+{
26772+ down_write_nested(&rw->rwsem, lsc);
26773+ AuDbgWcntInc(rw);
26774+}
1facf9fc 26775+
dece6358
AM
26776+static inline void au_rw_write_unlock(struct au_rwsem *rw)
26777+{
26778+ AuRwMustWriteLock(rw);
26779+ AuDbgWcntDec(rw);
26780+ up_write(&rw->rwsem);
26781+}
26782+
26783+/* why is not _nested version defined */
26784+static inline int au_rw_read_trylock(struct au_rwsem *rw)
26785+{
076b876e
AM
26786+ int ret;
26787+
26788+ ret = down_read_trylock(&rw->rwsem);
dece6358
AM
26789+ if (ret)
26790+ AuDbgRcntInc(rw);
26791+ return ret;
26792+}
26793+
26794+static inline int au_rw_write_trylock(struct au_rwsem *rw)
26795+{
076b876e
AM
26796+ int ret;
26797+
26798+ ret = down_write_trylock(&rw->rwsem);
dece6358
AM
26799+ if (ret)
26800+ AuDbgWcntInc(rw);
26801+ return ret;
26802+}
26803+
5afbbe0d 26804+#undef AuDbgCntDec
dece6358
AM
26805+#undef AuDbgRcntInc
26806+#undef AuDbgRcntDec
dece6358 26807+#undef AuDbgWcntDec
1facf9fc 26808+
26809+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
26810+static inline void prefix##_read_lock(param) \
dece6358 26811+{ au_rw_read_lock(rwsem); } \
1facf9fc 26812+static inline void prefix##_write_lock(param) \
dece6358 26813+{ au_rw_write_lock(rwsem); } \
1facf9fc 26814+static inline int prefix##_read_trylock(param) \
dece6358 26815+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 26816+static inline int prefix##_write_trylock(param) \
dece6358 26817+{ return au_rw_write_trylock(rwsem); }
1facf9fc 26818+/* why is not _nested version defined */
26819+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 26820+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 26821+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 26822+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 26823+
26824+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
26825+static inline void prefix##_read_unlock(param) \
dece6358 26826+{ au_rw_read_unlock(rwsem); } \
1facf9fc 26827+static inline void prefix##_write_unlock(param) \
dece6358 26828+{ au_rw_write_unlock(rwsem); } \
1facf9fc 26829+static inline void prefix##_downgrade_lock(param) \
dece6358 26830+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 26831+
26832+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
26833+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
26834+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
26835+
26836+#endif /* __KERNEL__ */
26837+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
26838diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
26839--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 26840+++ linux/fs/aufs/sbinfo.c 2017-07-29 12:14:25.906375514 +0200
a2654f78 26841@@ -0,0 +1,304 @@
1facf9fc 26842+/*
a2654f78 26843+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 26844+ *
26845+ * This program, aufs is free software; you can redistribute it and/or modify
26846+ * it under the terms of the GNU General Public License as published by
26847+ * the Free Software Foundation; either version 2 of the License, or
26848+ * (at your option) any later version.
dece6358
AM
26849+ *
26850+ * This program is distributed in the hope that it will be useful,
26851+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26852+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26853+ * GNU General Public License for more details.
26854+ *
26855+ * You should have received a copy of the GNU General Public License
523b37e3 26856+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26857+ */
26858+
26859+/*
26860+ * superblock private data
26861+ */
26862+
26863+#include "aufs.h"
26864+
26865+/*
26866+ * they are necessary regardless sysfs is disabled.
26867+ */
26868+void au_si_free(struct kobject *kobj)
26869+{
86dc4139 26870+ int i;
1facf9fc 26871+ struct au_sbinfo *sbinfo;
b752ccd1 26872+ char *locked __maybe_unused; /* debug only */
1facf9fc 26873+
26874+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139
AM
26875+ for (i = 0; i < AuPlink_NHASH; i++)
26876+ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
f0c0a007 26877+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
5afbbe0d
AM
26878+
26879+ AuDebugOn(percpu_counter_sum(&sbinfo->si_ninodes));
26880+ percpu_counter_destroy(&sbinfo->si_ninodes);
26881+ AuDebugOn(percpu_counter_sum(&sbinfo->si_nfiles));
26882+ percpu_counter_destroy(&sbinfo->si_nfiles);
1facf9fc 26883+
e49829fe 26884+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 26885+ au_br_free(sbinfo);
e49829fe 26886+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1 26887+
1c60b727 26888+ kfree(sbinfo->si_branch);
1facf9fc 26889+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 26890+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 26891+
1c60b727 26892+ kfree(sbinfo);
1facf9fc 26893+}
26894+
26895+int au_si_alloc(struct super_block *sb)
26896+{
86dc4139 26897+ int err, i;
1facf9fc 26898+ struct au_sbinfo *sbinfo;
26899+
26900+ err = -ENOMEM;
4a4d8108 26901+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 26902+ if (unlikely(!sbinfo))
26903+ goto out;
26904+
26905+ /* will be reallocated separately */
26906+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
26907+ if (unlikely(!sbinfo->si_branch))
febd17d6 26908+ goto out_sbinfo;
1facf9fc 26909+
1facf9fc 26910+ err = sysaufs_si_init(sbinfo);
26911+ if (unlikely(err))
26912+ goto out_br;
26913+
26914+ au_nwt_init(&sbinfo->si_nowait);
dece6358 26915+ au_rw_init_wlock(&sbinfo->si_rwsem);
b752ccd1 26916+
5afbbe0d
AM
26917+ percpu_counter_init(&sbinfo->si_ninodes, 0, GFP_NOFS);
26918+ percpu_counter_init(&sbinfo->si_nfiles, 0, GFP_NOFS);
7f207e10 26919+
5afbbe0d 26920+ sbinfo->si_bbot = -1;
392086de 26921+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 26922+
26923+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
26924+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
26925+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
26926+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 26927+
076b876e
AM
26928+ au_fhsm_init(sbinfo);
26929+
e49829fe 26930+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 26931+
392086de
AM
26932+ sbinfo->si_xino_jiffy = jiffies;
26933+ sbinfo->si_xino_expire
26934+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 26935+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 26936+ sbinfo->si_xino_brid = -1;
26937+ /* leave si_xib_last_pindex and si_xib_next_bit */
26938+
b912730e
AM
26939+ au_sphl_init(&sbinfo->si_aopen);
26940+
e49829fe 26941+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 26942+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
26943+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
26944+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
26945+
86dc4139
AM
26946+ for (i = 0; i < AuPlink_NHASH; i++)
26947+ au_sphl_init(sbinfo->si_plink + i);
1facf9fc 26948+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 26949+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 26950+
523b37e3
AM
26951+ au_sphl_init(&sbinfo->si_files);
26952+
b95c5147
AM
26953+ /* with getattr by default */
26954+ sbinfo->si_iop_array = aufs_iop;
26955+
1facf9fc 26956+ /* leave other members for sysaufs and si_mnt. */
26957+ sbinfo->si_sb = sb;
26958+ sb->s_fs_info = sbinfo;
b752ccd1 26959+ si_pid_set(sb);
1facf9fc 26960+ return 0; /* success */
26961+
4f0767ce 26962+out_br:
1c60b727 26963+ kfree(sbinfo->si_branch);
4f0767ce 26964+out_sbinfo:
1c60b727 26965+ kfree(sbinfo);
4f0767ce 26966+out:
1facf9fc 26967+ return err;
26968+}
26969+
e2f27e51 26970+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink)
1facf9fc 26971+{
26972+ int err, sz;
26973+ struct au_branch **brp;
26974+
dece6358
AM
26975+ AuRwMustWriteLock(&sbinfo->si_rwsem);
26976+
1facf9fc 26977+ err = -ENOMEM;
5afbbe0d 26978+ sz = sizeof(*brp) * (sbinfo->si_bbot + 1);
1facf9fc 26979+ if (unlikely(!sz))
26980+ sz = sizeof(*brp);
e2f27e51
AM
26981+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS,
26982+ may_shrink);
1facf9fc 26983+ if (brp) {
26984+ sbinfo->si_branch = brp;
26985+ err = 0;
26986+ }
26987+
26988+ return err;
26989+}
26990+
26991+/* ---------------------------------------------------------------------- */
26992+
26993+unsigned int au_sigen_inc(struct super_block *sb)
26994+{
26995+ unsigned int gen;
5527c038 26996+ struct inode *inode;
1facf9fc 26997+
dece6358
AM
26998+ SiMustWriteLock(sb);
26999+
1facf9fc 27000+ gen = ++au_sbi(sb)->si_generation;
27001+ au_update_digen(sb->s_root);
5527c038
JR
27002+ inode = d_inode(sb->s_root);
27003+ au_update_iigen(inode, /*half*/0);
27004+ inode->i_version++;
1facf9fc 27005+ return gen;
27006+}
27007+
27008+aufs_bindex_t au_new_br_id(struct super_block *sb)
27009+{
27010+ aufs_bindex_t br_id;
27011+ int i;
27012+ struct au_sbinfo *sbinfo;
27013+
dece6358
AM
27014+ SiMustWriteLock(sb);
27015+
1facf9fc 27016+ sbinfo = au_sbi(sb);
27017+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
27018+ br_id = ++sbinfo->si_last_br_id;
7f207e10 27019+ AuDebugOn(br_id < 0);
1facf9fc 27020+ if (br_id && au_br_index(sb, br_id) < 0)
27021+ return br_id;
27022+ }
27023+
27024+ return -1;
27025+}
27026+
27027+/* ---------------------------------------------------------------------- */
27028+
e49829fe
JR
27029+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
27030+int si_read_lock(struct super_block *sb, int flags)
27031+{
27032+ int err;
27033+
27034+ err = 0;
27035+ if (au_ftest_lock(flags, FLUSH))
27036+ au_nwt_flush(&au_sbi(sb)->si_nowait);
27037+
27038+ si_noflush_read_lock(sb);
27039+ err = au_plink_maint(sb, flags);
27040+ if (unlikely(err))
27041+ si_read_unlock(sb);
27042+
27043+ return err;
27044+}
27045+
27046+int si_write_lock(struct super_block *sb, int flags)
27047+{
27048+ int err;
27049+
27050+ if (au_ftest_lock(flags, FLUSH))
27051+ au_nwt_flush(&au_sbi(sb)->si_nowait);
27052+
27053+ si_noflush_write_lock(sb);
27054+ err = au_plink_maint(sb, flags);
27055+ if (unlikely(err))
27056+ si_write_unlock(sb);
27057+
27058+ return err;
27059+}
27060+
1facf9fc 27061+/* dentry and super_block lock. call at entry point */
e49829fe 27062+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 27063+{
e49829fe 27064+ int err;
027c5e7a 27065+ struct super_block *sb;
e49829fe 27066+
027c5e7a
AM
27067+ sb = dentry->d_sb;
27068+ err = si_read_lock(sb, flags);
27069+ if (unlikely(err))
27070+ goto out;
27071+
27072+ if (au_ftest_lock(flags, DW))
27073+ di_write_lock_child(dentry);
27074+ else
27075+ di_read_lock_child(dentry, flags);
27076+
27077+ if (au_ftest_lock(flags, GEN)) {
27078+ err = au_digen_test(dentry, au_sigen(sb));
79b8bda9
AM
27079+ if (!au_opt_test(au_mntflags(sb), UDBA_NONE))
27080+ AuDebugOn(!err && au_dbrange_test(dentry));
27081+ else if (!err)
27082+ err = au_dbrange_test(dentry);
027c5e7a
AM
27083+ if (unlikely(err))
27084+ aufs_read_unlock(dentry, flags);
e49829fe
JR
27085+ }
27086+
027c5e7a 27087+out:
e49829fe 27088+ return err;
1facf9fc 27089+}
27090+
27091+void aufs_read_unlock(struct dentry *dentry, int flags)
27092+{
27093+ if (au_ftest_lock(flags, DW))
27094+ di_write_unlock(dentry);
27095+ else
27096+ di_read_unlock(dentry, flags);
27097+ si_read_unlock(dentry->d_sb);
27098+}
27099+
27100+void aufs_write_lock(struct dentry *dentry)
27101+{
e49829fe 27102+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 27103+ di_write_lock_child(dentry);
27104+}
27105+
27106+void aufs_write_unlock(struct dentry *dentry)
27107+{
27108+ di_write_unlock(dentry);
27109+ si_write_unlock(dentry->d_sb);
27110+}
27111+
e49829fe 27112+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 27113+{
e49829fe 27114+ int err;
027c5e7a
AM
27115+ unsigned int sigen;
27116+ struct super_block *sb;
e49829fe 27117+
027c5e7a
AM
27118+ sb = d1->d_sb;
27119+ err = si_read_lock(sb, flags);
27120+ if (unlikely(err))
27121+ goto out;
27122+
b95c5147 27123+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS));
027c5e7a
AM
27124+
27125+ if (au_ftest_lock(flags, GEN)) {
27126+ sigen = au_sigen(sb);
27127+ err = au_digen_test(d1, sigen);
27128+ AuDebugOn(!err && au_dbrange_test(d1));
27129+ if (!err) {
27130+ err = au_digen_test(d2, sigen);
27131+ AuDebugOn(!err && au_dbrange_test(d2));
27132+ }
27133+ if (unlikely(err))
27134+ aufs_read_and_write_unlock2(d1, d2);
27135+ }
27136+
27137+out:
e49829fe 27138+ return err;
1facf9fc 27139+}
27140+
27141+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
27142+{
27143+ di_write_unlock2(d1, d2);
27144+ si_read_unlock(d1->d_sb);
27145+}
7f207e10
AM
27146diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
27147--- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 27148+++ linux/fs/aufs/spl.h 2017-07-29 12:14:25.906375514 +0200
f0c0a007 27149@@ -0,0 +1,113 @@
1facf9fc 27150+/*
a2654f78 27151+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 27152+ *
27153+ * This program, aufs is free software; you can redistribute it and/or modify
27154+ * it under the terms of the GNU General Public License as published by
27155+ * the Free Software Foundation; either version 2 of the License, or
27156+ * (at your option) any later version.
dece6358
AM
27157+ *
27158+ * This program is distributed in the hope that it will be useful,
27159+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27160+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27161+ * GNU General Public License for more details.
27162+ *
27163+ * You should have received a copy of the GNU General Public License
523b37e3 27164+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27165+ */
27166+
27167+/*
27168+ * simple list protected by a spinlock
27169+ */
27170+
27171+#ifndef __AUFS_SPL_H__
27172+#define __AUFS_SPL_H__
27173+
27174+#ifdef __KERNEL__
27175+
f0c0a007 27176+#if 0
1facf9fc 27177+struct au_splhead {
27178+ spinlock_t spin;
27179+ struct list_head head;
27180+};
27181+
27182+static inline void au_spl_init(struct au_splhead *spl)
27183+{
27184+ spin_lock_init(&spl->spin);
27185+ INIT_LIST_HEAD(&spl->head);
27186+}
27187+
27188+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
27189+{
27190+ spin_lock(&spl->spin);
27191+ list_add(list, &spl->head);
27192+ spin_unlock(&spl->spin);
27193+}
27194+
27195+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
27196+{
27197+ spin_lock(&spl->spin);
27198+ list_del(list);
27199+ spin_unlock(&spl->spin);
27200+}
27201+
4a4d8108
AM
27202+static inline void au_spl_del_rcu(struct list_head *list,
27203+ struct au_splhead *spl)
27204+{
27205+ spin_lock(&spl->spin);
27206+ list_del_rcu(list);
27207+ spin_unlock(&spl->spin);
27208+}
f0c0a007 27209+#endif
4a4d8108 27210+
86dc4139
AM
27211+/* ---------------------------------------------------------------------- */
27212+
27213+struct au_sphlhead {
27214+ spinlock_t spin;
27215+ struct hlist_head head;
27216+};
27217+
27218+static inline void au_sphl_init(struct au_sphlhead *sphl)
27219+{
27220+ spin_lock_init(&sphl->spin);
27221+ INIT_HLIST_HEAD(&sphl->head);
27222+}
27223+
27224+static inline void au_sphl_add(struct hlist_node *hlist,
27225+ struct au_sphlhead *sphl)
27226+{
27227+ spin_lock(&sphl->spin);
27228+ hlist_add_head(hlist, &sphl->head);
27229+ spin_unlock(&sphl->spin);
27230+}
27231+
27232+static inline void au_sphl_del(struct hlist_node *hlist,
27233+ struct au_sphlhead *sphl)
27234+{
27235+ spin_lock(&sphl->spin);
27236+ hlist_del(hlist);
27237+ spin_unlock(&sphl->spin);
27238+}
27239+
27240+static inline void au_sphl_del_rcu(struct hlist_node *hlist,
27241+ struct au_sphlhead *sphl)
27242+{
27243+ spin_lock(&sphl->spin);
27244+ hlist_del_rcu(hlist);
27245+ spin_unlock(&sphl->spin);
27246+}
27247+
27248+static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
27249+{
27250+ unsigned long cnt;
27251+ struct hlist_node *pos;
27252+
27253+ cnt = 0;
27254+ spin_lock(&sphl->spin);
27255+ hlist_for_each(pos, &sphl->head)
27256+ cnt++;
27257+ spin_unlock(&sphl->spin);
27258+ return cnt;
27259+}
27260+
1facf9fc 27261+#endif /* __KERNEL__ */
27262+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
27263diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
27264--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 27265+++ linux/fs/aufs/super.c 2017-07-29 12:14:25.906375514 +0200
a2654f78 27266@@ -0,0 +1,1044 @@
1facf9fc 27267+/*
a2654f78 27268+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 27269+ *
27270+ * This program, aufs is free software; you can redistribute it and/or modify
27271+ * it under the terms of the GNU General Public License as published by
27272+ * the Free Software Foundation; either version 2 of the License, or
27273+ * (at your option) any later version.
dece6358
AM
27274+ *
27275+ * This program is distributed in the hope that it will be useful,
27276+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27277+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27278+ * GNU General Public License for more details.
27279+ *
27280+ * You should have received a copy of the GNU General Public License
523b37e3 27281+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27282+ */
27283+
27284+/*
27285+ * mount and super_block operations
27286+ */
27287+
f6c5ef8b 27288+#include <linux/mm.h>
1facf9fc 27289+#include <linux/seq_file.h>
27290+#include <linux/statfs.h>
7f207e10 27291+#include <linux/vmalloc.h>
1facf9fc 27292+#include "aufs.h"
27293+
27294+/*
27295+ * super_operations
27296+ */
27297+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
27298+{
27299+ struct au_icntnr *c;
27300+
27301+ c = au_cache_alloc_icntnr();
27302+ if (c) {
027c5e7a 27303+ au_icntnr_init(c);
1facf9fc 27304+ c->vfs_inode.i_version = 1; /* sigen(sb); */
27305+ c->iinfo.ii_hinode = NULL;
27306+ return &c->vfs_inode;
27307+ }
27308+ return NULL;
27309+}
27310+
027c5e7a
AM
27311+static void aufs_destroy_inode_cb(struct rcu_head *head)
27312+{
27313+ struct inode *inode = container_of(head, struct inode, i_rcu);
27314+
1c60b727 27315+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
027c5e7a
AM
27316+}
27317+
1facf9fc 27318+static void aufs_destroy_inode(struct inode *inode)
27319+{
5afbbe0d
AM
27320+ if (!au_is_bad_inode(inode))
27321+ au_iinfo_fin(inode);
027c5e7a 27322+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 27323+}
27324+
27325+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
27326+{
27327+ struct inode *inode;
27328+ int err;
27329+
27330+ inode = iget_locked(sb, ino);
27331+ if (unlikely(!inode)) {
27332+ inode = ERR_PTR(-ENOMEM);
27333+ goto out;
27334+ }
27335+ if (!(inode->i_state & I_NEW))
27336+ goto out;
27337+
27338+ err = au_xigen_new(inode);
27339+ if (!err)
27340+ err = au_iinfo_init(inode);
27341+ if (!err)
27342+ inode->i_version++;
27343+ else {
27344+ iget_failed(inode);
27345+ inode = ERR_PTR(err);
27346+ }
27347+
4f0767ce 27348+out:
1facf9fc 27349+ /* never return NULL */
27350+ AuDebugOn(!inode);
27351+ AuTraceErrPtr(inode);
27352+ return inode;
27353+}
27354+
27355+/* lock free root dinfo */
27356+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
27357+{
27358+ int err;
5afbbe0d 27359+ aufs_bindex_t bindex, bbot;
1facf9fc 27360+ struct path path;
4a4d8108 27361+ struct au_hdentry *hdp;
1facf9fc 27362+ struct au_branch *br;
076b876e 27363+ au_br_perm_str_t perm;
1facf9fc 27364+
27365+ err = 0;
5afbbe0d
AM
27366+ bbot = au_sbbot(sb);
27367+ bindex = 0;
27368+ hdp = au_hdentry(au_di(sb->s_root), bindex);
27369+ for (; !err && bindex <= bbot; bindex++, hdp++) {
1facf9fc 27370+ br = au_sbr(sb, bindex);
86dc4139 27371+ path.mnt = au_br_mnt(br);
5afbbe0d 27372+ path.dentry = hdp->hd_dentry;
1facf9fc 27373+ err = au_seq_path(seq, &path);
79b8bda9 27374+ if (!err) {
076b876e 27375+ au_optstr_br_perm(&perm, br->br_perm);
79b8bda9 27376+ seq_printf(seq, "=%s", perm.a);
5afbbe0d 27377+ if (bindex != bbot)
79b8bda9 27378+ seq_putc(seq, ':');
1e00d052 27379+ }
1facf9fc 27380+ }
79b8bda9
AM
27381+ if (unlikely(err || seq_has_overflowed(seq)))
27382+ err = -E2BIG;
1facf9fc 27383+
27384+ return err;
27385+}
27386+
f2c43d5f
AM
27387+static void au_gen_fmt(char *fmt, int len __maybe_unused, const char *pat,
27388+ const char *append)
27389+{
27390+ char *p;
27391+
27392+ p = fmt;
27393+ while (*pat != ':')
27394+ *p++ = *pat++;
27395+ *p++ = *pat++;
27396+ strcpy(p, append);
27397+ AuDebugOn(strlen(fmt) >= len);
27398+}
27399+
1facf9fc 27400+static void au_show_wbr_create(struct seq_file *m, int v,
27401+ struct au_sbinfo *sbinfo)
27402+{
27403+ const char *pat;
f2c43d5f
AM
27404+ char fmt[32];
27405+ struct au_wbr_mfs *mfs;
1facf9fc 27406+
dece6358
AM
27407+ AuRwMustAnyLock(&sbinfo->si_rwsem);
27408+
c2b27bf2 27409+ seq_puts(m, ",create=");
1facf9fc 27410+ pat = au_optstr_wbr_create(v);
f2c43d5f 27411+ mfs = &sbinfo->si_wbr_mfs;
1facf9fc 27412+ switch (v) {
27413+ case AuWbrCreate_TDP:
27414+ case AuWbrCreate_RR:
27415+ case AuWbrCreate_MFS:
27416+ case AuWbrCreate_PMFS:
c2b27bf2 27417+ seq_puts(m, pat);
1facf9fc 27418+ break;
f2c43d5f
AM
27419+ case AuWbrCreate_MFSRR:
27420+ case AuWbrCreate_TDMFS:
27421+ case AuWbrCreate_PMFSRR:
27422+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu");
27423+ seq_printf(m, fmt, mfs->mfsrr_watermark);
1facf9fc 27424+ break;
f2c43d5f 27425+ case AuWbrCreate_MFSV:
1facf9fc 27426+ case AuWbrCreate_PMFSV:
f2c43d5f
AM
27427+ au_gen_fmt(fmt, sizeof(fmt), pat, "%lu");
27428+ seq_printf(m, fmt,
27429+ jiffies_to_msecs(mfs->mfs_expire)
e49829fe 27430+ / MSEC_PER_SEC);
1facf9fc 27431+ break;
1facf9fc 27432+ case AuWbrCreate_MFSRRV:
f2c43d5f 27433+ case AuWbrCreate_TDMFSV:
392086de 27434+ case AuWbrCreate_PMFSRRV:
f2c43d5f
AM
27435+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu:%lu");
27436+ seq_printf(m, fmt, mfs->mfsrr_watermark,
27437+ jiffies_to_msecs(mfs->mfs_expire) / MSEC_PER_SEC);
392086de 27438+ break;
f2c43d5f
AM
27439+ default:
27440+ BUG();
1facf9fc 27441+ }
27442+}
27443+
7eafdf33 27444+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 27445+{
27446+#ifdef CONFIG_SYSFS
27447+ return 0;
27448+#else
27449+ int err;
27450+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
27451+ aufs_bindex_t bindex, brid;
1facf9fc 27452+ struct qstr *name;
27453+ struct file *f;
27454+ struct dentry *d, *h_root;
27455+
dece6358
AM
27456+ AuRwMustAnyLock(&sbinfo->si_rwsem);
27457+
1facf9fc 27458+ err = 0;
1facf9fc 27459+ f = au_sbi(sb)->si_xib;
27460+ if (!f)
27461+ goto out;
27462+
27463+ /* stop printing the default xino path on the first writable branch */
27464+ h_root = NULL;
27465+ brid = au_xino_brid(sb);
27466+ if (brid >= 0) {
27467+ bindex = au_br_index(sb, brid);
5afbbe0d 27468+ h_root = au_hdentry(au_di(sb->s_root), bindex)->hd_dentry;
1facf9fc 27469+ }
2000de60 27470+ d = f->f_path.dentry;
1facf9fc 27471+ name = &d->d_name;
27472+ /* safe ->d_parent because the file is unlinked */
27473+ if (d->d_parent == h_root
27474+ && name->len == len
27475+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
27476+ goto out;
27477+
27478+ seq_puts(seq, ",xino=");
27479+ err = au_xino_path(seq, f);
27480+
4f0767ce 27481+out:
1facf9fc 27482+ return err;
27483+#endif
27484+}
27485+
27486+/* seq_file will re-call me in case of too long string */
7eafdf33 27487+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 27488+{
027c5e7a 27489+ int err;
1facf9fc 27490+ unsigned int mnt_flags, v;
27491+ struct super_block *sb;
27492+ struct au_sbinfo *sbinfo;
27493+
27494+#define AuBool(name, str) do { \
27495+ v = au_opt_test(mnt_flags, name); \
27496+ if (v != au_opt_test(AuOpt_Def, name)) \
27497+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
27498+} while (0)
27499+
27500+#define AuStr(name, str) do { \
27501+ v = mnt_flags & AuOptMask_##name; \
27502+ if (v != (AuOpt_Def & AuOptMask_##name)) \
27503+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
27504+} while (0)
27505+
27506+#define AuUInt(name, str, val) do { \
27507+ if (val != AUFS_##name##_DEF) \
27508+ seq_printf(m, "," #str "=%u", val); \
27509+} while (0)
27510+
7eafdf33 27511+ sb = dentry->d_sb;
c1595e42
JR
27512+ if (sb->s_flags & MS_POSIXACL)
27513+ seq_puts(m, ",acl");
27514+
27515+ /* lock free root dinfo */
1facf9fc 27516+ si_noflush_read_lock(sb);
27517+ sbinfo = au_sbi(sb);
27518+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
27519+
27520+ mnt_flags = au_mntflags(sb);
27521+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 27522+ err = au_show_xino(m, sb);
1facf9fc 27523+ if (unlikely(err))
27524+ goto out;
27525+ } else
27526+ seq_puts(m, ",noxino");
27527+
27528+ AuBool(TRUNC_XINO, trunc_xino);
27529+ AuStr(UDBA, udba);
dece6358 27530+ AuBool(SHWH, shwh);
1facf9fc 27531+ AuBool(PLINK, plink);
4a4d8108 27532+ AuBool(DIO, dio);
076b876e 27533+ AuBool(DIRPERM1, dirperm1);
1facf9fc 27534+
27535+ v = sbinfo->si_wbr_create;
27536+ if (v != AuWbrCreate_Def)
27537+ au_show_wbr_create(m, v, sbinfo);
27538+
27539+ v = sbinfo->si_wbr_copyup;
27540+ if (v != AuWbrCopyup_Def)
27541+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
27542+
27543+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
27544+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
27545+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
27546+
27547+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
27548+
027c5e7a
AM
27549+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
27550+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 27551+
27552+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
27553+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
27554+
076b876e
AM
27555+ au_fhsm_show(m, sbinfo);
27556+
1facf9fc 27557+ AuBool(SUM, sum);
27558+ /* AuBool(SUM_W, wsum); */
27559+ AuBool(WARN_PERM, warn_perm);
27560+ AuBool(VERBOSE, verbose);
27561+
4f0767ce 27562+out:
1facf9fc 27563+ /* be sure to print "br:" last */
27564+ if (!sysaufs_brs) {
27565+ seq_puts(m, ",br:");
27566+ au_show_brs(m, sb);
27567+ }
27568+ si_read_unlock(sb);
27569+ return 0;
27570+
1facf9fc 27571+#undef AuBool
27572+#undef AuStr
4a4d8108 27573+#undef AuUInt
1facf9fc 27574+}
27575+
27576+/* ---------------------------------------------------------------------- */
27577+
27578+/* sum mode which returns the summation for statfs(2) */
27579+
27580+static u64 au_add_till_max(u64 a, u64 b)
27581+{
27582+ u64 old;
27583+
27584+ old = a;
27585+ a += b;
92d182d2
AM
27586+ if (old <= a)
27587+ return a;
27588+ return ULLONG_MAX;
27589+}
27590+
27591+static u64 au_mul_till_max(u64 a, long mul)
27592+{
27593+ u64 old;
27594+
27595+ old = a;
27596+ a *= mul;
27597+ if (old <= a)
1facf9fc 27598+ return a;
27599+ return ULLONG_MAX;
27600+}
27601+
27602+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
27603+{
27604+ int err;
92d182d2 27605+ long bsize, factor;
1facf9fc 27606+ u64 blocks, bfree, bavail, files, ffree;
5afbbe0d 27607+ aufs_bindex_t bbot, bindex, i;
1facf9fc 27608+ unsigned char shared;
7f207e10 27609+ struct path h_path;
1facf9fc 27610+ struct super_block *h_sb;
27611+
92d182d2
AM
27612+ err = 0;
27613+ bsize = LONG_MAX;
27614+ files = 0;
27615+ ffree = 0;
1facf9fc 27616+ blocks = 0;
27617+ bfree = 0;
27618+ bavail = 0;
5afbbe0d
AM
27619+ bbot = au_sbbot(sb);
27620+ for (bindex = 0; bindex <= bbot; bindex++) {
7f207e10
AM
27621+ h_path.mnt = au_sbr_mnt(sb, bindex);
27622+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 27623+ shared = 0;
92d182d2 27624+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 27625+ shared = (au_sbr_sb(sb, i) == h_sb);
27626+ if (shared)
27627+ continue;
27628+
27629+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
27630+ h_path.dentry = h_path.mnt->mnt_root;
27631+ err = vfs_statfs(&h_path, buf);
1facf9fc 27632+ if (unlikely(err))
27633+ goto out;
27634+
92d182d2
AM
27635+ if (bsize > buf->f_bsize) {
27636+ /*
27637+ * we will reduce bsize, so we have to expand blocks
27638+ * etc. to match them again
27639+ */
27640+ factor = (bsize / buf->f_bsize);
27641+ blocks = au_mul_till_max(blocks, factor);
27642+ bfree = au_mul_till_max(bfree, factor);
27643+ bavail = au_mul_till_max(bavail, factor);
27644+ bsize = buf->f_bsize;
27645+ }
27646+
27647+ factor = (buf->f_bsize / bsize);
27648+ blocks = au_add_till_max(blocks,
27649+ au_mul_till_max(buf->f_blocks, factor));
27650+ bfree = au_add_till_max(bfree,
27651+ au_mul_till_max(buf->f_bfree, factor));
27652+ bavail = au_add_till_max(bavail,
27653+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 27654+ files = au_add_till_max(files, buf->f_files);
27655+ ffree = au_add_till_max(ffree, buf->f_ffree);
27656+ }
27657+
92d182d2 27658+ buf->f_bsize = bsize;
1facf9fc 27659+ buf->f_blocks = blocks;
27660+ buf->f_bfree = bfree;
27661+ buf->f_bavail = bavail;
27662+ buf->f_files = files;
27663+ buf->f_ffree = ffree;
92d182d2 27664+ buf->f_frsize = 0;
1facf9fc 27665+
4f0767ce 27666+out:
1facf9fc 27667+ return err;
27668+}
27669+
27670+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
27671+{
27672+ int err;
7f207e10 27673+ struct path h_path;
1facf9fc 27674+ struct super_block *sb;
27675+
27676+ /* lock free root dinfo */
27677+ sb = dentry->d_sb;
27678+ si_noflush_read_lock(sb);
7f207e10 27679+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 27680+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
27681+ h_path.mnt = au_sbr_mnt(sb, 0);
27682+ h_path.dentry = h_path.mnt->mnt_root;
27683+ err = vfs_statfs(&h_path, buf);
27684+ } else
1facf9fc 27685+ err = au_statfs_sum(sb, buf);
27686+ si_read_unlock(sb);
27687+
27688+ if (!err) {
27689+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 27690+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 27691+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
27692+ }
27693+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
27694+
27695+ return err;
27696+}
27697+
27698+/* ---------------------------------------------------------------------- */
27699+
537831f9
AM
27700+static int aufs_sync_fs(struct super_block *sb, int wait)
27701+{
27702+ int err, e;
5afbbe0d 27703+ aufs_bindex_t bbot, bindex;
537831f9
AM
27704+ struct au_branch *br;
27705+ struct super_block *h_sb;
27706+
27707+ err = 0;
27708+ si_noflush_read_lock(sb);
5afbbe0d
AM
27709+ bbot = au_sbbot(sb);
27710+ for (bindex = 0; bindex <= bbot; bindex++) {
537831f9
AM
27711+ br = au_sbr(sb, bindex);
27712+ if (!au_br_writable(br->br_perm))
27713+ continue;
27714+
27715+ h_sb = au_sbr_sb(sb, bindex);
a2654f78
AM
27716+ e = vfsub_sync_filesystem(h_sb, wait);
27717+ if (unlikely(e && !err))
27718+ err = e;
27719+ /* go on even if an error happens */
537831f9
AM
27720+ }
27721+ si_read_unlock(sb);
27722+
27723+ return err;
27724+}
27725+
27726+/* ---------------------------------------------------------------------- */
27727+
1facf9fc 27728+/* final actions when unmounting a file system */
27729+static void aufs_put_super(struct super_block *sb)
27730+{
27731+ struct au_sbinfo *sbinfo;
27732+
27733+ sbinfo = au_sbi(sb);
27734+ if (!sbinfo)
27735+ return;
27736+
1facf9fc 27737+ dbgaufs_si_fin(sbinfo);
27738+ kobject_put(&sbinfo->si_kobj);
27739+}
27740+
27741+/* ---------------------------------------------------------------------- */
27742+
79b8bda9
AM
27743+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
27744+ struct super_block *sb, void *arg)
7f207e10
AM
27745+{
27746+ void *array;
076b876e 27747+ unsigned long long n, sz;
7f207e10
AM
27748+
27749+ array = NULL;
27750+ n = 0;
27751+ if (!*hint)
27752+ goto out;
27753+
27754+ if (*hint > ULLONG_MAX / sizeof(array)) {
27755+ array = ERR_PTR(-EMFILE);
27756+ pr_err("hint %llu\n", *hint);
27757+ goto out;
27758+ }
27759+
076b876e
AM
27760+ sz = sizeof(array) * *hint;
27761+ array = kzalloc(sz, GFP_NOFS);
7f207e10 27762+ if (unlikely(!array))
076b876e 27763+ array = vzalloc(sz);
7f207e10
AM
27764+ if (unlikely(!array)) {
27765+ array = ERR_PTR(-ENOMEM);
27766+ goto out;
27767+ }
27768+
79b8bda9 27769+ n = cb(sb, array, *hint, arg);
7f207e10
AM
27770+ AuDebugOn(n > *hint);
27771+
27772+out:
27773+ *hint = n;
27774+ return array;
27775+}
27776+
79b8bda9 27777+static unsigned long long au_iarray_cb(struct super_block *sb, void *a,
7f207e10
AM
27778+ unsigned long long max __maybe_unused,
27779+ void *arg)
27780+{
27781+ unsigned long long n;
27782+ struct inode **p, *inode;
27783+ struct list_head *head;
27784+
27785+ n = 0;
27786+ p = a;
27787+ head = arg;
79b8bda9 27788+ spin_lock(&sb->s_inode_list_lock);
7f207e10 27789+ list_for_each_entry(inode, head, i_sb_list) {
5afbbe0d
AM
27790+ if (!au_is_bad_inode(inode)
27791+ && au_ii(inode)->ii_btop >= 0) {
2cbb1c4b
JR
27792+ spin_lock(&inode->i_lock);
27793+ if (atomic_read(&inode->i_count)) {
27794+ au_igrab(inode);
27795+ *p++ = inode;
27796+ n++;
27797+ AuDebugOn(n > max);
27798+ }
27799+ spin_unlock(&inode->i_lock);
7f207e10
AM
27800+ }
27801+ }
79b8bda9 27802+ spin_unlock(&sb->s_inode_list_lock);
7f207e10
AM
27803+
27804+ return n;
27805+}
27806+
27807+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
27808+{
5afbbe0d 27809+ *max = au_ninodes(sb);
79b8bda9 27810+ return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes);
7f207e10
AM
27811+}
27812+
27813+void au_iarray_free(struct inode **a, unsigned long long max)
27814+{
27815+ unsigned long long ull;
27816+
27817+ for (ull = 0; ull < max; ull++)
27818+ iput(a[ull]);
be52b249 27819+ kvfree(a);
7f207e10
AM
27820+}
27821+
27822+/* ---------------------------------------------------------------------- */
27823+
1facf9fc 27824+/*
27825+ * refresh dentry and inode at remount time.
27826+ */
027c5e7a
AM
27827+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
27828+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
27829+ struct dentry *parent)
1facf9fc 27830+{
27831+ int err;
1facf9fc 27832+
27833+ di_write_lock_child(dentry);
1facf9fc 27834+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
27835+ err = au_refresh_dentry(dentry, parent);
27836+ if (!err && dir_flags)
5527c038 27837+ au_hn_reset(d_inode(dentry), dir_flags);
1facf9fc 27838+ di_read_unlock(parent, AuLock_IR);
1facf9fc 27839+ di_write_unlock(dentry);
27840+
27841+ return err;
27842+}
27843+
027c5e7a
AM
27844+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
27845+ struct au_sbinfo *sbinfo,
b95c5147 27846+ const unsigned int dir_flags, unsigned int do_idop)
1facf9fc 27847+{
027c5e7a
AM
27848+ int err;
27849+ struct dentry *parent;
027c5e7a
AM
27850+
27851+ err = 0;
27852+ parent = dget_parent(dentry);
27853+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
5527c038
JR
27854+ if (d_really_is_positive(dentry)) {
27855+ if (!d_is_dir(dentry))
027c5e7a
AM
27856+ err = au_do_refresh(dentry, /*dir_flags*/0,
27857+ parent);
27858+ else {
27859+ err = au_do_refresh(dentry, dir_flags, parent);
27860+ if (unlikely(err))
27861+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
27862+ }
27863+ } else
27864+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
27865+ AuDbgDentry(dentry);
27866+ }
27867+ dput(parent);
27868+
79b8bda9 27869+ if (!err) {
b95c5147 27870+ if (do_idop)
79b8bda9
AM
27871+ au_refresh_dop(dentry, /*force_reval*/0);
27872+ } else
27873+ au_refresh_dop(dentry, /*force_reval*/1);
27874+
027c5e7a
AM
27875+ AuTraceErr(err);
27876+ return err;
1facf9fc 27877+}
27878+
b95c5147 27879+static int au_refresh_d(struct super_block *sb, unsigned int do_idop)
1facf9fc 27880+{
27881+ int err, i, j, ndentry, e;
027c5e7a 27882+ unsigned int sigen;
1facf9fc 27883+ struct au_dcsub_pages dpages;
27884+ struct au_dpage *dpage;
027c5e7a
AM
27885+ struct dentry **dentries, *d;
27886+ struct au_sbinfo *sbinfo;
27887+ struct dentry *root = sb->s_root;
5527c038 27888+ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
1facf9fc 27889+
b95c5147 27890+ if (do_idop)
79b8bda9
AM
27891+ au_refresh_dop(root, /*force_reval*/0);
27892+
027c5e7a
AM
27893+ err = au_dpages_init(&dpages, GFP_NOFS);
27894+ if (unlikely(err))
1facf9fc 27895+ goto out;
027c5e7a
AM
27896+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
27897+ if (unlikely(err))
1facf9fc 27898+ goto out_dpages;
1facf9fc 27899+
027c5e7a
AM
27900+ sigen = au_sigen(sb);
27901+ sbinfo = au_sbi(sb);
27902+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 27903+ dpage = dpages.dpages + i;
27904+ dentries = dpage->dentries;
27905+ ndentry = dpage->ndentry;
027c5e7a 27906+ for (j = 0; j < ndentry; j++) {
1facf9fc 27907+ d = dentries[j];
79b8bda9 27908+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
b95c5147 27909+ do_idop);
027c5e7a
AM
27910+ if (unlikely(e && !err))
27911+ err = e;
27912+ /* go on even err */
1facf9fc 27913+ }
27914+ }
27915+
4f0767ce 27916+out_dpages:
1facf9fc 27917+ au_dpages_free(&dpages);
4f0767ce 27918+out:
1facf9fc 27919+ return err;
27920+}
27921+
b95c5147 27922+static int au_refresh_i(struct super_block *sb, unsigned int do_idop)
1facf9fc 27923+{
027c5e7a
AM
27924+ int err, e;
27925+ unsigned int sigen;
27926+ unsigned long long max, ull;
27927+ struct inode *inode, **array;
1facf9fc 27928+
027c5e7a
AM
27929+ array = au_iarray_alloc(sb, &max);
27930+ err = PTR_ERR(array);
27931+ if (IS_ERR(array))
27932+ goto out;
1facf9fc 27933+
27934+ err = 0;
027c5e7a
AM
27935+ sigen = au_sigen(sb);
27936+ for (ull = 0; ull < max; ull++) {
27937+ inode = array[ull];
076b876e
AM
27938+ if (unlikely(!inode))
27939+ break;
b95c5147
AM
27940+
27941+ e = 0;
27942+ ii_write_lock_child(inode);
537831f9 27943+ if (au_iigen(inode, NULL) != sigen) {
027c5e7a 27944+ e = au_refresh_hinode_self(inode);
1facf9fc 27945+ if (unlikely(e)) {
b95c5147 27946+ au_refresh_iop(inode, /*force_getattr*/1);
027c5e7a 27947+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 27948+ if (!err)
27949+ err = e;
27950+ /* go on even if err */
27951+ }
27952+ }
b95c5147
AM
27953+ if (!e && do_idop)
27954+ au_refresh_iop(inode, /*force_getattr*/0);
27955+ ii_write_unlock(inode);
1facf9fc 27956+ }
27957+
027c5e7a 27958+ au_iarray_free(array, max);
1facf9fc 27959+
4f0767ce 27960+out:
1facf9fc 27961+ return err;
27962+}
27963+
b95c5147 27964+static void au_remount_refresh(struct super_block *sb, unsigned int do_idop)
1facf9fc 27965+{
027c5e7a
AM
27966+ int err, e;
27967+ unsigned int udba;
5afbbe0d 27968+ aufs_bindex_t bindex, bbot;
1facf9fc 27969+ struct dentry *root;
27970+ struct inode *inode;
027c5e7a 27971+ struct au_branch *br;
79b8bda9 27972+ struct au_sbinfo *sbi;
1facf9fc 27973+
27974+ au_sigen_inc(sb);
79b8bda9
AM
27975+ sbi = au_sbi(sb);
27976+ au_fclr_si(sbi, FAILED_REFRESH_DIR);
1facf9fc 27977+
27978+ root = sb->s_root;
27979+ DiMustNoWaiters(root);
5527c038 27980+ inode = d_inode(root);
1facf9fc 27981+ IiMustNoWaiters(inode);
1facf9fc 27982+
027c5e7a 27983+ udba = au_opt_udba(sb);
5afbbe0d
AM
27984+ bbot = au_sbbot(sb);
27985+ for (bindex = 0; bindex <= bbot; bindex++) {
027c5e7a
AM
27986+ br = au_sbr(sb, bindex);
27987+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 27988+ if (unlikely(err))
027c5e7a
AM
27989+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
27990+ bindex, err);
27991+ /* go on even if err */
1facf9fc 27992+ }
027c5e7a 27993+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 27994+
b95c5147 27995+ if (do_idop) {
79b8bda9
AM
27996+ if (au_ftest_si(sbi, NO_DREVAL)) {
27997+ AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
27998+ sb->s_d_op = &aufs_dop_noreval;
b95c5147
AM
27999+ AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr);
28000+ sbi->si_iop_array = aufs_iop_nogetattr;
79b8bda9
AM
28001+ } else {
28002+ AuDebugOn(sb->s_d_op == &aufs_dop);
28003+ sb->s_d_op = &aufs_dop;
b95c5147
AM
28004+ AuDebugOn(sbi->si_iop_array == aufs_iop);
28005+ sbi->si_iop_array = aufs_iop;
79b8bda9 28006+ }
b95c5147
AM
28007+ pr_info("reset to %pf and %pf\n",
28008+ sb->s_d_op, sbi->si_iop_array);
79b8bda9
AM
28009+ }
28010+
027c5e7a 28011+ di_write_unlock(root);
b95c5147
AM
28012+ err = au_refresh_d(sb, do_idop);
28013+ e = au_refresh_i(sb, do_idop);
027c5e7a
AM
28014+ if (unlikely(e && !err))
28015+ err = e;
1facf9fc 28016+ /* aufs_write_lock() calls ..._child() */
28017+ di_write_lock_child(root);
027c5e7a
AM
28018+
28019+ au_cpup_attr_all(inode, /*force*/1);
28020+
28021+ if (unlikely(err))
28022+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 28023+}
28024+
28025+/* stop extra interpretation of errno in mount(8), and strange error messages */
28026+static int cvt_err(int err)
28027+{
28028+ AuTraceErr(err);
28029+
28030+ switch (err) {
28031+ case -ENOENT:
28032+ case -ENOTDIR:
28033+ case -EEXIST:
28034+ case -EIO:
28035+ err = -EINVAL;
28036+ }
28037+ return err;
28038+}
28039+
28040+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
28041+{
4a4d8108
AM
28042+ int err, do_dx;
28043+ unsigned int mntflags;
be52b249
AM
28044+ struct au_opts opts = {
28045+ .opt = NULL
28046+ };
1facf9fc 28047+ struct dentry *root;
28048+ struct inode *inode;
28049+ struct au_sbinfo *sbinfo;
28050+
28051+ err = 0;
28052+ root = sb->s_root;
28053+ if (!data || !*data) {
e49829fe
JR
28054+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
28055+ if (!err) {
28056+ di_write_lock_child(root);
28057+ err = au_opts_verify(sb, *flags, /*pending*/0);
28058+ aufs_write_unlock(root);
28059+ }
1facf9fc 28060+ goto out;
28061+ }
28062+
28063+ err = -ENOMEM;
1facf9fc 28064+ opts.opt = (void *)__get_free_page(GFP_NOFS);
28065+ if (unlikely(!opts.opt))
28066+ goto out;
28067+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
28068+ opts.flags = AuOpts_REMOUNT;
28069+ opts.sb_flags = *flags;
28070+
28071+ /* parse it before aufs lock */
28072+ err = au_opts_parse(sb, data, &opts);
28073+ if (unlikely(err))
28074+ goto out_opts;
28075+
28076+ sbinfo = au_sbi(sb);
5527c038 28077+ inode = d_inode(root);
febd17d6 28078+ inode_lock(inode);
e49829fe
JR
28079+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
28080+ if (unlikely(err))
28081+ goto out_mtx;
28082+ di_write_lock_child(root);
1facf9fc 28083+
28084+ /* au_opts_remount() may return an error */
28085+ err = au_opts_remount(sb, &opts);
28086+ au_opts_free(&opts);
28087+
027c5e7a 28088+ if (au_ftest_opts(opts.flags, REFRESH))
b95c5147 28089+ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP));
1facf9fc 28090+
4a4d8108
AM
28091+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
28092+ mntflags = au_mntflags(sb);
28093+ do_dx = !!au_opt_test(mntflags, DIO);
28094+ au_dy_arefresh(do_dx);
28095+ }
28096+
076b876e 28097+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
1facf9fc 28098+ aufs_write_unlock(root);
953406b4 28099+
e49829fe 28100+out_mtx:
febd17d6 28101+ inode_unlock(inode);
4f0767ce 28102+out_opts:
1c60b727 28103+ free_page((unsigned long)opts.opt);
4f0767ce 28104+out:
1facf9fc 28105+ err = cvt_err(err);
28106+ AuTraceErr(err);
28107+ return err;
28108+}
28109+
4a4d8108 28110+static const struct super_operations aufs_sop = {
1facf9fc 28111+ .alloc_inode = aufs_alloc_inode,
28112+ .destroy_inode = aufs_destroy_inode,
b752ccd1 28113+ /* always deleting, no clearing */
1facf9fc 28114+ .drop_inode = generic_delete_inode,
28115+ .show_options = aufs_show_options,
28116+ .statfs = aufs_statfs,
28117+ .put_super = aufs_put_super,
537831f9 28118+ .sync_fs = aufs_sync_fs,
1facf9fc 28119+ .remount_fs = aufs_remount_fs
28120+};
28121+
28122+/* ---------------------------------------------------------------------- */
28123+
28124+static int alloc_root(struct super_block *sb)
28125+{
28126+ int err;
28127+ struct inode *inode;
28128+ struct dentry *root;
28129+
28130+ err = -ENOMEM;
28131+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
28132+ err = PTR_ERR(inode);
28133+ if (IS_ERR(inode))
28134+ goto out;
28135+
b95c5147 28136+ inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */
1facf9fc 28137+ inode->i_fop = &aufs_dir_fop;
28138+ inode->i_mode = S_IFDIR;
9dbd164d 28139+ set_nlink(inode, 2);
1facf9fc 28140+ unlock_new_inode(inode);
28141+
92d182d2 28142+ root = d_make_root(inode);
1facf9fc 28143+ if (unlikely(!root))
92d182d2 28144+ goto out;
1facf9fc 28145+ err = PTR_ERR(root);
28146+ if (IS_ERR(root))
92d182d2 28147+ goto out;
1facf9fc 28148+
4a4d8108 28149+ err = au_di_init(root);
1facf9fc 28150+ if (!err) {
28151+ sb->s_root = root;
28152+ return 0; /* success */
28153+ }
28154+ dput(root);
1facf9fc 28155+
4f0767ce 28156+out:
1facf9fc 28157+ return err;
1facf9fc 28158+}
28159+
28160+static int aufs_fill_super(struct super_block *sb, void *raw_data,
28161+ int silent __maybe_unused)
28162+{
28163+ int err;
be52b249
AM
28164+ struct au_opts opts = {
28165+ .opt = NULL
28166+ };
79b8bda9 28167+ struct au_sbinfo *sbinfo;
1facf9fc 28168+ struct dentry *root;
28169+ struct inode *inode;
28170+ char *arg = raw_data;
28171+
28172+ if (unlikely(!arg || !*arg)) {
28173+ err = -EINVAL;
4a4d8108 28174+ pr_err("no arg\n");
1facf9fc 28175+ goto out;
28176+ }
28177+
28178+ err = -ENOMEM;
1facf9fc 28179+ opts.opt = (void *)__get_free_page(GFP_NOFS);
28180+ if (unlikely(!opts.opt))
28181+ goto out;
28182+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
28183+ opts.sb_flags = sb->s_flags;
28184+
28185+ err = au_si_alloc(sb);
28186+ if (unlikely(err))
28187+ goto out_opts;
79b8bda9 28188+ sbinfo = au_sbi(sb);
1facf9fc 28189+
28190+ /* all timestamps always follow the ones on the branch */
28191+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
28192+ sb->s_op = &aufs_sop;
027c5e7a 28193+ sb->s_d_op = &aufs_dop;
1facf9fc 28194+ sb->s_magic = AUFS_SUPER_MAGIC;
28195+ sb->s_maxbytes = 0;
c1595e42 28196+ sb->s_stack_depth = 1;
1facf9fc 28197+ au_export_init(sb);
f2c43d5f 28198+ au_xattr_init(sb);
1facf9fc 28199+
28200+ err = alloc_root(sb);
28201+ if (unlikely(err)) {
28202+ si_write_unlock(sb);
28203+ goto out_info;
28204+ }
28205+ root = sb->s_root;
5527c038 28206+ inode = d_inode(root);
1facf9fc 28207+
28208+ /*
28209+ * actually we can parse options regardless aufs lock here.
28210+ * but at remount time, parsing must be done before aufs lock.
28211+ * so we follow the same rule.
28212+ */
28213+ ii_write_lock_parent(inode);
28214+ aufs_write_unlock(root);
28215+ err = au_opts_parse(sb, arg, &opts);
28216+ if (unlikely(err))
28217+ goto out_root;
28218+
28219+ /* lock vfs_inode first, then aufs. */
febd17d6 28220+ inode_lock(inode);
1facf9fc 28221+ aufs_write_lock(root);
28222+ err = au_opts_mount(sb, &opts);
28223+ au_opts_free(&opts);
79b8bda9
AM
28224+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) {
28225+ sb->s_d_op = &aufs_dop_noreval;
28226+ pr_info("%pf\n", sb->s_d_op);
28227+ au_refresh_dop(root, /*force_reval*/0);
b95c5147
AM
28228+ sbinfo->si_iop_array = aufs_iop_nogetattr;
28229+ au_refresh_iop(inode, /*force_getattr*/0);
79b8bda9 28230+ }
1facf9fc 28231+ aufs_write_unlock(root);
febd17d6 28232+ inode_unlock(inode);
4a4d8108
AM
28233+ if (!err)
28234+ goto out_opts; /* success */
1facf9fc 28235+
4f0767ce 28236+out_root:
1facf9fc 28237+ dput(root);
28238+ sb->s_root = NULL;
4f0767ce 28239+out_info:
79b8bda9
AM
28240+ dbgaufs_si_fin(sbinfo);
28241+ kobject_put(&sbinfo->si_kobj);
1facf9fc 28242+ sb->s_fs_info = NULL;
4f0767ce 28243+out_opts:
1c60b727 28244+ free_page((unsigned long)opts.opt);
4f0767ce 28245+out:
1facf9fc 28246+ AuTraceErr(err);
28247+ err = cvt_err(err);
28248+ AuTraceErr(err);
28249+ return err;
28250+}
28251+
28252+/* ---------------------------------------------------------------------- */
28253+
027c5e7a
AM
28254+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
28255+ const char *dev_name __maybe_unused,
28256+ void *raw_data)
1facf9fc 28257+{
027c5e7a 28258+ struct dentry *root;
1facf9fc 28259+ struct super_block *sb;
28260+
28261+ /* all timestamps always follow the ones on the branch */
28262+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
28263+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
28264+ if (IS_ERR(root))
28265+ goto out;
28266+
28267+ sb = root->d_sb;
28268+ si_write_lock(sb, !AuLock_FLUSH);
28269+ sysaufs_brs_add(sb, 0);
28270+ si_write_unlock(sb);
28271+ au_sbilist_add(sb);
28272+
28273+out:
28274+ return root;
1facf9fc 28275+}
28276+
e49829fe
JR
28277+static void aufs_kill_sb(struct super_block *sb)
28278+{
28279+ struct au_sbinfo *sbinfo;
28280+
28281+ sbinfo = au_sbi(sb);
28282+ if (sbinfo) {
28283+ au_sbilist_del(sb);
28284+ aufs_write_lock(sb->s_root);
076b876e 28285+ au_fhsm_fin(sb);
e49829fe
JR
28286+ if (sbinfo->si_wbr_create_ops->fin)
28287+ sbinfo->si_wbr_create_ops->fin(sb);
28288+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
28289+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
b95c5147 28290+ au_remount_refresh(sb, /*do_idop*/0);
e49829fe
JR
28291+ }
28292+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
28293+ au_plink_put(sb, /*verbose*/1);
28294+ au_xino_clr(sb);
1e00d052 28295+ sbinfo->si_sb = NULL;
e49829fe 28296+ aufs_write_unlock(sb->s_root);
e49829fe
JR
28297+ au_nwt_flush(&sbinfo->si_nowait);
28298+ }
98d9a5b1 28299+ kill_anon_super(sb);
e49829fe
JR
28300+}
28301+
1facf9fc 28302+struct file_system_type aufs_fs_type = {
28303+ .name = AUFS_FSTYPE,
c06a8ce3
AM
28304+ /* a race between rename and others */
28305+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 28306+ .mount = aufs_mount,
e49829fe 28307+ .kill_sb = aufs_kill_sb,
1facf9fc 28308+ /* no need to __module_get() and module_put(). */
28309+ .owner = THIS_MODULE,
28310+};
7f207e10
AM
28311diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
28312--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 28313+++ linux/fs/aufs/super.h 2017-07-29 12:14:25.906375514 +0200
a2654f78 28314@@ -0,0 +1,617 @@
1facf9fc 28315+/*
a2654f78 28316+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 28317+ *
28318+ * This program, aufs is free software; you can redistribute it and/or modify
28319+ * it under the terms of the GNU General Public License as published by
28320+ * the Free Software Foundation; either version 2 of the License, or
28321+ * (at your option) any later version.
dece6358
AM
28322+ *
28323+ * This program is distributed in the hope that it will be useful,
28324+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28325+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28326+ * GNU General Public License for more details.
28327+ *
28328+ * You should have received a copy of the GNU General Public License
523b37e3 28329+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28330+ */
28331+
28332+/*
28333+ * super_block operations
28334+ */
28335+
28336+#ifndef __AUFS_SUPER_H__
28337+#define __AUFS_SUPER_H__
28338+
28339+#ifdef __KERNEL__
28340+
28341+#include <linux/fs.h>
5527c038 28342+#include <linux/kobject.h>
1facf9fc 28343+#include "rwsem.h"
28344+#include "spl.h"
28345+#include "wkq.h"
28346+
1facf9fc 28347+/* policies to select one among multiple writable branches */
28348+struct au_wbr_copyup_operations {
28349+ int (*copyup)(struct dentry *dentry);
28350+};
28351+
392086de
AM
28352+#define AuWbr_DIR 1 /* target is a dir */
28353+#define AuWbr_PARENT (1 << 1) /* always require a parent */
28354+
28355+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
28356+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
28357+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
28358+
1facf9fc 28359+struct au_wbr_create_operations {
392086de 28360+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 28361+ int (*init)(struct super_block *sb);
28362+ int (*fin)(struct super_block *sb);
28363+};
28364+
28365+struct au_wbr_mfs {
28366+ struct mutex mfs_lock; /* protect this structure */
28367+ unsigned long mfs_jiffy;
28368+ unsigned long mfs_expire;
28369+ aufs_bindex_t mfs_bindex;
28370+
28371+ unsigned long long mfsrr_bytes;
28372+ unsigned long long mfsrr_watermark;
28373+};
28374+
86dc4139
AM
28375+#define AuPlink_NHASH 100
28376+static inline int au_plink_hash(ino_t ino)
28377+{
28378+ return ino % AuPlink_NHASH;
28379+}
28380+
076b876e
AM
28381+/* File-based Hierarchical Storage Management */
28382+struct au_fhsm {
28383+#ifdef CONFIG_AUFS_FHSM
28384+ /* allow only one process who can receive the notification */
28385+ spinlock_t fhsm_spin;
28386+ pid_t fhsm_pid;
28387+ wait_queue_head_t fhsm_wqh;
28388+ atomic_t fhsm_readable;
28389+
c1595e42 28390+ /* these are protected by si_rwsem */
076b876e 28391+ unsigned long fhsm_expire;
c1595e42 28392+ aufs_bindex_t fhsm_bottom;
076b876e
AM
28393+#endif
28394+};
28395+
1facf9fc 28396+struct au_branch;
28397+struct au_sbinfo {
28398+ /* nowait tasks in the system-wide workqueue */
28399+ struct au_nowait_tasks si_nowait;
28400+
b752ccd1
AM
28401+ /*
28402+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
28403+ * rwsem for au_sbinfo is necessary.
28404+ */
dece6358 28405+ struct au_rwsem si_rwsem;
1facf9fc 28406+
7f207e10 28407+ /*
523b37e3
AM
28408+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
28409+ * remount.
7f207e10 28410+ */
5afbbe0d 28411+ struct percpu_counter si_ninodes, si_nfiles;
7f207e10 28412+
1facf9fc 28413+ /* branch management */
28414+ unsigned int si_generation;
28415+
2000de60 28416+ /* see AuSi_ flags */
1facf9fc 28417+ unsigned char au_si_status;
28418+
5afbbe0d 28419+ aufs_bindex_t si_bbot;
7f207e10
AM
28420+
28421+ /* dirty trick to keep br_id plus */
28422+ unsigned int si_last_br_id :
28423+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 28424+ struct au_branch **si_branch;
28425+
28426+ /* policy to select a writable branch */
28427+ unsigned char si_wbr_copyup;
28428+ unsigned char si_wbr_create;
28429+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
28430+ struct au_wbr_create_operations *si_wbr_create_ops;
28431+
28432+ /* round robin */
28433+ atomic_t si_wbr_rr_next;
28434+
28435+ /* most free space */
28436+ struct au_wbr_mfs si_wbr_mfs;
28437+
076b876e
AM
28438+ /* File-based Hierarchical Storage Management */
28439+ struct au_fhsm si_fhsm;
28440+
1facf9fc 28441+ /* mount flags */
28442+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
28443+ unsigned int si_mntflags;
28444+
28445+ /* external inode number (bitmap and translation table) */
5527c038
JR
28446+ vfs_readf_t si_xread;
28447+ vfs_writef_t si_xwrite;
1facf9fc 28448+ struct file *si_xib;
28449+ struct mutex si_xib_mtx; /* protect xib members */
28450+ unsigned long *si_xib_buf;
28451+ unsigned long si_xib_last_pindex;
28452+ int si_xib_next_bit;
28453+ aufs_bindex_t si_xino_brid;
392086de
AM
28454+ unsigned long si_xino_jiffy;
28455+ unsigned long si_xino_expire;
1facf9fc 28456+ /* reserved for future use */
28457+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
28458+
28459+#ifdef CONFIG_AUFS_EXPORT
28460+ /* i_generation */
28461+ struct file *si_xigen;
28462+ atomic_t si_xigen_next;
28463+#endif
28464+
b912730e
AM
28465+ /* dirty trick to suppoer atomic_open */
28466+ struct au_sphlhead si_aopen;
28467+
1facf9fc 28468+ /* vdir parameters */
e49829fe 28469+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 28470+ unsigned int si_rdblk; /* deblk size */
28471+ unsigned int si_rdhash; /* hash size */
28472+
28473+ /*
28474+ * If the number of whiteouts are larger than si_dirwh, leave all of
28475+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
28476+ * future fsck.aufs or kernel thread will remove them later.
28477+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
28478+ */
28479+ unsigned int si_dirwh;
28480+
1facf9fc 28481+ /* pseudo_link list */
86dc4139 28482+ struct au_sphlhead si_plink[AuPlink_NHASH];
1facf9fc 28483+ wait_queue_head_t si_plink_wq;
4a4d8108 28484+ spinlock_t si_plink_maint_lock;
e49829fe 28485+ pid_t si_plink_maint_pid;
1facf9fc 28486+
523b37e3
AM
28487+ /* file list */
28488+ struct au_sphlhead si_files;
28489+
b95c5147
AM
28490+ /* with/without getattr, brother of sb->s_d_op */
28491+ struct inode_operations *si_iop_array;
28492+
1facf9fc 28493+ /*
28494+ * sysfs and lifetime management.
28495+ * this is not a small structure and it may be a waste of memory in case
28496+ * of sysfs is disabled, particulary when many aufs-es are mounted.
28497+ * but using sysfs is majority.
28498+ */
28499+ struct kobject si_kobj;
28500+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
28501+ struct dentry *si_dbgaufs;
28502+ struct dentry *si_dbgaufs_plink;
28503+ struct dentry *si_dbgaufs_xib;
1facf9fc 28504+#ifdef CONFIG_AUFS_EXPORT
28505+ struct dentry *si_dbgaufs_xigen;
28506+#endif
28507+#endif
28508+
e49829fe 28509+#ifdef CONFIG_AUFS_SBILIST
5afbbe0d 28510+ struct hlist_node si_list;
e49829fe
JR
28511+#endif
28512+
1facf9fc 28513+ /* dirty, necessary for unmounting, sysfs and sysrq */
28514+ struct super_block *si_sb;
28515+};
28516+
dece6358
AM
28517+/* sbinfo status flags */
28518+/*
28519+ * set true when refresh_dirs() failed at remount time.
28520+ * then try refreshing dirs at access time again.
28521+ * if it is false, refreshing dirs at access time is unnecesary
28522+ */
027c5e7a 28523+#define AuSi_FAILED_REFRESH_DIR 1
076b876e 28524+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
79b8bda9 28525+#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */
076b876e
AM
28526+
28527+#ifndef CONFIG_AUFS_FHSM
28528+#undef AuSi_FHSM
28529+#define AuSi_FHSM 0
28530+#endif
28531+
dece6358
AM
28532+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
28533+ unsigned int flag)
28534+{
28535+ AuRwMustAnyLock(&sbi->si_rwsem);
28536+ return sbi->au_si_status & flag;
28537+}
28538+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
28539+#define au_fset_si(sbinfo, name) do { \
28540+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
28541+ (sbinfo)->au_si_status |= AuSi_##name; \
28542+} while (0)
28543+#define au_fclr_si(sbinfo, name) do { \
28544+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
28545+ (sbinfo)->au_si_status &= ~AuSi_##name; \
28546+} while (0)
28547+
1facf9fc 28548+/* ---------------------------------------------------------------------- */
28549+
28550+/* policy to select one among writable branches */
4a4d8108
AM
28551+#define AuWbrCopyup(sbinfo, ...) \
28552+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
28553+#define AuWbrCreate(sbinfo, ...) \
28554+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 28555+
28556+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
28557+#define AuLock_DW 1 /* write-lock dentry */
28558+#define AuLock_IR (1 << 1) /* read-lock inode */
28559+#define AuLock_IW (1 << 2) /* write-lock inode */
28560+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
b95c5147 28561+#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */
f2c43d5f 28562+ /* except RENAME_EXCHANGE */
e49829fe
JR
28563+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
28564+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 28565+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 28566+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
28567+#define au_fset_lock(flags, name) \
28568+ do { (flags) |= AuLock_##name; } while (0)
28569+#define au_fclr_lock(flags, name) \
28570+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 28571+
28572+/* ---------------------------------------------------------------------- */
28573+
28574+/* super.c */
28575+extern struct file_system_type aufs_fs_type;
28576+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
79b8bda9
AM
28577+typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array,
28578+ unsigned long long max, void *arg);
79b8bda9
AM
28579+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
28580+ struct super_block *sb, void *arg);
7f207e10
AM
28581+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
28582+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 28583+
28584+/* sbinfo.c */
28585+void au_si_free(struct kobject *kobj);
28586+int au_si_alloc(struct super_block *sb);
e2f27e51 28587+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink);
1facf9fc 28588+
28589+unsigned int au_sigen_inc(struct super_block *sb);
28590+aufs_bindex_t au_new_br_id(struct super_block *sb);
28591+
e49829fe
JR
28592+int si_read_lock(struct super_block *sb, int flags);
28593+int si_write_lock(struct super_block *sb, int flags);
28594+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 28595+void aufs_read_unlock(struct dentry *dentry, int flags);
28596+void aufs_write_lock(struct dentry *dentry);
28597+void aufs_write_unlock(struct dentry *dentry);
e49829fe 28598+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 28599+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
28600+
28601+/* wbr_policy.c */
28602+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
28603+extern struct au_wbr_create_operations au_wbr_create_ops[];
28604+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2 28605+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
5afbbe0d 28606+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop);
c2b27bf2
AM
28607+
28608+/* mvdown.c */
28609+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 28610+
076b876e
AM
28611+#ifdef CONFIG_AUFS_FHSM
28612+/* fhsm.c */
28613+
28614+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
28615+{
28616+ pid_t pid;
28617+
28618+ spin_lock(&fhsm->fhsm_spin);
28619+ pid = fhsm->fhsm_pid;
28620+ spin_unlock(&fhsm->fhsm_spin);
28621+
28622+ return pid;
28623+}
28624+
28625+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
28626+void au_fhsm_wrote_all(struct super_block *sb, int force);
28627+int au_fhsm_fd(struct super_block *sb, int oflags);
28628+int au_fhsm_br_alloc(struct au_branch *br);
c1595e42 28629+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
076b876e
AM
28630+void au_fhsm_fin(struct super_block *sb);
28631+void au_fhsm_init(struct au_sbinfo *sbinfo);
28632+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
28633+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
28634+#else
28635+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
28636+ int force)
28637+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
28638+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
c1595e42
JR
28639+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
28640+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
28641+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
076b876e
AM
28642+AuStubVoid(au_fhsm_fin, struct super_block *sb)
28643+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
28644+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
28645+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
28646+#endif
28647+
1facf9fc 28648+/* ---------------------------------------------------------------------- */
28649+
28650+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
28651+{
28652+ return sb->s_fs_info;
28653+}
28654+
28655+/* ---------------------------------------------------------------------- */
28656+
28657+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 28658+int au_test_nfsd(void);
1facf9fc 28659+void au_export_init(struct super_block *sb);
b752ccd1 28660+void au_xigen_inc(struct inode *inode);
1facf9fc 28661+int au_xigen_new(struct inode *inode);
28662+int au_xigen_set(struct super_block *sb, struct file *base);
28663+void au_xigen_clr(struct super_block *sb);
28664+
28665+static inline int au_busy_or_stale(void)
28666+{
b752ccd1 28667+ if (!au_test_nfsd())
1facf9fc 28668+ return -EBUSY;
28669+ return -ESTALE;
28670+}
28671+#else
b752ccd1 28672+AuStubInt0(au_test_nfsd, void)
a2a7ad62 28673+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 28674+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
28675+AuStubInt0(au_xigen_new, struct inode *inode)
28676+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
28677+AuStubVoid(au_xigen_clr, struct super_block *sb)
c1595e42 28678+AuStub(int, au_busy_or_stale, return -EBUSY, void)
1facf9fc 28679+#endif /* CONFIG_AUFS_EXPORT */
28680+
28681+/* ---------------------------------------------------------------------- */
28682+
e49829fe
JR
28683+#ifdef CONFIG_AUFS_SBILIST
28684+/* module.c */
5afbbe0d 28685+extern struct au_sphlhead au_sbilist;
e49829fe
JR
28686+
28687+static inline void au_sbilist_init(void)
28688+{
5afbbe0d 28689+ au_sphl_init(&au_sbilist);
e49829fe
JR
28690+}
28691+
28692+static inline void au_sbilist_add(struct super_block *sb)
28693+{
5afbbe0d 28694+ au_sphl_add(&au_sbi(sb)->si_list, &au_sbilist);
e49829fe
JR
28695+}
28696+
28697+static inline void au_sbilist_del(struct super_block *sb)
28698+{
5afbbe0d 28699+ au_sphl_del(&au_sbi(sb)->si_list, &au_sbilist);
e49829fe 28700+}
53392da6
AM
28701+
28702+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
28703+static inline void au_sbilist_lock(void)
28704+{
28705+ spin_lock(&au_sbilist.spin);
28706+}
28707+
28708+static inline void au_sbilist_unlock(void)
28709+{
28710+ spin_unlock(&au_sbilist.spin);
28711+}
28712+#define AuGFP_SBILIST GFP_ATOMIC
28713+#else
28714+AuStubVoid(au_sbilist_lock, void)
28715+AuStubVoid(au_sbilist_unlock, void)
28716+#define AuGFP_SBILIST GFP_NOFS
28717+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
28718+#else
28719+AuStubVoid(au_sbilist_init, void)
c1595e42
JR
28720+AuStubVoid(au_sbilist_add, struct super_block *sb)
28721+AuStubVoid(au_sbilist_del, struct super_block *sb)
53392da6
AM
28722+AuStubVoid(au_sbilist_lock, void)
28723+AuStubVoid(au_sbilist_unlock, void)
28724+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
28725+#endif
28726+
28727+/* ---------------------------------------------------------------------- */
28728+
1facf9fc 28729+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
28730+{
dece6358 28731+ /*
c1595e42 28732+ * This function is a dynamic '__init' function actually,
dece6358
AM
28733+ * so the tiny check for si_rwsem is unnecessary.
28734+ */
28735+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 28736+#ifdef CONFIG_DEBUG_FS
28737+ sbinfo->si_dbgaufs = NULL;
86dc4139 28738+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 28739+ sbinfo->si_dbgaufs_xib = NULL;
28740+#ifdef CONFIG_AUFS_EXPORT
28741+ sbinfo->si_dbgaufs_xigen = NULL;
28742+#endif
28743+#endif
28744+}
28745+
28746+/* ---------------------------------------------------------------------- */
28747+
a2654f78
AM
28748+/* current->atomic_flags */
28749+/* this value should never corrupt the ones defined in linux/sched.h */
28750+#define PFA_AUFS 7
28751+
28752+TASK_PFA_TEST(AUFS, test_aufs) /* task_test_aufs */
28753+TASK_PFA_SET(AUFS, aufs) /* task_set_aufs */
28754+TASK_PFA_CLEAR(AUFS, aufs) /* task_clear_aufs */
b752ccd1
AM
28755+
28756+static inline int si_pid_test(struct super_block *sb)
28757+{
a2654f78 28758+ return !!task_test_aufs(current);
b752ccd1
AM
28759+}
28760+
28761+static inline void si_pid_clr(struct super_block *sb)
28762+{
a2654f78
AM
28763+ AuDebugOn(!task_test_aufs(current));
28764+ task_clear_aufs(current);
b752ccd1
AM
28765+}
28766+
a2654f78
AM
28767+static inline void si_pid_set(struct super_block *sb)
28768+{
28769+ AuDebugOn(task_test_aufs(current));
28770+ task_set_aufs(current);
28771+}
febd17d6 28772+
b752ccd1
AM
28773+/* ---------------------------------------------------------------------- */
28774+
1facf9fc 28775+/* lock superblock. mainly for entry point functions */
28776+/*
b752ccd1
AM
28777+ * __si_read_lock, __si_write_lock,
28778+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 28779+ */
b752ccd1 28780+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 28781+
dece6358
AM
28782+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
28783+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
28784+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
28785+
b752ccd1
AM
28786+static inline void si_noflush_read_lock(struct super_block *sb)
28787+{
28788+ __si_read_lock(sb);
28789+ si_pid_set(sb);
28790+}
28791+
28792+static inline int si_noflush_read_trylock(struct super_block *sb)
28793+{
076b876e
AM
28794+ int locked;
28795+
28796+ locked = __si_read_trylock(sb);
b752ccd1
AM
28797+ if (locked)
28798+ si_pid_set(sb);
28799+ return locked;
28800+}
28801+
28802+static inline void si_noflush_write_lock(struct super_block *sb)
28803+{
28804+ __si_write_lock(sb);
28805+ si_pid_set(sb);
28806+}
28807+
28808+static inline int si_noflush_write_trylock(struct super_block *sb)
28809+{
076b876e
AM
28810+ int locked;
28811+
28812+ locked = __si_write_trylock(sb);
b752ccd1
AM
28813+ if (locked)
28814+ si_pid_set(sb);
28815+ return locked;
28816+}
28817+
7e9cd9fe 28818+#if 0 /* reserved */
1facf9fc 28819+static inline int si_read_trylock(struct super_block *sb, int flags)
28820+{
28821+ if (au_ftest_lock(flags, FLUSH))
28822+ au_nwt_flush(&au_sbi(sb)->si_nowait);
28823+ return si_noflush_read_trylock(sb);
28824+}
e49829fe 28825+#endif
1facf9fc 28826+
b752ccd1
AM
28827+static inline void si_read_unlock(struct super_block *sb)
28828+{
28829+ si_pid_clr(sb);
28830+ __si_read_unlock(sb);
28831+}
28832+
7e9cd9fe 28833+#if 0 /* reserved */
1facf9fc 28834+static inline int si_write_trylock(struct super_block *sb, int flags)
28835+{
28836+ if (au_ftest_lock(flags, FLUSH))
28837+ au_nwt_flush(&au_sbi(sb)->si_nowait);
28838+ return si_noflush_write_trylock(sb);
28839+}
b752ccd1
AM
28840+#endif
28841+
28842+static inline void si_write_unlock(struct super_block *sb)
28843+{
28844+ si_pid_clr(sb);
28845+ __si_write_unlock(sb);
28846+}
28847+
7e9cd9fe 28848+#if 0 /* reserved */
b752ccd1
AM
28849+static inline void si_downgrade_lock(struct super_block *sb)
28850+{
28851+ __si_downgrade_lock(sb);
28852+}
28853+#endif
1facf9fc 28854+
28855+/* ---------------------------------------------------------------------- */
28856+
5afbbe0d 28857+static inline aufs_bindex_t au_sbbot(struct super_block *sb)
1facf9fc 28858+{
dece6358 28859+ SiMustAnyLock(sb);
5afbbe0d 28860+ return au_sbi(sb)->si_bbot;
1facf9fc 28861+}
28862+
28863+static inline unsigned int au_mntflags(struct super_block *sb)
28864+{
dece6358 28865+ SiMustAnyLock(sb);
1facf9fc 28866+ return au_sbi(sb)->si_mntflags;
28867+}
28868+
28869+static inline unsigned int au_sigen(struct super_block *sb)
28870+{
dece6358 28871+ SiMustAnyLock(sb);
1facf9fc 28872+ return au_sbi(sb)->si_generation;
28873+}
28874+
5afbbe0d
AM
28875+static inline unsigned long long au_ninodes(struct super_block *sb)
28876+{
28877+ s64 n = percpu_counter_sum(&au_sbi(sb)->si_ninodes);
28878+
28879+ BUG_ON(n < 0);
28880+ return n;
28881+}
28882+
7f207e10
AM
28883+static inline void au_ninodes_inc(struct super_block *sb)
28884+{
5afbbe0d 28885+ percpu_counter_inc(&au_sbi(sb)->si_ninodes);
7f207e10
AM
28886+}
28887+
28888+static inline void au_ninodes_dec(struct super_block *sb)
28889+{
5afbbe0d
AM
28890+ percpu_counter_dec(&au_sbi(sb)->si_ninodes);
28891+}
28892+
28893+static inline unsigned long long au_nfiles(struct super_block *sb)
28894+{
28895+ s64 n = percpu_counter_sum(&au_sbi(sb)->si_nfiles);
28896+
28897+ BUG_ON(n < 0);
28898+ return n;
7f207e10
AM
28899+}
28900+
28901+static inline void au_nfiles_inc(struct super_block *sb)
28902+{
5afbbe0d 28903+ percpu_counter_inc(&au_sbi(sb)->si_nfiles);
7f207e10
AM
28904+}
28905+
28906+static inline void au_nfiles_dec(struct super_block *sb)
28907+{
5afbbe0d 28908+ percpu_counter_dec(&au_sbi(sb)->si_nfiles);
7f207e10
AM
28909+}
28910+
1facf9fc 28911+static inline struct au_branch *au_sbr(struct super_block *sb,
28912+ aufs_bindex_t bindex)
28913+{
dece6358 28914+ SiMustAnyLock(sb);
1facf9fc 28915+ return au_sbi(sb)->si_branch[0 + bindex];
28916+}
28917+
28918+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
28919+{
dece6358 28920+ SiMustWriteLock(sb);
1facf9fc 28921+ au_sbi(sb)->si_xino_brid = brid;
28922+}
28923+
28924+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
28925+{
dece6358 28926+ SiMustAnyLock(sb);
1facf9fc 28927+ return au_sbi(sb)->si_xino_brid;
28928+}
28929+
28930+#endif /* __KERNEL__ */
28931+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
28932diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
28933--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 28934+++ linux/fs/aufs/sysaufs.c 2017-07-29 12:14:25.906375514 +0200
523b37e3 28935@@ -0,0 +1,104 @@
1facf9fc 28936+/*
a2654f78 28937+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 28938+ *
28939+ * This program, aufs is free software; you can redistribute it and/or modify
28940+ * it under the terms of the GNU General Public License as published by
28941+ * the Free Software Foundation; either version 2 of the License, or
28942+ * (at your option) any later version.
dece6358
AM
28943+ *
28944+ * This program is distributed in the hope that it will be useful,
28945+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28946+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28947+ * GNU General Public License for more details.
28948+ *
28949+ * You should have received a copy of the GNU General Public License
523b37e3 28950+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28951+ */
28952+
28953+/*
28954+ * sysfs interface and lifetime management
28955+ * they are necessary regardless sysfs is disabled.
28956+ */
28957+
1facf9fc 28958+#include <linux/random.h>
1facf9fc 28959+#include "aufs.h"
28960+
28961+unsigned long sysaufs_si_mask;
e49829fe 28962+struct kset *sysaufs_kset;
1facf9fc 28963+
28964+#define AuSiAttr(_name) { \
28965+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
28966+ .show = sysaufs_si_##_name, \
28967+}
28968+
28969+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
28970+struct attribute *sysaufs_si_attrs[] = {
28971+ &sysaufs_si_attr_xi_path.attr,
28972+ NULL,
28973+};
28974+
4a4d8108 28975+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 28976+ .show = sysaufs_si_show
28977+};
28978+
28979+static struct kobj_type au_sbi_ktype = {
28980+ .release = au_si_free,
28981+ .sysfs_ops = &au_sbi_ops,
28982+ .default_attrs = sysaufs_si_attrs
28983+};
28984+
28985+/* ---------------------------------------------------------------------- */
28986+
28987+int sysaufs_si_init(struct au_sbinfo *sbinfo)
28988+{
28989+ int err;
28990+
e49829fe 28991+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 28992+ /* cf. sysaufs_name() */
28993+ err = kobject_init_and_add
e49829fe 28994+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 28995+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
28996+
28997+ dbgaufs_si_null(sbinfo);
28998+ if (!err) {
28999+ err = dbgaufs_si_init(sbinfo);
29000+ if (unlikely(err))
29001+ kobject_put(&sbinfo->si_kobj);
29002+ }
29003+ return err;
29004+}
29005+
29006+void sysaufs_fin(void)
29007+{
29008+ dbgaufs_fin();
e49829fe
JR
29009+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
29010+ kset_unregister(sysaufs_kset);
1facf9fc 29011+}
29012+
29013+int __init sysaufs_init(void)
29014+{
29015+ int err;
29016+
29017+ do {
29018+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
29019+ } while (!sysaufs_si_mask);
29020+
4a4d8108 29021+ err = -EINVAL;
e49829fe
JR
29022+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
29023+ if (unlikely(!sysaufs_kset))
4a4d8108 29024+ goto out;
e49829fe
JR
29025+ err = PTR_ERR(sysaufs_kset);
29026+ if (IS_ERR(sysaufs_kset))
1facf9fc 29027+ goto out;
e49829fe 29028+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 29029+ if (unlikely(err)) {
e49829fe 29030+ kset_unregister(sysaufs_kset);
1facf9fc 29031+ goto out;
29032+ }
29033+
29034+ err = dbgaufs_init();
29035+ if (unlikely(err))
29036+ sysaufs_fin();
4f0767ce 29037+out:
1facf9fc 29038+ return err;
29039+}
7f207e10
AM
29040diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
29041--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 29042+++ linux/fs/aufs/sysaufs.h 2017-07-29 12:14:25.906375514 +0200
c1595e42 29043@@ -0,0 +1,101 @@
1facf9fc 29044+/*
a2654f78 29045+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 29046+ *
29047+ * This program, aufs is free software; you can redistribute it and/or modify
29048+ * it under the terms of the GNU General Public License as published by
29049+ * the Free Software Foundation; either version 2 of the License, or
29050+ * (at your option) any later version.
dece6358
AM
29051+ *
29052+ * This program is distributed in the hope that it will be useful,
29053+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29054+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29055+ * GNU General Public License for more details.
29056+ *
29057+ * You should have received a copy of the GNU General Public License
523b37e3 29058+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29059+ */
29060+
29061+/*
29062+ * sysfs interface and mount lifetime management
29063+ */
29064+
29065+#ifndef __SYSAUFS_H__
29066+#define __SYSAUFS_H__
29067+
29068+#ifdef __KERNEL__
29069+
1facf9fc 29070+#include <linux/sysfs.h>
1facf9fc 29071+#include "module.h"
29072+
dece6358
AM
29073+struct super_block;
29074+struct au_sbinfo;
29075+
1facf9fc 29076+struct sysaufs_si_attr {
29077+ struct attribute attr;
29078+ int (*show)(struct seq_file *seq, struct super_block *sb);
29079+};
29080+
29081+/* ---------------------------------------------------------------------- */
29082+
29083+/* sysaufs.c */
29084+extern unsigned long sysaufs_si_mask;
e49829fe 29085+extern struct kset *sysaufs_kset;
1facf9fc 29086+extern struct attribute *sysaufs_si_attrs[];
29087+int sysaufs_si_init(struct au_sbinfo *sbinfo);
29088+int __init sysaufs_init(void);
29089+void sysaufs_fin(void);
29090+
29091+/* ---------------------------------------------------------------------- */
29092+
29093+/* some people doesn't like to show a pointer in kernel */
29094+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
29095+{
29096+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
29097+}
29098+
29099+#define SysaufsSiNamePrefix "si_"
29100+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
29101+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
29102+{
29103+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
29104+ sysaufs_si_id(sbinfo));
29105+}
29106+
29107+struct au_branch;
29108+#ifdef CONFIG_SYSFS
29109+/* sysfs.c */
29110+extern struct attribute_group *sysaufs_attr_group;
29111+
29112+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
29113+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
29114+ char *buf);
076b876e
AM
29115+long au_brinfo_ioctl(struct file *file, unsigned long arg);
29116+#ifdef CONFIG_COMPAT
29117+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
29118+#endif
1facf9fc 29119+
29120+void sysaufs_br_init(struct au_branch *br);
29121+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
29122+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
29123+
29124+#define sysaufs_brs_init() do {} while (0)
29125+
29126+#else
29127+#define sysaufs_attr_group NULL
29128+
4a4d8108 29129+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
c1595e42
JR
29130+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
29131+ struct attribute *attr, char *buf)
4a4d8108
AM
29132+AuStubVoid(sysaufs_br_init, struct au_branch *br)
29133+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
29134+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 29135+
29136+static inline void sysaufs_brs_init(void)
29137+{
29138+ sysaufs_brs = 0;
29139+}
29140+
29141+#endif /* CONFIG_SYSFS */
29142+
29143+#endif /* __KERNEL__ */
29144+#endif /* __SYSAUFS_H__ */
7f207e10
AM
29145diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
29146--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 29147+++ linux/fs/aufs/sysfs.c 2017-07-29 12:14:25.906375514 +0200
79b8bda9 29148@@ -0,0 +1,376 @@
1facf9fc 29149+/*
a2654f78 29150+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 29151+ *
29152+ * This program, aufs is free software; you can redistribute it and/or modify
29153+ * it under the terms of the GNU General Public License as published by
29154+ * the Free Software Foundation; either version 2 of the License, or
29155+ * (at your option) any later version.
dece6358
AM
29156+ *
29157+ * This program is distributed in the hope that it will be useful,
29158+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29159+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29160+ * GNU General Public License for more details.
29161+ *
29162+ * You should have received a copy of the GNU General Public License
523b37e3 29163+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29164+ */
29165+
29166+/*
29167+ * sysfs interface
29168+ */
29169+
076b876e 29170+#include <linux/compat.h>
1facf9fc 29171+#include <linux/seq_file.h>
1facf9fc 29172+#include "aufs.h"
29173+
4a4d8108
AM
29174+#ifdef CONFIG_AUFS_FS_MODULE
29175+/* this entry violates the "one line per file" policy of sysfs */
29176+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
29177+ char *buf)
29178+{
29179+ ssize_t err;
29180+ static char *conf =
29181+/* this file is generated at compiling */
29182+#include "conf.str"
29183+ ;
29184+
29185+ err = snprintf(buf, PAGE_SIZE, conf);
29186+ if (unlikely(err >= PAGE_SIZE))
29187+ err = -EFBIG;
29188+ return err;
29189+}
29190+
29191+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
29192+#endif
29193+
1facf9fc 29194+static struct attribute *au_attr[] = {
4a4d8108
AM
29195+#ifdef CONFIG_AUFS_FS_MODULE
29196+ &au_config_attr.attr,
29197+#endif
1facf9fc 29198+ NULL, /* need to NULL terminate the list of attributes */
29199+};
29200+
29201+static struct attribute_group sysaufs_attr_group_body = {
29202+ .attrs = au_attr
29203+};
29204+
29205+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
29206+
29207+/* ---------------------------------------------------------------------- */
29208+
29209+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
29210+{
29211+ int err;
29212+
dece6358
AM
29213+ SiMustAnyLock(sb);
29214+
1facf9fc 29215+ err = 0;
29216+ if (au_opt_test(au_mntflags(sb), XINO)) {
29217+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
29218+ seq_putc(seq, '\n');
29219+ }
29220+ return err;
29221+}
29222+
29223+/*
29224+ * the lifetime of branch is independent from the entry under sysfs.
29225+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
29226+ * unlinked.
29227+ */
29228+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 29229+ aufs_bindex_t bindex, int idx)
1facf9fc 29230+{
1e00d052 29231+ int err;
1facf9fc 29232+ struct path path;
29233+ struct dentry *root;
29234+ struct au_branch *br;
076b876e 29235+ au_br_perm_str_t perm;
1facf9fc 29236+
29237+ AuDbg("b%d\n", bindex);
29238+
1e00d052 29239+ err = 0;
1facf9fc 29240+ root = sb->s_root;
29241+ di_read_lock_parent(root, !AuLock_IR);
29242+ br = au_sbr(sb, bindex);
392086de
AM
29243+
29244+ switch (idx) {
29245+ case AuBrSysfs_BR:
29246+ path.mnt = au_br_mnt(br);
29247+ path.dentry = au_h_dptr(root, bindex);
79b8bda9
AM
29248+ err = au_seq_path(seq, &path);
29249+ if (!err) {
29250+ au_optstr_br_perm(&perm, br->br_perm);
29251+ seq_printf(seq, "=%s\n", perm.a);
29252+ }
392086de
AM
29253+ break;
29254+ case AuBrSysfs_BRID:
79b8bda9 29255+ seq_printf(seq, "%d\n", br->br_id);
392086de
AM
29256+ break;
29257+ }
076b876e 29258+ di_read_unlock(root, !AuLock_IR);
79b8bda9 29259+ if (unlikely(err || seq_has_overflowed(seq)))
076b876e 29260+ err = -E2BIG;
392086de 29261+
1e00d052 29262+ return err;
1facf9fc 29263+}
29264+
29265+/* ---------------------------------------------------------------------- */
29266+
29267+static struct seq_file *au_seq(char *p, ssize_t len)
29268+{
29269+ struct seq_file *seq;
29270+
29271+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
29272+ if (seq) {
29273+ /* mutex_init(&seq.lock); */
29274+ seq->buf = p;
29275+ seq->size = len;
29276+ return seq; /* success */
29277+ }
29278+
29279+ seq = ERR_PTR(-ENOMEM);
29280+ return seq;
29281+}
29282+
392086de
AM
29283+#define SysaufsBr_PREFIX "br"
29284+#define SysaufsBrid_PREFIX "brid"
1facf9fc 29285+
29286+/* todo: file size may exceed PAGE_SIZE */
29287+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 29288+ char *buf)
1facf9fc 29289+{
29290+ ssize_t err;
392086de 29291+ int idx;
1facf9fc 29292+ long l;
5afbbe0d 29293+ aufs_bindex_t bbot;
1facf9fc 29294+ struct au_sbinfo *sbinfo;
29295+ struct super_block *sb;
29296+ struct seq_file *seq;
29297+ char *name;
29298+ struct attribute **cattr;
29299+
29300+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
29301+ sb = sbinfo->si_sb;
1308ab2a 29302+
29303+ /*
29304+ * prevent a race condition between sysfs and aufs.
29305+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
29306+ * prohibits maintaining the sysfs entries.
29307+ * hew we acquire read lock after sysfs_get_active_two().
29308+ * on the other hand, the remount process may maintain the sysfs/aufs
29309+ * entries after acquiring write lock.
29310+ * it can cause a deadlock.
29311+ * simply we gave up processing read here.
29312+ */
29313+ err = -EBUSY;
29314+ if (unlikely(!si_noflush_read_trylock(sb)))
29315+ goto out;
1facf9fc 29316+
29317+ seq = au_seq(buf, PAGE_SIZE);
29318+ err = PTR_ERR(seq);
29319+ if (IS_ERR(seq))
1308ab2a 29320+ goto out_unlock;
1facf9fc 29321+
29322+ name = (void *)attr->name;
29323+ cattr = sysaufs_si_attrs;
29324+ while (*cattr) {
29325+ if (!strcmp(name, (*cattr)->name)) {
29326+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
29327+ ->show(seq, sb);
29328+ goto out_seq;
29329+ }
29330+ cattr++;
29331+ }
29332+
392086de
AM
29333+ if (!strncmp(name, SysaufsBrid_PREFIX,
29334+ sizeof(SysaufsBrid_PREFIX) - 1)) {
29335+ idx = AuBrSysfs_BRID;
29336+ name += sizeof(SysaufsBrid_PREFIX) - 1;
29337+ } else if (!strncmp(name, SysaufsBr_PREFIX,
29338+ sizeof(SysaufsBr_PREFIX) - 1)) {
29339+ idx = AuBrSysfs_BR;
1facf9fc 29340+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
29341+ } else
29342+ BUG();
29343+
29344+ err = kstrtol(name, 10, &l);
29345+ if (!err) {
5afbbe0d
AM
29346+ bbot = au_sbbot(sb);
29347+ if (l <= bbot)
392086de
AM
29348+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
29349+ else
29350+ err = -ENOENT;
1facf9fc 29351+ }
1facf9fc 29352+
4f0767ce 29353+out_seq:
1facf9fc 29354+ if (!err) {
29355+ err = seq->count;
29356+ /* sysfs limit */
29357+ if (unlikely(err == PAGE_SIZE))
29358+ err = -EFBIG;
29359+ }
1c60b727 29360+ kfree(seq);
4f0767ce 29361+out_unlock:
1facf9fc 29362+ si_read_unlock(sb);
4f0767ce 29363+out:
1facf9fc 29364+ return err;
29365+}
29366+
29367+/* ---------------------------------------------------------------------- */
29368+
076b876e
AM
29369+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
29370+{
29371+ int err;
29372+ int16_t brid;
5afbbe0d 29373+ aufs_bindex_t bindex, bbot;
076b876e
AM
29374+ size_t sz;
29375+ char *buf;
29376+ struct seq_file *seq;
29377+ struct au_branch *br;
29378+
29379+ si_read_lock(sb, AuLock_FLUSH);
5afbbe0d
AM
29380+ bbot = au_sbbot(sb);
29381+ err = bbot + 1;
076b876e
AM
29382+ if (!arg)
29383+ goto out;
29384+
29385+ err = -ENOMEM;
29386+ buf = (void *)__get_free_page(GFP_NOFS);
29387+ if (unlikely(!buf))
29388+ goto out;
29389+
29390+ seq = au_seq(buf, PAGE_SIZE);
29391+ err = PTR_ERR(seq);
29392+ if (IS_ERR(seq))
29393+ goto out_buf;
29394+
29395+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
5afbbe0d 29396+ for (bindex = 0; bindex <= bbot; bindex++, arg++) {
076b876e
AM
29397+ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg));
29398+ if (unlikely(err))
29399+ break;
29400+
29401+ br = au_sbr(sb, bindex);
29402+ brid = br->br_id;
29403+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
29404+ err = __put_user(brid, &arg->id);
29405+ if (unlikely(err))
29406+ break;
29407+
29408+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
29409+ err = __put_user(br->br_perm, &arg->perm);
29410+ if (unlikely(err))
29411+ break;
29412+
79b8bda9
AM
29413+ err = au_seq_path(seq, &br->br_path);
29414+ if (unlikely(err))
29415+ break;
29416+ seq_putc(seq, '\0');
29417+ if (!seq_has_overflowed(seq)) {
076b876e
AM
29418+ err = copy_to_user(arg->path, seq->buf, seq->count);
29419+ seq->count = 0;
29420+ if (unlikely(err))
29421+ break;
29422+ } else {
29423+ err = -E2BIG;
29424+ goto out_seq;
29425+ }
29426+ }
29427+ if (unlikely(err))
29428+ err = -EFAULT;
29429+
29430+out_seq:
1c60b727 29431+ kfree(seq);
076b876e 29432+out_buf:
1c60b727 29433+ free_page((unsigned long)buf);
076b876e
AM
29434+out:
29435+ si_read_unlock(sb);
29436+ return err;
29437+}
29438+
29439+long au_brinfo_ioctl(struct file *file, unsigned long arg)
29440+{
2000de60 29441+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg);
076b876e
AM
29442+}
29443+
29444+#ifdef CONFIG_COMPAT
29445+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
29446+{
2000de60 29447+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg));
076b876e
AM
29448+}
29449+#endif
29450+
29451+/* ---------------------------------------------------------------------- */
29452+
1facf9fc 29453+void sysaufs_br_init(struct au_branch *br)
29454+{
392086de
AM
29455+ int i;
29456+ struct au_brsysfs *br_sysfs;
29457+ struct attribute *attr;
4a4d8108 29458+
392086de
AM
29459+ br_sysfs = br->br_sysfs;
29460+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
29461+ attr = &br_sysfs->attr;
29462+ sysfs_attr_init(attr);
29463+ attr->name = br_sysfs->name;
29464+ attr->mode = S_IRUGO;
29465+ br_sysfs++;
29466+ }
1facf9fc 29467+}
29468+
29469+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
29470+{
29471+ struct au_branch *br;
29472+ struct kobject *kobj;
392086de
AM
29473+ struct au_brsysfs *br_sysfs;
29474+ int i;
5afbbe0d 29475+ aufs_bindex_t bbot;
1facf9fc 29476+
29477+ dbgaufs_brs_del(sb, bindex);
29478+
29479+ if (!sysaufs_brs)
29480+ return;
29481+
29482+ kobj = &au_sbi(sb)->si_kobj;
5afbbe0d
AM
29483+ bbot = au_sbbot(sb);
29484+ for (; bindex <= bbot; bindex++) {
1facf9fc 29485+ br = au_sbr(sb, bindex);
392086de
AM
29486+ br_sysfs = br->br_sysfs;
29487+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
29488+ sysfs_remove_file(kobj, &br_sysfs->attr);
29489+ br_sysfs++;
29490+ }
1facf9fc 29491+ }
29492+}
29493+
29494+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
29495+{
392086de 29496+ int err, i;
5afbbe0d 29497+ aufs_bindex_t bbot;
1facf9fc 29498+ struct kobject *kobj;
29499+ struct au_branch *br;
392086de 29500+ struct au_brsysfs *br_sysfs;
1facf9fc 29501+
29502+ dbgaufs_brs_add(sb, bindex);
29503+
29504+ if (!sysaufs_brs)
29505+ return;
29506+
29507+ kobj = &au_sbi(sb)->si_kobj;
5afbbe0d
AM
29508+ bbot = au_sbbot(sb);
29509+ for (; bindex <= bbot; bindex++) {
1facf9fc 29510+ br = au_sbr(sb, bindex);
392086de
AM
29511+ br_sysfs = br->br_sysfs;
29512+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
29513+ SysaufsBr_PREFIX "%d", bindex);
29514+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
29515+ SysaufsBrid_PREFIX "%d", bindex);
29516+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
29517+ err = sysfs_create_file(kobj, &br_sysfs->attr);
29518+ if (unlikely(err))
29519+ pr_warn("failed %s under sysfs(%d)\n",
29520+ br_sysfs->name, err);
29521+ br_sysfs++;
29522+ }
1facf9fc 29523+ }
29524+}
7f207e10
AM
29525diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
29526--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 29527+++ linux/fs/aufs/sysrq.c 2017-07-29 12:14:25.906375514 +0200
076b876e 29528@@ -0,0 +1,157 @@
1facf9fc 29529+/*
a2654f78 29530+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 29531+ *
29532+ * This program, aufs is free software; you can redistribute it and/or modify
29533+ * it under the terms of the GNU General Public License as published by
29534+ * the Free Software Foundation; either version 2 of the License, or
29535+ * (at your option) any later version.
dece6358
AM
29536+ *
29537+ * This program is distributed in the hope that it will be useful,
29538+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29539+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29540+ * GNU General Public License for more details.
29541+ *
29542+ * You should have received a copy of the GNU General Public License
523b37e3 29543+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29544+ */
29545+
29546+/*
29547+ * magic sysrq hanlder
29548+ */
29549+
1facf9fc 29550+/* #include <linux/sysrq.h> */
027c5e7a 29551+#include <linux/writeback.h>
1facf9fc 29552+#include "aufs.h"
29553+
29554+/* ---------------------------------------------------------------------- */
29555+
29556+static void sysrq_sb(struct super_block *sb)
29557+{
29558+ char *plevel;
29559+ struct au_sbinfo *sbinfo;
29560+ struct file *file;
523b37e3
AM
29561+ struct au_sphlhead *files;
29562+ struct au_finfo *finfo;
1facf9fc 29563+
29564+ plevel = au_plevel;
29565+ au_plevel = KERN_WARNING;
1facf9fc 29566+
4a4d8108 29567+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
29568+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
29569+
29570+ sbinfo = au_sbi(sb);
4a4d8108 29571+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 29572+ pr("superblock\n");
1facf9fc 29573+ au_dpri_sb(sb);
027c5e7a
AM
29574+
29575+#if 0
c06a8ce3 29576+ pr("root dentry\n");
1facf9fc 29577+ au_dpri_dentry(sb->s_root);
c06a8ce3 29578+ pr("root inode\n");
5527c038 29579+ au_dpri_inode(d_inode(sb->s_root));
027c5e7a
AM
29580+#endif
29581+
1facf9fc 29582+#if 0
027c5e7a
AM
29583+ do {
29584+ int err, i, j, ndentry;
29585+ struct au_dcsub_pages dpages;
29586+ struct au_dpage *dpage;
29587+
29588+ err = au_dpages_init(&dpages, GFP_ATOMIC);
29589+ if (unlikely(err))
29590+ break;
29591+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
29592+ if (!err)
29593+ for (i = 0; i < dpages.ndpage; i++) {
29594+ dpage = dpages.dpages + i;
29595+ ndentry = dpage->ndentry;
29596+ for (j = 0; j < ndentry; j++)
29597+ au_dpri_dentry(dpage->dentries[j]);
29598+ }
29599+ au_dpages_free(&dpages);
29600+ } while (0);
29601+#endif
29602+
29603+#if 1
29604+ {
29605+ struct inode *i;
076b876e 29606+
c06a8ce3 29607+ pr("isolated inode\n");
79b8bda9 29608+ spin_lock(&sb->s_inode_list_lock);
2cbb1c4b
JR
29609+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
29610+ spin_lock(&i->i_lock);
b4510431 29611+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 29612+ au_dpri_inode(i);
2cbb1c4b
JR
29613+ spin_unlock(&i->i_lock);
29614+ }
79b8bda9 29615+ spin_unlock(&sb->s_inode_list_lock);
027c5e7a 29616+ }
1facf9fc 29617+#endif
c06a8ce3 29618+ pr("files\n");
523b37e3
AM
29619+ files = &au_sbi(sb)->si_files;
29620+ spin_lock(&files->spin);
29621+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
4a4d8108 29622+ umode_t mode;
076b876e 29623+
523b37e3 29624+ file = finfo->fi_file;
c06a8ce3 29625+ mode = file_inode(file)->i_mode;
38d290e6 29626+ if (!special_file(mode))
1facf9fc 29627+ au_dpri_file(file);
523b37e3
AM
29628+ }
29629+ spin_unlock(&files->spin);
c06a8ce3 29630+ pr("done\n");
1facf9fc 29631+
c06a8ce3 29632+#undef pr
1facf9fc 29633+ au_plevel = plevel;
1facf9fc 29634+}
29635+
29636+/* ---------------------------------------------------------------------- */
29637+
29638+/* module parameter */
29639+static char *aufs_sysrq_key = "a";
29640+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
29641+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
29642+
0c5527e5 29643+static void au_sysrq(int key __maybe_unused)
1facf9fc 29644+{
1facf9fc 29645+ struct au_sbinfo *sbinfo;
29646+
027c5e7a 29647+ lockdep_off();
53392da6 29648+ au_sbilist_lock();
5afbbe0d 29649+ hlist_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 29650+ sysrq_sb(sbinfo->si_sb);
53392da6 29651+ au_sbilist_unlock();
027c5e7a 29652+ lockdep_on();
1facf9fc 29653+}
29654+
29655+static struct sysrq_key_op au_sysrq_op = {
29656+ .handler = au_sysrq,
29657+ .help_msg = "Aufs",
29658+ .action_msg = "Aufs",
29659+ .enable_mask = SYSRQ_ENABLE_DUMP
29660+};
29661+
29662+/* ---------------------------------------------------------------------- */
29663+
29664+int __init au_sysrq_init(void)
29665+{
29666+ int err;
29667+ char key;
29668+
29669+ err = -1;
29670+ key = *aufs_sysrq_key;
29671+ if ('a' <= key && key <= 'z')
29672+ err = register_sysrq_key(key, &au_sysrq_op);
29673+ if (unlikely(err))
4a4d8108 29674+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 29675+ return err;
29676+}
29677+
29678+void au_sysrq_fin(void)
29679+{
29680+ int err;
076b876e 29681+
1facf9fc 29682+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
29683+ if (unlikely(err))
4a4d8108 29684+ pr_err("err %d (ignored)\n", err);
1facf9fc 29685+}
7f207e10
AM
29686diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
29687--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
29688+++ linux/fs/aufs/vdir.c 2017-07-29 12:14:25.906375514 +0200
29689@@ -0,0 +1,892 @@
1facf9fc 29690+/*
a2654f78 29691+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 29692+ *
29693+ * This program, aufs is free software; you can redistribute it and/or modify
29694+ * it under the terms of the GNU General Public License as published by
29695+ * the Free Software Foundation; either version 2 of the License, or
29696+ * (at your option) any later version.
dece6358
AM
29697+ *
29698+ * This program is distributed in the hope that it will be useful,
29699+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29700+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29701+ * GNU General Public License for more details.
29702+ *
29703+ * You should have received a copy of the GNU General Public License
523b37e3 29704+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29705+ */
29706+
29707+/*
29708+ * virtual or vertical directory
29709+ */
29710+
29711+#include "aufs.h"
29712+
dece6358 29713+static unsigned int calc_size(int nlen)
1facf9fc 29714+{
dece6358 29715+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 29716+}
29717+
29718+static int set_deblk_end(union au_vdir_deblk_p *p,
29719+ union au_vdir_deblk_p *deblk_end)
29720+{
29721+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
29722+ p->de->de_str.len = 0;
29723+ /* smp_mb(); */
29724+ return 0;
29725+ }
29726+ return -1; /* error */
29727+}
29728+
29729+/* returns true or false */
29730+static int is_deblk_end(union au_vdir_deblk_p *p,
29731+ union au_vdir_deblk_p *deblk_end)
29732+{
29733+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
29734+ return !p->de->de_str.len;
29735+ return 1;
29736+}
29737+
29738+static unsigned char *last_deblk(struct au_vdir *vdir)
29739+{
29740+ return vdir->vd_deblk[vdir->vd_nblk - 1];
29741+}
29742+
29743+/* ---------------------------------------------------------------------- */
29744+
79b8bda9 29745+/* estimate the appropriate size for name hash table */
1308ab2a 29746+unsigned int au_rdhash_est(loff_t sz)
29747+{
29748+ unsigned int n;
29749+
29750+ n = UINT_MAX;
29751+ sz >>= 10;
29752+ if (sz < n)
29753+ n = sz;
29754+ if (sz < AUFS_RDHASH_DEF)
29755+ n = AUFS_RDHASH_DEF;
4a4d8108 29756+ /* pr_info("n %u\n", n); */
1308ab2a 29757+ return n;
29758+}
29759+
1facf9fc 29760+/*
29761+ * the allocated memory has to be freed by
dece6358 29762+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 29763+ */
dece6358 29764+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 29765+{
1facf9fc 29766+ struct hlist_head *head;
dece6358 29767+ unsigned int u;
076b876e 29768+ size_t sz;
1facf9fc 29769+
076b876e
AM
29770+ sz = sizeof(*nhash->nh_head) * num_hash;
29771+ head = kmalloc(sz, gfp);
dece6358
AM
29772+ if (head) {
29773+ nhash->nh_num = num_hash;
29774+ nhash->nh_head = head;
29775+ for (u = 0; u < num_hash; u++)
1facf9fc 29776+ INIT_HLIST_HEAD(head++);
dece6358 29777+ return 0; /* success */
1facf9fc 29778+ }
1facf9fc 29779+
dece6358 29780+ return -ENOMEM;
1facf9fc 29781+}
29782+
dece6358
AM
29783+static void nhash_count(struct hlist_head *head)
29784+{
29785+#if 0
29786+ unsigned long n;
29787+ struct hlist_node *pos;
29788+
29789+ n = 0;
29790+ hlist_for_each(pos, head)
29791+ n++;
4a4d8108 29792+ pr_info("%lu\n", n);
dece6358
AM
29793+#endif
29794+}
29795+
29796+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 29797+{
c06a8ce3
AM
29798+ struct au_vdir_wh *pos;
29799+ struct hlist_node *node;
1facf9fc 29800+
c06a8ce3 29801+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
1c60b727 29802+ kfree(pos);
1facf9fc 29803+}
29804+
dece6358 29805+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 29806+{
c06a8ce3
AM
29807+ struct au_vdir_dehstr *pos;
29808+ struct hlist_node *node;
1facf9fc 29809+
c06a8ce3 29810+ hlist_for_each_entry_safe(pos, node, head, hash)
1c60b727 29811+ au_cache_free_vdir_dehstr(pos);
1facf9fc 29812+}
29813+
dece6358
AM
29814+static void au_nhash_do_free(struct au_nhash *nhash,
29815+ void (*free)(struct hlist_head *head))
1facf9fc 29816+{
1308ab2a 29817+ unsigned int n;
1facf9fc 29818+ struct hlist_head *head;
1facf9fc 29819+
dece6358 29820+ n = nhash->nh_num;
1308ab2a 29821+ if (!n)
29822+ return;
29823+
dece6358 29824+ head = nhash->nh_head;
1308ab2a 29825+ while (n-- > 0) {
dece6358
AM
29826+ nhash_count(head);
29827+ free(head++);
1facf9fc 29828+ }
1c60b727 29829+ kfree(nhash->nh_head);
1facf9fc 29830+}
29831+
dece6358 29832+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 29833+{
dece6358
AM
29834+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
29835+}
1facf9fc 29836+
dece6358
AM
29837+static void au_nhash_de_free(struct au_nhash *delist)
29838+{
29839+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 29840+}
29841+
29842+/* ---------------------------------------------------------------------- */
29843+
29844+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
29845+ int limit)
29846+{
29847+ int num;
29848+ unsigned int u, n;
29849+ struct hlist_head *head;
c06a8ce3 29850+ struct au_vdir_wh *pos;
1facf9fc 29851+
29852+ num = 0;
29853+ n = whlist->nh_num;
29854+ head = whlist->nh_head;
1308ab2a 29855+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
29856+ hlist_for_each_entry(pos, head, wh_hash)
29857+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 29858+ return 1;
1facf9fc 29859+ return 0;
29860+}
29861+
29862+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 29863+ unsigned char *name,
1facf9fc 29864+ unsigned int len)
29865+{
dece6358
AM
29866+ unsigned int v;
29867+ /* const unsigned int magic_bit = 12; */
29868+
1308ab2a 29869+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
29870+
dece6358 29871+ v = 0;
f0c0a007
AM
29872+ if (len > 8)
29873+ len = 8;
dece6358
AM
29874+ while (len--)
29875+ v += *name++;
29876+ /* v = hash_long(v, magic_bit); */
29877+ v %= nhash->nh_num;
29878+ return nhash->nh_head + v;
29879+}
29880+
29881+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
29882+ int nlen)
29883+{
29884+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 29885+}
29886+
29887+/* returns found or not */
dece6358 29888+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 29889+{
29890+ struct hlist_head *head;
c06a8ce3 29891+ struct au_vdir_wh *pos;
1facf9fc 29892+ struct au_vdir_destr *str;
29893+
dece6358 29894+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
29895+ hlist_for_each_entry(pos, head, wh_hash) {
29896+ str = &pos->wh_str;
1facf9fc 29897+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
29898+ if (au_nhash_test_name(str, name, nlen))
29899+ return 1;
29900+ }
29901+ return 0;
29902+}
29903+
29904+/* returns found(true) or not */
29905+static int test_known(struct au_nhash *delist, char *name, int nlen)
29906+{
29907+ struct hlist_head *head;
c06a8ce3 29908+ struct au_vdir_dehstr *pos;
dece6358
AM
29909+ struct au_vdir_destr *str;
29910+
29911+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
29912+ hlist_for_each_entry(pos, head, hash) {
29913+ str = pos->str;
dece6358
AM
29914+ AuDbg("%.*s\n", str->len, str->name);
29915+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 29916+ return 1;
29917+ }
29918+ return 0;
29919+}
29920+
dece6358
AM
29921+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
29922+ unsigned char d_type)
29923+{
29924+#ifdef CONFIG_AUFS_SHWH
29925+ wh->wh_ino = ino;
29926+ wh->wh_type = d_type;
29927+#endif
29928+}
29929+
29930+/* ---------------------------------------------------------------------- */
29931+
29932+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
29933+ unsigned int d_type, aufs_bindex_t bindex,
29934+ unsigned char shwh)
1facf9fc 29935+{
29936+ int err;
29937+ struct au_vdir_destr *str;
29938+ struct au_vdir_wh *wh;
29939+
dece6358 29940+ AuDbg("%.*s\n", nlen, name);
1308ab2a 29941+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
29942+
1facf9fc 29943+ err = -ENOMEM;
dece6358 29944+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 29945+ if (unlikely(!wh))
29946+ goto out;
29947+
29948+ err = 0;
29949+ wh->wh_bindex = bindex;
dece6358
AM
29950+ if (shwh)
29951+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 29952+ str = &wh->wh_str;
dece6358
AM
29953+ str->len = nlen;
29954+ memcpy(str->name, name, nlen);
29955+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 29956+ /* smp_mb(); */
29957+
4f0767ce 29958+out:
1facf9fc 29959+ return err;
29960+}
29961+
1facf9fc 29962+static int append_deblk(struct au_vdir *vdir)
29963+{
29964+ int err;
dece6358 29965+ unsigned long ul;
1facf9fc 29966+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
29967+ union au_vdir_deblk_p p, deblk_end;
29968+ unsigned char **o;
29969+
29970+ err = -ENOMEM;
e2f27e51
AM
29971+ o = au_krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
29972+ GFP_NOFS, /*may_shrink*/0);
1facf9fc 29973+ if (unlikely(!o))
29974+ goto out;
29975+
29976+ vdir->vd_deblk = o;
29977+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
29978+ if (p.deblk) {
29979+ ul = vdir->vd_nblk++;
29980+ vdir->vd_deblk[ul] = p.deblk;
29981+ vdir->vd_last.ul = ul;
29982+ vdir->vd_last.p.deblk = p.deblk;
29983+ deblk_end.deblk = p.deblk + deblk_sz;
29984+ err = set_deblk_end(&p, &deblk_end);
29985+ }
29986+
4f0767ce 29987+out:
1facf9fc 29988+ return err;
29989+}
29990+
dece6358
AM
29991+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
29992+ unsigned int d_type, struct au_nhash *delist)
29993+{
29994+ int err;
29995+ unsigned int sz;
29996+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
29997+ union au_vdir_deblk_p p, *room, deblk_end;
29998+ struct au_vdir_dehstr *dehstr;
29999+
30000+ p.deblk = last_deblk(vdir);
30001+ deblk_end.deblk = p.deblk + deblk_sz;
30002+ room = &vdir->vd_last.p;
30003+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
30004+ || !is_deblk_end(room, &deblk_end));
30005+
30006+ sz = calc_size(nlen);
30007+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
30008+ err = append_deblk(vdir);
30009+ if (unlikely(err))
30010+ goto out;
30011+
30012+ p.deblk = last_deblk(vdir);
30013+ deblk_end.deblk = p.deblk + deblk_sz;
30014+ /* smp_mb(); */
30015+ AuDebugOn(room->deblk != p.deblk);
30016+ }
30017+
30018+ err = -ENOMEM;
4a4d8108 30019+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
30020+ if (unlikely(!dehstr))
30021+ goto out;
30022+
30023+ dehstr->str = &room->de->de_str;
30024+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
30025+ room->de->de_ino = ino;
30026+ room->de->de_type = d_type;
30027+ room->de->de_str.len = nlen;
30028+ memcpy(room->de->de_str.name, name, nlen);
30029+
30030+ err = 0;
30031+ room->deblk += sz;
30032+ if (unlikely(set_deblk_end(room, &deblk_end)))
30033+ err = append_deblk(vdir);
30034+ /* smp_mb(); */
30035+
4f0767ce 30036+out:
dece6358
AM
30037+ return err;
30038+}
30039+
30040+/* ---------------------------------------------------------------------- */
30041+
1c60b727 30042+void au_vdir_free(struct au_vdir *vdir)
dece6358
AM
30043+{
30044+ unsigned char **deblk;
30045+
30046+ deblk = vdir->vd_deblk;
1c60b727
AM
30047+ while (vdir->vd_nblk--)
30048+ kfree(*deblk++);
30049+ kfree(vdir->vd_deblk);
30050+ au_cache_free_vdir(vdir);
dece6358
AM
30051+}
30052+
1308ab2a 30053+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 30054+{
30055+ struct au_vdir *vdir;
1308ab2a 30056+ struct super_block *sb;
1facf9fc 30057+ int err;
30058+
2000de60 30059+ sb = file->f_path.dentry->d_sb;
dece6358
AM
30060+ SiMustAnyLock(sb);
30061+
1facf9fc 30062+ err = -ENOMEM;
30063+ vdir = au_cache_alloc_vdir();
30064+ if (unlikely(!vdir))
30065+ goto out;
30066+
30067+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
30068+ if (unlikely(!vdir->vd_deblk))
30069+ goto out_free;
30070+
30071+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 30072+ if (!vdir->vd_deblk_sz) {
79b8bda9 30073+ /* estimate the appropriate size for deblk */
1308ab2a 30074+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 30075+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 30076+ }
1facf9fc 30077+ vdir->vd_nblk = 0;
30078+ vdir->vd_version = 0;
30079+ vdir->vd_jiffy = 0;
30080+ err = append_deblk(vdir);
30081+ if (!err)
30082+ return vdir; /* success */
30083+
1c60b727 30084+ kfree(vdir->vd_deblk);
1facf9fc 30085+
4f0767ce 30086+out_free:
1c60b727 30087+ au_cache_free_vdir(vdir);
4f0767ce 30088+out:
1facf9fc 30089+ vdir = ERR_PTR(err);
30090+ return vdir;
30091+}
30092+
30093+static int reinit_vdir(struct au_vdir *vdir)
30094+{
30095+ int err;
30096+ union au_vdir_deblk_p p, deblk_end;
30097+
30098+ while (vdir->vd_nblk > 1) {
1c60b727 30099+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
1facf9fc 30100+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
30101+ vdir->vd_nblk--;
30102+ }
30103+ p.deblk = vdir->vd_deblk[0];
30104+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
30105+ err = set_deblk_end(&p, &deblk_end);
30106+ /* keep vd_dblk_sz */
30107+ vdir->vd_last.ul = 0;
30108+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
30109+ vdir->vd_version = 0;
30110+ vdir->vd_jiffy = 0;
30111+ /* smp_mb(); */
30112+ return err;
30113+}
30114+
30115+/* ---------------------------------------------------------------------- */
30116+
1facf9fc 30117+#define AuFillVdir_CALLED 1
30118+#define AuFillVdir_WHABLE (1 << 1)
dece6358 30119+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 30120+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
30121+#define au_fset_fillvdir(flags, name) \
30122+ do { (flags) |= AuFillVdir_##name; } while (0)
30123+#define au_fclr_fillvdir(flags, name) \
30124+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 30125+
dece6358
AM
30126+#ifndef CONFIG_AUFS_SHWH
30127+#undef AuFillVdir_SHWH
30128+#define AuFillVdir_SHWH 0
30129+#endif
30130+
1facf9fc 30131+struct fillvdir_arg {
392086de 30132+ struct dir_context ctx;
1facf9fc 30133+ struct file *file;
30134+ struct au_vdir *vdir;
dece6358
AM
30135+ struct au_nhash delist;
30136+ struct au_nhash whlist;
1facf9fc 30137+ aufs_bindex_t bindex;
30138+ unsigned int flags;
30139+ int err;
30140+};
30141+
392086de 30142+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 30143+ loff_t offset __maybe_unused, u64 h_ino,
30144+ unsigned int d_type)
30145+{
392086de 30146+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 30147+ char *name = (void *)__name;
30148+ struct super_block *sb;
1facf9fc 30149+ ino_t ino;
dece6358 30150+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 30151+
1facf9fc 30152+ arg->err = 0;
2000de60 30153+ sb = arg->file->f_path.dentry->d_sb;
1facf9fc 30154+ au_fset_fillvdir(arg->flags, CALLED);
30155+ /* smp_mb(); */
dece6358 30156+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 30157+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
30158+ if (test_known(&arg->delist, name, nlen)
30159+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
30160+ goto out; /* already exists or whiteouted */
1facf9fc 30161+
dece6358 30162+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
30163+ if (!arg->err) {
30164+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
30165+ d_type = DT_UNKNOWN;
dece6358
AM
30166+ arg->err = append_de(arg->vdir, name, nlen, ino,
30167+ d_type, &arg->delist);
4a4d8108 30168+ }
1facf9fc 30169+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
30170+ name += AUFS_WH_PFX_LEN;
dece6358
AM
30171+ nlen -= AUFS_WH_PFX_LEN;
30172+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
30173+ goto out; /* already whiteouted */
1facf9fc 30174+
dece6358
AM
30175+ if (shwh)
30176+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
30177+ &ino);
4a4d8108
AM
30178+ if (!arg->err) {
30179+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
30180+ d_type = DT_UNKNOWN;
1facf9fc 30181+ arg->err = au_nhash_append_wh
dece6358
AM
30182+ (&arg->whlist, name, nlen, ino, d_type,
30183+ arg->bindex, shwh);
4a4d8108 30184+ }
1facf9fc 30185+ }
30186+
4f0767ce 30187+out:
1facf9fc 30188+ if (!arg->err)
30189+ arg->vdir->vd_jiffy = jiffies;
30190+ /* smp_mb(); */
30191+ AuTraceErr(arg->err);
30192+ return arg->err;
30193+}
30194+
dece6358
AM
30195+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
30196+ struct au_nhash *whlist, struct au_nhash *delist)
30197+{
30198+#ifdef CONFIG_AUFS_SHWH
30199+ int err;
30200+ unsigned int nh, u;
30201+ struct hlist_head *head;
c06a8ce3
AM
30202+ struct au_vdir_wh *pos;
30203+ struct hlist_node *n;
dece6358
AM
30204+ char *p, *o;
30205+ struct au_vdir_destr *destr;
30206+
30207+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
30208+
30209+ err = -ENOMEM;
537831f9 30210+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
30211+ if (unlikely(!p))
30212+ goto out;
30213+
30214+ err = 0;
30215+ nh = whlist->nh_num;
30216+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
30217+ p += AUFS_WH_PFX_LEN;
30218+ for (u = 0; u < nh; u++) {
30219+ head = whlist->nh_head + u;
c06a8ce3
AM
30220+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
30221+ destr = &pos->wh_str;
dece6358
AM
30222+ memcpy(p, destr->name, destr->len);
30223+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 30224+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
30225+ if (unlikely(err))
30226+ break;
30227+ }
30228+ }
30229+
1c60b727 30230+ free_page((unsigned long)o);
dece6358 30231+
4f0767ce 30232+out:
dece6358
AM
30233+ AuTraceErr(err);
30234+ return err;
30235+#else
30236+ return 0;
30237+#endif
30238+}
30239+
1facf9fc 30240+static int au_do_read_vdir(struct fillvdir_arg *arg)
30241+{
30242+ int err;
dece6358 30243+ unsigned int rdhash;
1facf9fc 30244+ loff_t offset;
5afbbe0d 30245+ aufs_bindex_t bbot, bindex, btop;
dece6358 30246+ unsigned char shwh;
1facf9fc 30247+ struct file *hf, *file;
30248+ struct super_block *sb;
30249+
1facf9fc 30250+ file = arg->file;
2000de60 30251+ sb = file->f_path.dentry->d_sb;
dece6358
AM
30252+ SiMustAnyLock(sb);
30253+
30254+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 30255+ if (!rdhash)
30256+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
30257+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
30258+ if (unlikely(err))
1facf9fc 30259+ goto out;
dece6358
AM
30260+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
30261+ if (unlikely(err))
1facf9fc 30262+ goto out_delist;
30263+
30264+ err = 0;
30265+ arg->flags = 0;
dece6358
AM
30266+ shwh = 0;
30267+ if (au_opt_test(au_mntflags(sb), SHWH)) {
30268+ shwh = 1;
30269+ au_fset_fillvdir(arg->flags, SHWH);
30270+ }
5afbbe0d
AM
30271+ btop = au_fbtop(file);
30272+ bbot = au_fbbot_dir(file);
30273+ for (bindex = btop; !err && bindex <= bbot; bindex++) {
4a4d8108 30274+ hf = au_hf_dir(file, bindex);
1facf9fc 30275+ if (!hf)
30276+ continue;
30277+
30278+ offset = vfsub_llseek(hf, 0, SEEK_SET);
30279+ err = offset;
30280+ if (unlikely(offset))
30281+ break;
30282+
30283+ arg->bindex = bindex;
30284+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358 30285+ if (shwh
5afbbe0d 30286+ || (bindex != bbot
dece6358 30287+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 30288+ au_fset_fillvdir(arg->flags, WHABLE);
30289+ do {
30290+ arg->err = 0;
30291+ au_fclr_fillvdir(arg->flags, CALLED);
30292+ /* smp_mb(); */
392086de 30293+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 30294+ if (err >= 0)
30295+ err = arg->err;
30296+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
30297+
30298+ /*
30299+ * dir_relax() may be good for concurrency, but aufs should not
30300+ * use it since it will cause a lockdep problem.
30301+ */
1facf9fc 30302+ }
dece6358
AM
30303+
30304+ if (!err && shwh)
30305+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
30306+
30307+ au_nhash_wh_free(&arg->whlist);
1facf9fc 30308+
4f0767ce 30309+out_delist:
dece6358 30310+ au_nhash_de_free(&arg->delist);
4f0767ce 30311+out:
1facf9fc 30312+ return err;
30313+}
30314+
30315+static int read_vdir(struct file *file, int may_read)
30316+{
30317+ int err;
30318+ unsigned long expire;
30319+ unsigned char do_read;
392086de
AM
30320+ struct fillvdir_arg arg = {
30321+ .ctx = {
2000de60 30322+ .actor = fillvdir
392086de
AM
30323+ }
30324+ };
1facf9fc 30325+ struct inode *inode;
30326+ struct au_vdir *vdir, *allocated;
30327+
30328+ err = 0;
c06a8ce3 30329+ inode = file_inode(file);
1facf9fc 30330+ IMustLock(inode);
5afbbe0d 30331+ IiMustWriteLock(inode);
dece6358
AM
30332+ SiMustAnyLock(inode->i_sb);
30333+
1facf9fc 30334+ allocated = NULL;
30335+ do_read = 0;
30336+ expire = au_sbi(inode->i_sb)->si_rdcache;
30337+ vdir = au_ivdir(inode);
30338+ if (!vdir) {
30339+ do_read = 1;
1308ab2a 30340+ vdir = alloc_vdir(file);
1facf9fc 30341+ err = PTR_ERR(vdir);
30342+ if (IS_ERR(vdir))
30343+ goto out;
30344+ err = 0;
30345+ allocated = vdir;
30346+ } else if (may_read
30347+ && (inode->i_version != vdir->vd_version
30348+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
30349+ do_read = 1;
30350+ err = reinit_vdir(vdir);
30351+ if (unlikely(err))
30352+ goto out;
30353+ }
30354+
30355+ if (!do_read)
30356+ return 0; /* success */
30357+
30358+ arg.file = file;
30359+ arg.vdir = vdir;
30360+ err = au_do_read_vdir(&arg);
30361+ if (!err) {
392086de 30362+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
1facf9fc 30363+ vdir->vd_version = inode->i_version;
30364+ vdir->vd_last.ul = 0;
30365+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
30366+ if (allocated)
30367+ au_set_ivdir(inode, allocated);
30368+ } else if (allocated)
1c60b727 30369+ au_vdir_free(allocated);
1facf9fc 30370+
4f0767ce 30371+out:
1facf9fc 30372+ return err;
30373+}
30374+
30375+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
30376+{
30377+ int err, rerr;
30378+ unsigned long ul, n;
30379+ const unsigned int deblk_sz = src->vd_deblk_sz;
30380+
30381+ AuDebugOn(tgt->vd_nblk != 1);
30382+
30383+ err = -ENOMEM;
30384+ if (tgt->vd_nblk < src->vd_nblk) {
30385+ unsigned char **p;
30386+
e2f27e51
AM
30387+ p = au_krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
30388+ GFP_NOFS, /*may_shrink*/0);
1facf9fc 30389+ if (unlikely(!p))
30390+ goto out;
30391+ tgt->vd_deblk = p;
30392+ }
30393+
1308ab2a 30394+ if (tgt->vd_deblk_sz != deblk_sz) {
30395+ unsigned char *p;
30396+
30397+ tgt->vd_deblk_sz = deblk_sz;
e2f27e51
AM
30398+ p = au_krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS,
30399+ /*may_shrink*/1);
1308ab2a 30400+ if (unlikely(!p))
30401+ goto out;
30402+ tgt->vd_deblk[0] = p;
30403+ }
1facf9fc 30404+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 30405+ tgt->vd_version = src->vd_version;
30406+ tgt->vd_jiffy = src->vd_jiffy;
30407+
30408+ n = src->vd_nblk;
30409+ for (ul = 1; ul < n; ul++) {
dece6358
AM
30410+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
30411+ GFP_NOFS);
30412+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 30413+ goto out;
1308ab2a 30414+ tgt->vd_nblk++;
1facf9fc 30415+ }
1308ab2a 30416+ tgt->vd_nblk = n;
30417+ tgt->vd_last.ul = tgt->vd_last.ul;
30418+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
30419+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
30420+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 30421+ /* smp_mb(); */
30422+ return 0; /* success */
30423+
4f0767ce 30424+out:
1facf9fc 30425+ rerr = reinit_vdir(tgt);
30426+ BUG_ON(rerr);
30427+ return err;
30428+}
30429+
30430+int au_vdir_init(struct file *file)
30431+{
30432+ int err;
30433+ struct inode *inode;
30434+ struct au_vdir *vdir_cache, *allocated;
30435+
392086de 30436+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 30437+ err = read_vdir(file, !file->f_pos);
30438+ if (unlikely(err))
30439+ goto out;
30440+
30441+ allocated = NULL;
30442+ vdir_cache = au_fvdir_cache(file);
30443+ if (!vdir_cache) {
1308ab2a 30444+ vdir_cache = alloc_vdir(file);
1facf9fc 30445+ err = PTR_ERR(vdir_cache);
30446+ if (IS_ERR(vdir_cache))
30447+ goto out;
30448+ allocated = vdir_cache;
30449+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 30450+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 30451+ err = reinit_vdir(vdir_cache);
30452+ if (unlikely(err))
30453+ goto out;
30454+ } else
30455+ return 0; /* success */
30456+
c06a8ce3 30457+ inode = file_inode(file);
1facf9fc 30458+ err = copy_vdir(vdir_cache, au_ivdir(inode));
30459+ if (!err) {
30460+ file->f_version = inode->i_version;
30461+ if (allocated)
30462+ au_set_fvdir_cache(file, allocated);
30463+ } else if (allocated)
1c60b727 30464+ au_vdir_free(allocated);
1facf9fc 30465+
4f0767ce 30466+out:
1facf9fc 30467+ return err;
30468+}
30469+
30470+static loff_t calc_offset(struct au_vdir *vdir)
30471+{
30472+ loff_t offset;
30473+ union au_vdir_deblk_p p;
30474+
30475+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
30476+ offset = vdir->vd_last.p.deblk - p.deblk;
30477+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
30478+ return offset;
30479+}
30480+
30481+/* returns true or false */
392086de 30482+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 30483+{
30484+ int valid;
30485+ unsigned int deblk_sz;
30486+ unsigned long ul, n;
30487+ loff_t offset;
30488+ union au_vdir_deblk_p p, deblk_end;
30489+ struct au_vdir *vdir_cache;
30490+
30491+ valid = 1;
30492+ vdir_cache = au_fvdir_cache(file);
30493+ offset = calc_offset(vdir_cache);
30494+ AuDbg("offset %lld\n", offset);
392086de 30495+ if (ctx->pos == offset)
1facf9fc 30496+ goto out;
30497+
30498+ vdir_cache->vd_last.ul = 0;
30499+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 30500+ if (!ctx->pos)
1facf9fc 30501+ goto out;
30502+
30503+ valid = 0;
30504+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 30505+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 30506+ AuDbg("ul %lu\n", ul);
30507+ if (ul >= vdir_cache->vd_nblk)
30508+ goto out;
30509+
30510+ n = vdir_cache->vd_nblk;
30511+ for (; ul < n; ul++) {
30512+ p.deblk = vdir_cache->vd_deblk[ul];
30513+ deblk_end.deblk = p.deblk + deblk_sz;
30514+ offset = ul;
30515+ offset *= deblk_sz;
392086de 30516+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 30517+ unsigned int l;
30518+
30519+ l = calc_size(p.de->de_str.len);
30520+ offset += l;
30521+ p.deblk += l;
30522+ }
30523+ if (!is_deblk_end(&p, &deblk_end)) {
30524+ valid = 1;
30525+ vdir_cache->vd_last.ul = ul;
30526+ vdir_cache->vd_last.p = p;
30527+ break;
30528+ }
30529+ }
30530+
4f0767ce 30531+out:
1facf9fc 30532+ /* smp_mb(); */
30533+ AuTraceErr(!valid);
30534+ return valid;
30535+}
30536+
392086de 30537+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 30538+{
1facf9fc 30539+ unsigned int l, deblk_sz;
30540+ union au_vdir_deblk_p deblk_end;
30541+ struct au_vdir *vdir_cache;
30542+ struct au_vdir_de *de;
30543+
30544+ vdir_cache = au_fvdir_cache(file);
392086de 30545+ if (!seek_vdir(file, ctx))
1facf9fc 30546+ return 0;
30547+
30548+ deblk_sz = vdir_cache->vd_deblk_sz;
30549+ while (1) {
30550+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
30551+ deblk_end.deblk += deblk_sz;
30552+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
30553+ de = vdir_cache->vd_last.p.de;
30554+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 30555+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 30556+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
30557+ if (unlikely(!dir_emit(ctx, de->de_str.name,
30558+ de->de_str.len, de->de_ino,
30559+ de->de_type))) {
1facf9fc 30560+ /* todo: ignore the error caused by udba? */
30561+ /* return err; */
30562+ return 0;
30563+ }
30564+
30565+ l = calc_size(de->de_str.len);
30566+ vdir_cache->vd_last.p.deblk += l;
392086de 30567+ ctx->pos += l;
1facf9fc 30568+ }
30569+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
30570+ vdir_cache->vd_last.ul++;
30571+ vdir_cache->vd_last.p.deblk
30572+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 30573+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 30574+ continue;
30575+ }
30576+ break;
30577+ }
30578+
30579+ /* smp_mb(); */
30580+ return 0;
30581+}
7f207e10
AM
30582diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
30583--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
1c60b727
AM
30584+++ linux/fs/aufs/vfsub.c 2017-07-29 12:14:25.906375514 +0200
30585@@ -0,0 +1,900 @@
1facf9fc 30586+/*
a2654f78 30587+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 30588+ *
30589+ * This program, aufs is free software; you can redistribute it and/or modify
30590+ * it under the terms of the GNU General Public License as published by
30591+ * the Free Software Foundation; either version 2 of the License, or
30592+ * (at your option) any later version.
dece6358
AM
30593+ *
30594+ * This program is distributed in the hope that it will be useful,
30595+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30596+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30597+ * GNU General Public License for more details.
30598+ *
30599+ * You should have received a copy of the GNU General Public License
523b37e3 30600+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30601+ */
30602+
30603+/*
30604+ * sub-routines for VFS
30605+ */
30606+
dece6358 30607+#include <linux/namei.h>
8cdd5066 30608+#include <linux/nsproxy.h>
dece6358
AM
30609+#include <linux/security.h>
30610+#include <linux/splice.h>
f2c43d5f 30611+#ifdef CONFIG_AUFS_BR_FUSE
8cdd5066 30612+#include "../fs/mount.h"
f2c43d5f 30613+#endif
1facf9fc 30614+#include "aufs.h"
30615+
8cdd5066
JR
30616+#ifdef CONFIG_AUFS_BR_FUSE
30617+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb)
30618+{
30619+ struct nsproxy *ns;
30620+
30621+ if (!au_test_fuse(h_sb) || !au_userns)
30622+ return 0;
30623+
30624+ ns = current->nsproxy;
30625+ /* no {get,put}_nsproxy(ns) */
30626+ return real_mount(mnt)->mnt_ns == ns->mnt_ns ? 0 : -EACCES;
30627+}
30628+#endif
30629+
a2654f78
AM
30630+int vfsub_sync_filesystem(struct super_block *h_sb, int wait)
30631+{
30632+ int err;
30633+
30634+ lockdep_off();
30635+ down_read(&h_sb->s_umount);
30636+ err = __sync_filesystem(h_sb, wait);
30637+ up_read(&h_sb->s_umount);
30638+ lockdep_on();
30639+
30640+ return err;
30641+}
30642+
8cdd5066
JR
30643+/* ---------------------------------------------------------------------- */
30644+
1facf9fc 30645+int vfsub_update_h_iattr(struct path *h_path, int *did)
30646+{
30647+ int err;
30648+ struct kstat st;
30649+ struct super_block *h_sb;
30650+
30651+ /* for remote fs, leave work for its getattr or d_revalidate */
30652+ /* for bad i_attr fs, handle them in aufs_getattr() */
30653+ /* still some fs may acquire i_mutex. we need to skip them */
30654+ err = 0;
30655+ if (!did)
30656+ did = &err;
30657+ h_sb = h_path->dentry->d_sb;
30658+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
30659+ if (*did)
521ced18 30660+ err = vfsub_getattr(h_path, &st);
1facf9fc 30661+
30662+ return err;
30663+}
30664+
30665+/* ---------------------------------------------------------------------- */
30666+
4a4d8108 30667+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 30668+{
30669+ struct file *file;
30670+
b4510431 30671+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 30672+ current_cred());
2cbb1c4b
JR
30673+ if (!IS_ERR_OR_NULL(file)
30674+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
5527c038 30675+ i_readcount_inc(d_inode(path->dentry));
4a4d8108 30676+
1308ab2a 30677+ return file;
30678+}
30679+
1facf9fc 30680+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
30681+{
30682+ struct file *file;
30683+
2cbb1c4b 30684+ lockdep_off();
7f207e10 30685+ file = filp_open(path,
2cbb1c4b 30686+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 30687+ mode);
2cbb1c4b 30688+ lockdep_on();
1facf9fc 30689+ if (IS_ERR(file))
30690+ goto out;
30691+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30692+
4f0767ce 30693+out:
1facf9fc 30694+ return file;
30695+}
30696+
b912730e
AM
30697+/*
30698+ * Ideally this function should call VFS:do_last() in order to keep all its
30699+ * checkings. But it is very hard for aufs to regenerate several VFS internal
30700+ * structure such as nameidata. This is a second (or third) best approach.
30701+ * cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open().
30702+ */
30703+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
30704+ struct vfsub_aopen_args *args, struct au_branch *br)
30705+{
30706+ int err;
30707+ struct file *file = args->file;
30708+ /* copied from linux/fs/namei.c:atomic_open() */
30709+ struct dentry *const DENTRY_NOT_SET = (void *)-1UL;
30710+
30711+ IMustLock(dir);
30712+ AuDebugOn(!dir->i_op->atomic_open);
30713+
30714+ err = au_br_test_oflag(args->open_flag, br);
30715+ if (unlikely(err))
30716+ goto out;
30717+
30718+ args->file->f_path.dentry = DENTRY_NOT_SET;
30719+ args->file->f_path.mnt = au_br_mnt(br);
30720+ err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag,
30721+ args->create_mode, args->opened);
30722+ if (err >= 0) {
30723+ /* some filesystems don't set FILE_CREATED while succeeded? */
30724+ if (*args->opened & FILE_CREATED)
30725+ fsnotify_create(dir, dentry);
30726+ } else
30727+ goto out;
30728+
30729+
30730+ if (!err) {
30731+ /* todo: call VFS:may_open() here */
30732+ err = open_check_o_direct(file);
30733+ /* todo: ima_file_check() too? */
30734+ if (!err && (args->open_flag & __FMODE_EXEC))
30735+ err = deny_write_access(file);
30736+ if (unlikely(err))
30737+ /* note that the file is created and still opened */
30738+ goto out;
30739+ }
30740+
5afbbe0d 30741+ au_br_get(br);
b912730e
AM
30742+ fsnotify_open(file);
30743+
30744+out:
30745+ return err;
30746+}
30747+
1facf9fc 30748+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
30749+{
30750+ int err;
30751+
1facf9fc 30752+ err = kern_path(name, flags, path);
5527c038 30753+ if (!err && d_is_positive(path->dentry))
1facf9fc 30754+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
30755+ return err;
30756+}
30757+
febd17d6
JR
30758+struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
30759+ struct dentry *parent, int len)
30760+{
30761+ struct path path = {
30762+ .mnt = NULL
30763+ };
30764+
30765+ path.dentry = lookup_one_len_unlocked(name, parent, len);
30766+ if (IS_ERR(path.dentry))
30767+ goto out;
30768+ if (d_is_positive(path.dentry))
30769+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
30770+
30771+out:
30772+ AuTraceErrPtr(path.dentry);
30773+ return path.dentry;
30774+}
30775+
1facf9fc 30776+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
30777+ int len)
30778+{
30779+ struct path path = {
30780+ .mnt = NULL
30781+ };
30782+
1308ab2a 30783+ /* VFS checks it too, but by WARN_ON_ONCE() */
5527c038 30784+ IMustLock(d_inode(parent));
1facf9fc 30785+
30786+ path.dentry = lookup_one_len(name, parent, len);
30787+ if (IS_ERR(path.dentry))
30788+ goto out;
5527c038 30789+ if (d_is_positive(path.dentry))
1facf9fc 30790+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
30791+
4f0767ce 30792+out:
4a4d8108 30793+ AuTraceErrPtr(path.dentry);
1facf9fc 30794+ return path.dentry;
30795+}
30796+
b4510431 30797+void vfsub_call_lkup_one(void *args)
2cbb1c4b 30798+{
b4510431
AM
30799+ struct vfsub_lkup_one_args *a = args;
30800+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
30801+}
30802+
1facf9fc 30803+/* ---------------------------------------------------------------------- */
30804+
30805+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
30806+ struct dentry *d2, struct au_hinode *hdir2)
30807+{
30808+ struct dentry *d;
30809+
2cbb1c4b 30810+ lockdep_off();
1facf9fc 30811+ d = lock_rename(d1, d2);
2cbb1c4b 30812+ lockdep_on();
4a4d8108 30813+ au_hn_suspend(hdir1);
1facf9fc 30814+ if (hdir1 != hdir2)
4a4d8108 30815+ au_hn_suspend(hdir2);
1facf9fc 30816+
30817+ return d;
30818+}
30819+
30820+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
30821+ struct dentry *d2, struct au_hinode *hdir2)
30822+{
4a4d8108 30823+ au_hn_resume(hdir1);
1facf9fc 30824+ if (hdir1 != hdir2)
4a4d8108 30825+ au_hn_resume(hdir2);
2cbb1c4b 30826+ lockdep_off();
1facf9fc 30827+ unlock_rename(d1, d2);
2cbb1c4b 30828+ lockdep_on();
1facf9fc 30829+}
30830+
30831+/* ---------------------------------------------------------------------- */
30832+
b4510431 30833+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 30834+{
30835+ int err;
30836+ struct dentry *d;
30837+
30838+ IMustLock(dir);
30839+
30840+ d = path->dentry;
30841+ path->dentry = d->d_parent;
b752ccd1 30842+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 30843+ path->dentry = d;
30844+ if (unlikely(err))
30845+ goto out;
30846+
c1595e42 30847+ lockdep_off();
b4510431 30848+ err = vfs_create(dir, path->dentry, mode, want_excl);
c1595e42 30849+ lockdep_on();
1facf9fc 30850+ if (!err) {
30851+ struct path tmp = *path;
30852+ int did;
30853+
30854+ vfsub_update_h_iattr(&tmp, &did);
30855+ if (did) {
30856+ tmp.dentry = path->dentry->d_parent;
30857+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30858+ }
30859+ /*ignore*/
30860+ }
30861+
4f0767ce 30862+out:
1facf9fc 30863+ return err;
30864+}
30865+
30866+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
30867+{
30868+ int err;
30869+ struct dentry *d;
30870+
30871+ IMustLock(dir);
30872+
30873+ d = path->dentry;
30874+ path->dentry = d->d_parent;
b752ccd1 30875+ err = security_path_symlink(path, d, symname);
1facf9fc 30876+ path->dentry = d;
30877+ if (unlikely(err))
30878+ goto out;
30879+
c1595e42 30880+ lockdep_off();
1facf9fc 30881+ err = vfs_symlink(dir, path->dentry, symname);
c1595e42 30882+ lockdep_on();
1facf9fc 30883+ if (!err) {
30884+ struct path tmp = *path;
30885+ int did;
30886+
30887+ vfsub_update_h_iattr(&tmp, &did);
30888+ if (did) {
30889+ tmp.dentry = path->dentry->d_parent;
30890+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30891+ }
30892+ /*ignore*/
30893+ }
30894+
4f0767ce 30895+out:
1facf9fc 30896+ return err;
30897+}
30898+
30899+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
30900+{
30901+ int err;
30902+ struct dentry *d;
30903+
30904+ IMustLock(dir);
30905+
30906+ d = path->dentry;
30907+ path->dentry = d->d_parent;
027c5e7a 30908+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 30909+ path->dentry = d;
30910+ if (unlikely(err))
30911+ goto out;
30912+
c1595e42 30913+ lockdep_off();
1facf9fc 30914+ err = vfs_mknod(dir, path->dentry, mode, dev);
c1595e42 30915+ lockdep_on();
1facf9fc 30916+ if (!err) {
30917+ struct path tmp = *path;
30918+ int did;
30919+
30920+ vfsub_update_h_iattr(&tmp, &did);
30921+ if (did) {
30922+ tmp.dentry = path->dentry->d_parent;
30923+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30924+ }
30925+ /*ignore*/
30926+ }
30927+
4f0767ce 30928+out:
1facf9fc 30929+ return err;
30930+}
30931+
30932+static int au_test_nlink(struct inode *inode)
30933+{
30934+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
30935+
30936+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
30937+ || inode->i_nlink < link_max)
30938+ return 0;
30939+ return -EMLINK;
30940+}
30941+
523b37e3
AM
30942+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
30943+ struct inode **delegated_inode)
1facf9fc 30944+{
30945+ int err;
30946+ struct dentry *d;
30947+
30948+ IMustLock(dir);
30949+
5527c038 30950+ err = au_test_nlink(d_inode(src_dentry));
1facf9fc 30951+ if (unlikely(err))
30952+ return err;
30953+
b4510431 30954+ /* we don't call may_linkat() */
1facf9fc 30955+ d = path->dentry;
30956+ path->dentry = d->d_parent;
b752ccd1 30957+ err = security_path_link(src_dentry, path, d);
1facf9fc 30958+ path->dentry = d;
30959+ if (unlikely(err))
30960+ goto out;
30961+
2cbb1c4b 30962+ lockdep_off();
523b37e3 30963+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 30964+ lockdep_on();
1facf9fc 30965+ if (!err) {
30966+ struct path tmp = *path;
30967+ int did;
30968+
30969+ /* fuse has different memory inode for the same inumber */
30970+ vfsub_update_h_iattr(&tmp, &did);
30971+ if (did) {
30972+ tmp.dentry = path->dentry->d_parent;
30973+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30974+ tmp.dentry = src_dentry;
30975+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30976+ }
30977+ /*ignore*/
30978+ }
30979+
4f0767ce 30980+out:
1facf9fc 30981+ return err;
30982+}
30983+
30984+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3 30985+ struct inode *dir, struct path *path,
f2c43d5f 30986+ struct inode **delegated_inode, unsigned int flags)
1facf9fc 30987+{
30988+ int err;
30989+ struct path tmp = {
30990+ .mnt = path->mnt
30991+ };
30992+ struct dentry *d;
30993+
30994+ IMustLock(dir);
30995+ IMustLock(src_dir);
30996+
30997+ d = path->dentry;
30998+ path->dentry = d->d_parent;
30999+ tmp.dentry = src_dentry->d_parent;
38d290e6 31000+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
1facf9fc 31001+ path->dentry = d;
31002+ if (unlikely(err))
31003+ goto out;
31004+
2cbb1c4b 31005+ lockdep_off();
523b37e3 31006+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
f2c43d5f 31007+ delegated_inode, flags);
2cbb1c4b 31008+ lockdep_on();
1facf9fc 31009+ if (!err) {
31010+ int did;
31011+
31012+ tmp.dentry = d->d_parent;
31013+ vfsub_update_h_iattr(&tmp, &did);
31014+ if (did) {
31015+ tmp.dentry = src_dentry;
31016+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
31017+ tmp.dentry = src_dentry->d_parent;
31018+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
31019+ }
31020+ /*ignore*/
31021+ }
31022+
4f0767ce 31023+out:
1facf9fc 31024+ return err;
31025+}
31026+
31027+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
31028+{
31029+ int err;
31030+ struct dentry *d;
31031+
31032+ IMustLock(dir);
31033+
31034+ d = path->dentry;
31035+ path->dentry = d->d_parent;
b752ccd1 31036+ err = security_path_mkdir(path, d, mode);
1facf9fc 31037+ path->dentry = d;
31038+ if (unlikely(err))
31039+ goto out;
31040+
c1595e42 31041+ lockdep_off();
1facf9fc 31042+ err = vfs_mkdir(dir, path->dentry, mode);
c1595e42 31043+ lockdep_on();
1facf9fc 31044+ if (!err) {
31045+ struct path tmp = *path;
31046+ int did;
31047+
31048+ vfsub_update_h_iattr(&tmp, &did);
31049+ if (did) {
31050+ tmp.dentry = path->dentry->d_parent;
31051+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
31052+ }
31053+ /*ignore*/
31054+ }
31055+
4f0767ce 31056+out:
1facf9fc 31057+ return err;
31058+}
31059+
31060+int vfsub_rmdir(struct inode *dir, struct path *path)
31061+{
31062+ int err;
31063+ struct dentry *d;
31064+
31065+ IMustLock(dir);
31066+
31067+ d = path->dentry;
31068+ path->dentry = d->d_parent;
b752ccd1 31069+ err = security_path_rmdir(path, d);
1facf9fc 31070+ path->dentry = d;
31071+ if (unlikely(err))
31072+ goto out;
31073+
2cbb1c4b 31074+ lockdep_off();
1facf9fc 31075+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 31076+ lockdep_on();
1facf9fc 31077+ if (!err) {
31078+ struct path tmp = {
31079+ .dentry = path->dentry->d_parent,
31080+ .mnt = path->mnt
31081+ };
31082+
31083+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
31084+ }
31085+
4f0767ce 31086+out:
1facf9fc 31087+ return err;
31088+}
31089+
31090+/* ---------------------------------------------------------------------- */
31091+
9dbd164d 31092+/* todo: support mmap_sem? */
1facf9fc 31093+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
31094+ loff_t *ppos)
31095+{
31096+ ssize_t err;
31097+
2cbb1c4b 31098+ lockdep_off();
1facf9fc 31099+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 31100+ lockdep_on();
1facf9fc 31101+ if (err >= 0)
31102+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
31103+ return err;
31104+}
31105+
31106+/* todo: kernel_read()? */
31107+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
31108+ loff_t *ppos)
31109+{
31110+ ssize_t err;
31111+ mm_segment_t oldfs;
b752ccd1
AM
31112+ union {
31113+ void *k;
31114+ char __user *u;
31115+ } buf;
1facf9fc 31116+
b752ccd1 31117+ buf.k = kbuf;
1facf9fc 31118+ oldfs = get_fs();
31119+ set_fs(KERNEL_DS);
b752ccd1 31120+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 31121+ set_fs(oldfs);
31122+ return err;
31123+}
31124+
31125+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
31126+ loff_t *ppos)
31127+{
31128+ ssize_t err;
31129+
2cbb1c4b 31130+ lockdep_off();
1facf9fc 31131+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 31132+ lockdep_on();
1facf9fc 31133+ if (err >= 0)
31134+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
31135+ return err;
31136+}
31137+
31138+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
31139+{
31140+ ssize_t err;
31141+ mm_segment_t oldfs;
b752ccd1
AM
31142+ union {
31143+ void *k;
31144+ const char __user *u;
31145+ } buf;
1facf9fc 31146+
b752ccd1 31147+ buf.k = kbuf;
1facf9fc 31148+ oldfs = get_fs();
31149+ set_fs(KERNEL_DS);
b752ccd1 31150+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 31151+ set_fs(oldfs);
31152+ return err;
31153+}
31154+
4a4d8108
AM
31155+int vfsub_flush(struct file *file, fl_owner_t id)
31156+{
31157+ int err;
31158+
31159+ err = 0;
523b37e3 31160+ if (file->f_op->flush) {
2000de60 31161+ if (!au_test_nfs(file->f_path.dentry->d_sb))
2cbb1c4b
JR
31162+ err = file->f_op->flush(file, id);
31163+ else {
31164+ lockdep_off();
31165+ err = file->f_op->flush(file, id);
31166+ lockdep_on();
31167+ }
4a4d8108
AM
31168+ if (!err)
31169+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
31170+ /*ignore*/
31171+ }
31172+ return err;
31173+}
31174+
392086de 31175+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 31176+{
31177+ int err;
31178+
523b37e3 31179+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 31180+
2cbb1c4b 31181+ lockdep_off();
392086de 31182+ err = iterate_dir(file, ctx);
2cbb1c4b 31183+ lockdep_on();
1facf9fc 31184+ if (err >= 0)
31185+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
1c60b727 31186+
1facf9fc 31187+ return err;
31188+}
31189+
31190+long vfsub_splice_to(struct file *in, loff_t *ppos,
31191+ struct pipe_inode_info *pipe, size_t len,
31192+ unsigned int flags)
31193+{
31194+ long err;
31195+
2cbb1c4b 31196+ lockdep_off();
0fc653ad 31197+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 31198+ lockdep_on();
4a4d8108 31199+ file_accessed(in);
1facf9fc 31200+ if (err >= 0)
31201+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
31202+ return err;
31203+}
31204+
31205+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
31206+ loff_t *ppos, size_t len, unsigned int flags)
31207+{
31208+ long err;
31209+
2cbb1c4b 31210+ lockdep_off();
0fc653ad 31211+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 31212+ lockdep_on();
1facf9fc 31213+ if (err >= 0)
31214+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
31215+ return err;
31216+}
31217+
53392da6
AM
31218+int vfsub_fsync(struct file *file, struct path *path, int datasync)
31219+{
31220+ int err;
31221+
31222+ /* file can be NULL */
31223+ lockdep_off();
31224+ err = vfs_fsync(file, datasync);
31225+ lockdep_on();
31226+ if (!err) {
31227+ if (!path) {
31228+ AuDebugOn(!file);
31229+ path = &file->f_path;
31230+ }
31231+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
31232+ }
31233+ return err;
31234+}
31235+
1facf9fc 31236+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
31237+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
31238+ struct file *h_file)
31239+{
31240+ int err;
31241+ struct inode *h_inode;
c06a8ce3 31242+ struct super_block *h_sb;
1facf9fc 31243+
1facf9fc 31244+ if (!h_file) {
c06a8ce3
AM
31245+ err = vfsub_truncate(h_path, length);
31246+ goto out;
1facf9fc 31247+ }
31248+
5527c038 31249+ h_inode = d_inode(h_path->dentry);
c06a8ce3
AM
31250+ h_sb = h_inode->i_sb;
31251+ lockdep_off();
31252+ sb_start_write(h_sb);
31253+ lockdep_on();
1facf9fc 31254+ err = locks_verify_truncate(h_inode, h_file, length);
31255+ if (!err)
953406b4 31256+ err = security_path_truncate(h_path);
2cbb1c4b
JR
31257+ if (!err) {
31258+ lockdep_off();
1facf9fc 31259+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
31260+ lockdep_on();
31261+ }
c06a8ce3
AM
31262+ lockdep_off();
31263+ sb_end_write(h_sb);
31264+ lockdep_on();
1facf9fc 31265+
4f0767ce 31266+out:
1facf9fc 31267+ return err;
31268+}
31269+
31270+/* ---------------------------------------------------------------------- */
31271+
31272+struct au_vfsub_mkdir_args {
31273+ int *errp;
31274+ struct inode *dir;
31275+ struct path *path;
31276+ int mode;
31277+};
31278+
31279+static void au_call_vfsub_mkdir(void *args)
31280+{
31281+ struct au_vfsub_mkdir_args *a = args;
31282+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
31283+}
31284+
31285+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
31286+{
31287+ int err, do_sio, wkq_err;
31288+
31289+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
31290+ if (!do_sio) {
31291+ lockdep_off();
1facf9fc 31292+ err = vfsub_mkdir(dir, path, mode);
c1595e42
JR
31293+ lockdep_on();
31294+ } else {
1facf9fc 31295+ struct au_vfsub_mkdir_args args = {
31296+ .errp = &err,
31297+ .dir = dir,
31298+ .path = path,
31299+ .mode = mode
31300+ };
31301+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
31302+ if (unlikely(wkq_err))
31303+ err = wkq_err;
31304+ }
31305+
31306+ return err;
31307+}
31308+
31309+struct au_vfsub_rmdir_args {
31310+ int *errp;
31311+ struct inode *dir;
31312+ struct path *path;
31313+};
31314+
31315+static void au_call_vfsub_rmdir(void *args)
31316+{
31317+ struct au_vfsub_rmdir_args *a = args;
31318+ *a->errp = vfsub_rmdir(a->dir, a->path);
31319+}
31320+
31321+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
31322+{
31323+ int err, do_sio, wkq_err;
31324+
31325+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
31326+ if (!do_sio) {
31327+ lockdep_off();
1facf9fc 31328+ err = vfsub_rmdir(dir, path);
c1595e42
JR
31329+ lockdep_on();
31330+ } else {
1facf9fc 31331+ struct au_vfsub_rmdir_args args = {
31332+ .errp = &err,
31333+ .dir = dir,
31334+ .path = path
31335+ };
31336+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
31337+ if (unlikely(wkq_err))
31338+ err = wkq_err;
31339+ }
31340+
31341+ return err;
31342+}
31343+
31344+/* ---------------------------------------------------------------------- */
31345+
31346+struct notify_change_args {
31347+ int *errp;
31348+ struct path *path;
31349+ struct iattr *ia;
523b37e3 31350+ struct inode **delegated_inode;
1facf9fc 31351+};
31352+
31353+static void call_notify_change(void *args)
31354+{
31355+ struct notify_change_args *a = args;
31356+ struct inode *h_inode;
31357+
5527c038 31358+ h_inode = d_inode(a->path->dentry);
1facf9fc 31359+ IMustLock(h_inode);
31360+
31361+ *a->errp = -EPERM;
31362+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
c1595e42 31363+ lockdep_off();
523b37e3
AM
31364+ *a->errp = notify_change(a->path->dentry, a->ia,
31365+ a->delegated_inode);
c1595e42 31366+ lockdep_on();
1facf9fc 31367+ if (!*a->errp)
31368+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
31369+ }
31370+ AuTraceErr(*a->errp);
31371+}
31372+
523b37e3
AM
31373+int vfsub_notify_change(struct path *path, struct iattr *ia,
31374+ struct inode **delegated_inode)
1facf9fc 31375+{
31376+ int err;
31377+ struct notify_change_args args = {
523b37e3
AM
31378+ .errp = &err,
31379+ .path = path,
31380+ .ia = ia,
31381+ .delegated_inode = delegated_inode
1facf9fc 31382+ };
31383+
31384+ call_notify_change(&args);
31385+
31386+ return err;
31387+}
31388+
523b37e3
AM
31389+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
31390+ struct inode **delegated_inode)
1facf9fc 31391+{
31392+ int err, wkq_err;
31393+ struct notify_change_args args = {
523b37e3
AM
31394+ .errp = &err,
31395+ .path = path,
31396+ .ia = ia,
31397+ .delegated_inode = delegated_inode
1facf9fc 31398+ };
31399+
31400+ wkq_err = au_wkq_wait(call_notify_change, &args);
31401+ if (unlikely(wkq_err))
31402+ err = wkq_err;
31403+
31404+ return err;
31405+}
31406+
31407+/* ---------------------------------------------------------------------- */
31408+
31409+struct unlink_args {
31410+ int *errp;
31411+ struct inode *dir;
31412+ struct path *path;
523b37e3 31413+ struct inode **delegated_inode;
1facf9fc 31414+};
31415+
31416+static void call_unlink(void *args)
31417+{
31418+ struct unlink_args *a = args;
31419+ struct dentry *d = a->path->dentry;
31420+ struct inode *h_inode;
31421+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
c1595e42 31422+ && au_dcount(d) == 1);
1facf9fc 31423+
31424+ IMustLock(a->dir);
31425+
31426+ a->path->dentry = d->d_parent;
31427+ *a->errp = security_path_unlink(a->path, d);
31428+ a->path->dentry = d;
31429+ if (unlikely(*a->errp))
31430+ return;
31431+
31432+ if (!stop_sillyrename)
31433+ dget(d);
5527c038
JR
31434+ h_inode = NULL;
31435+ if (d_is_positive(d)) {
31436+ h_inode = d_inode(d);
027c5e7a 31437+ ihold(h_inode);
5527c038 31438+ }
1facf9fc 31439+
2cbb1c4b 31440+ lockdep_off();
523b37e3 31441+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 31442+ lockdep_on();
1facf9fc 31443+ if (!*a->errp) {
31444+ struct path tmp = {
31445+ .dentry = d->d_parent,
31446+ .mnt = a->path->mnt
31447+ };
31448+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
31449+ }
31450+
31451+ if (!stop_sillyrename)
31452+ dput(d);
31453+ if (h_inode)
31454+ iput(h_inode);
31455+
31456+ AuTraceErr(*a->errp);
31457+}
31458+
31459+/*
31460+ * @dir: must be locked.
31461+ * @dentry: target dentry.
31462+ */
523b37e3
AM
31463+int vfsub_unlink(struct inode *dir, struct path *path,
31464+ struct inode **delegated_inode, int force)
1facf9fc 31465+{
31466+ int err;
31467+ struct unlink_args args = {
523b37e3
AM
31468+ .errp = &err,
31469+ .dir = dir,
31470+ .path = path,
31471+ .delegated_inode = delegated_inode
1facf9fc 31472+ };
31473+
31474+ if (!force)
31475+ call_unlink(&args);
31476+ else {
31477+ int wkq_err;
31478+
31479+ wkq_err = au_wkq_wait(call_unlink, &args);
31480+ if (unlikely(wkq_err))
31481+ err = wkq_err;
31482+ }
31483+
31484+ return err;
31485+}
7f207e10
AM
31486diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
31487--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
3c1bdaff
AM
31488+++ linux/fs/aufs/vfsub.h 2017-09-05 10:42:11.058755349 +0200
31489@@ -0,0 +1,360 @@
1facf9fc 31490+/*
a2654f78 31491+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 31492+ *
31493+ * This program, aufs is free software; you can redistribute it and/or modify
31494+ * it under the terms of the GNU General Public License as published by
31495+ * the Free Software Foundation; either version 2 of the License, or
31496+ * (at your option) any later version.
dece6358
AM
31497+ *
31498+ * This program is distributed in the hope that it will be useful,
31499+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31500+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31501+ * GNU General Public License for more details.
31502+ *
31503+ * You should have received a copy of the GNU General Public License
523b37e3 31504+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31505+ */
31506+
31507+/*
31508+ * sub-routines for VFS
31509+ */
31510+
31511+#ifndef __AUFS_VFSUB_H__
31512+#define __AUFS_VFSUB_H__
31513+
31514+#ifdef __KERNEL__
31515+
31516+#include <linux/fs.h>
b4510431 31517+#include <linux/mount.h>
8cdd5066 31518+#include <linux/posix_acl.h>
c1595e42 31519+#include <linux/xattr.h>
7f207e10 31520+#include "debug.h"
1facf9fc 31521+
7f207e10 31522+/* copied from linux/fs/internal.h */
2cbb1c4b 31523+/* todo: BAD approach!! */
c06a8ce3 31524+extern void __mnt_drop_write(struct vfsmount *);
b912730e 31525+extern int open_check_o_direct(struct file *f);
7f207e10
AM
31526+
31527+/* ---------------------------------------------------------------------- */
1facf9fc 31528+
31529+/* lock subclass for lower inode */
31530+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
31531+/* reduce? gave up. */
31532+enum {
c1595e42 31533+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
1facf9fc 31534+ AuLsc_I_PARENT, /* lower inode, parent first */
31535+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 31536+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 31537+ AuLsc_I_CHILD,
31538+ AuLsc_I_CHILD2,
31539+ AuLsc_I_End
31540+};
31541+
31542+/* to debug easier, do not make them inlined functions */
31543+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
febd17d6 31544+#define IMustLock(i) AuDebugOn(!inode_is_locked(i))
1facf9fc 31545+
3c1bdaff
AM
31546+/* why VFS doesn't define it? */
31547+static inline
31548+void vfsub_inode_lock_shared_nested(struct inode *inode, unsigned int sc)
31549+{
31550+ down_read_nested(&inode->i_rwsem, sc);
31551+}
31552+
1facf9fc 31553+/* ---------------------------------------------------------------------- */
31554+
7f207e10
AM
31555+static inline void vfsub_drop_nlink(struct inode *inode)
31556+{
31557+ AuDebugOn(!inode->i_nlink);
31558+ drop_nlink(inode);
31559+}
31560+
027c5e7a
AM
31561+static inline void vfsub_dead_dir(struct inode *inode)
31562+{
31563+ AuDebugOn(!S_ISDIR(inode->i_mode));
31564+ inode->i_flags |= S_DEAD;
31565+ clear_nlink(inode);
31566+}
31567+
392086de
AM
31568+static inline int vfsub_native_ro(struct inode *inode)
31569+{
31570+ return (inode->i_sb->s_flags & MS_RDONLY)
31571+ || IS_RDONLY(inode)
31572+ /* || IS_APPEND(inode) */
31573+ || IS_IMMUTABLE(inode);
31574+}
31575+
8cdd5066
JR
31576+#ifdef CONFIG_AUFS_BR_FUSE
31577+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb);
31578+#else
31579+AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb);
31580+#endif
31581+
a2654f78
AM
31582+int vfsub_sync_filesystem(struct super_block *h_sb, int wait);
31583+
7f207e10
AM
31584+/* ---------------------------------------------------------------------- */
31585+
31586+int vfsub_update_h_iattr(struct path *h_path, int *did);
31587+struct file *vfsub_dentry_open(struct path *path, int flags);
31588+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
b912730e
AM
31589+struct vfsub_aopen_args {
31590+ struct file *file;
31591+ unsigned int open_flag;
31592+ umode_t create_mode;
31593+ int *opened;
31594+};
31595+struct au_branch;
31596+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
31597+ struct vfsub_aopen_args *args, struct au_branch *br);
1facf9fc 31598+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 31599+
febd17d6
JR
31600+struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
31601+ struct dentry *parent, int len);
1facf9fc 31602+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
31603+ int len);
b4510431
AM
31604+
31605+struct vfsub_lkup_one_args {
31606+ struct dentry **errp;
31607+ struct qstr *name;
31608+ struct dentry *parent;
31609+};
31610+
31611+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
31612+ struct dentry *parent)
31613+{
31614+ return vfsub_lookup_one_len(name->name, parent, name->len);
31615+}
31616+
31617+void vfsub_call_lkup_one(void *args);
31618+
31619+/* ---------------------------------------------------------------------- */
31620+
31621+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
31622+{
31623+ int err;
076b876e 31624+
b4510431
AM
31625+ lockdep_off();
31626+ err = mnt_want_write(mnt);
31627+ lockdep_on();
31628+ return err;
31629+}
31630+
31631+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
31632+{
31633+ lockdep_off();
31634+ mnt_drop_write(mnt);
31635+ lockdep_on();
31636+}
1facf9fc 31637+
7e9cd9fe 31638+#if 0 /* reserved */
c06a8ce3
AM
31639+static inline void vfsub_mnt_drop_write_file(struct file *file)
31640+{
31641+ lockdep_off();
31642+ mnt_drop_write_file(file);
31643+ lockdep_on();
31644+}
7e9cd9fe 31645+#endif
c06a8ce3 31646+
1facf9fc 31647+/* ---------------------------------------------------------------------- */
31648+
31649+struct au_hinode;
31650+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
31651+ struct dentry *d2, struct au_hinode *hdir2);
31652+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
31653+ struct dentry *d2, struct au_hinode *hdir2);
31654+
537831f9
AM
31655+int vfsub_create(struct inode *dir, struct path *path, int mode,
31656+ bool want_excl);
1facf9fc 31657+int vfsub_symlink(struct inode *dir, struct path *path,
31658+ const char *symname);
31659+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
31660+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 31661+ struct path *path, struct inode **delegated_inode);
1facf9fc 31662+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3 31663+ struct inode *hdir, struct path *path,
f2c43d5f 31664+ struct inode **delegated_inode, unsigned int flags);
1facf9fc 31665+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
31666+int vfsub_rmdir(struct inode *dir, struct path *path);
31667+
31668+/* ---------------------------------------------------------------------- */
31669+
31670+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
31671+ loff_t *ppos);
31672+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
31673+ loff_t *ppos);
31674+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
31675+ loff_t *ppos);
31676+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
31677+ loff_t *ppos);
4a4d8108 31678+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
31679+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
31680+
c06a8ce3
AM
31681+static inline loff_t vfsub_f_size_read(struct file *file)
31682+{
31683+ return i_size_read(file_inode(file));
31684+}
31685+
4a4d8108
AM
31686+static inline unsigned int vfsub_file_flags(struct file *file)
31687+{
31688+ unsigned int flags;
31689+
31690+ spin_lock(&file->f_lock);
31691+ flags = file->f_flags;
31692+ spin_unlock(&file->f_lock);
31693+
31694+ return flags;
31695+}
1308ab2a 31696+
f0c0a007
AM
31697+static inline int vfsub_file_execed(struct file *file)
31698+{
31699+ /* todo: direct access f_flags */
31700+ return !!(vfsub_file_flags(file) & __FMODE_EXEC);
31701+}
31702+
7e9cd9fe 31703+#if 0 /* reserved */
1facf9fc 31704+static inline void vfsub_file_accessed(struct file *h_file)
31705+{
31706+ file_accessed(h_file);
31707+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
31708+}
7e9cd9fe 31709+#endif
1facf9fc 31710+
79b8bda9 31711+#if 0 /* reserved */
1facf9fc 31712+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
31713+ struct dentry *h_dentry)
31714+{
31715+ struct path h_path = {
31716+ .dentry = h_dentry,
31717+ .mnt = h_mnt
31718+ };
92d182d2 31719+ touch_atime(&h_path);
1facf9fc 31720+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
31721+}
79b8bda9 31722+#endif
1facf9fc 31723+
0c3ec466
AM
31724+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
31725+ int flags)
31726+{
5afbbe0d 31727+ return update_time(h_inode, ts, flags);
0c3ec466
AM
31728+ /* no vfsub_update_h_iattr() since we don't have struct path */
31729+}
31730+
8cdd5066
JR
31731+#ifdef CONFIG_FS_POSIX_ACL
31732+static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode)
31733+{
31734+ int err;
31735+
31736+ err = posix_acl_chmod(h_inode, h_mode);
31737+ if (err == -EOPNOTSUPP)
31738+ err = 0;
31739+ return err;
31740+}
31741+#else
31742+AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode);
31743+#endif
31744+
4a4d8108
AM
31745+long vfsub_splice_to(struct file *in, loff_t *ppos,
31746+ struct pipe_inode_info *pipe, size_t len,
31747+ unsigned int flags);
31748+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
31749+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
31750+
31751+static inline long vfsub_truncate(struct path *path, loff_t length)
31752+{
31753+ long err;
076b876e 31754+
c06a8ce3
AM
31755+ lockdep_off();
31756+ err = vfs_truncate(path, length);
31757+ lockdep_on();
31758+ return err;
31759+}
31760+
4a4d8108
AM
31761+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
31762+ struct file *h_file);
53392da6 31763+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 31764+
521ced18
JR
31765+/*
31766+ * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such
31767+ * ioctl.
31768+ */
31769+static inline int vfsub_clone_file_range(struct file *src, struct file *dst,
31770+ u64 len)
31771+{
31772+ int err;
31773+
31774+ lockdep_off();
31775+ err = vfs_clone_file_range(src, 0, dst, 0, len);
31776+ lockdep_on();
31777+
31778+ return err;
31779+}
31780+
31781+/* copy_file_range(2) is a systemcall */
31782+static inline ssize_t vfsub_copy_file_range(struct file *src, loff_t src_pos,
31783+ struct file *dst, loff_t dst_pos,
31784+ size_t len, unsigned int flags)
31785+{
31786+ ssize_t ssz;
31787+
31788+ lockdep_off();
31789+ ssz = vfs_copy_file_range(src, src_pos, dst, dst_pos, len, flags);
31790+ lockdep_on();
31791+
31792+ return ssz;
31793+}
31794+
1facf9fc 31795+/* ---------------------------------------------------------------------- */
31796+
31797+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
31798+{
31799+ loff_t err;
31800+
2cbb1c4b 31801+ lockdep_off();
1facf9fc 31802+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 31803+ lockdep_on();
1facf9fc 31804+ return err;
31805+}
31806+
31807+/* ---------------------------------------------------------------------- */
31808+
4a4d8108
AM
31809+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
31810+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
31811+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
31812+ struct inode **delegated_inode);
31813+int vfsub_notify_change(struct path *path, struct iattr *ia,
31814+ struct inode **delegated_inode);
31815+int vfsub_unlink(struct inode *dir, struct path *path,
31816+ struct inode **delegated_inode, int force);
4a4d8108 31817+
521ced18
JR
31818+static inline int vfsub_getattr(const struct path *path, struct kstat *st)
31819+{
31820+ return vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
31821+}
31822+
c1595e42
JR
31823+/* ---------------------------------------------------------------------- */
31824+
31825+static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
31826+ const void *value, size_t size, int flags)
31827+{
31828+ int err;
31829+
31830+ lockdep_off();
31831+ err = vfs_setxattr(dentry, name, value, size, flags);
31832+ lockdep_on();
31833+
31834+ return err;
31835+}
31836+
31837+static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
31838+{
31839+ int err;
31840+
31841+ lockdep_off();
31842+ err = vfs_removexattr(dentry, name);
31843+ lockdep_on();
31844+
31845+ return err;
31846+}
31847+
1facf9fc 31848+#endif /* __KERNEL__ */
31849+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
31850diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
31851--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 31852+++ linux/fs/aufs/wbr_policy.c 2017-07-29 12:14:25.906375514 +0200
f2c43d5f 31853@@ -0,0 +1,830 @@
1facf9fc 31854+/*
a2654f78 31855+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 31856+ *
31857+ * This program, aufs is free software; you can redistribute it and/or modify
31858+ * it under the terms of the GNU General Public License as published by
31859+ * the Free Software Foundation; either version 2 of the License, or
31860+ * (at your option) any later version.
dece6358
AM
31861+ *
31862+ * This program is distributed in the hope that it will be useful,
31863+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31864+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31865+ * GNU General Public License for more details.
31866+ *
31867+ * You should have received a copy of the GNU General Public License
523b37e3 31868+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31869+ */
31870+
31871+/*
31872+ * policies for selecting one among multiple writable branches
31873+ */
31874+
31875+#include <linux/statfs.h>
31876+#include "aufs.h"
31877+
31878+/* subset of cpup_attr() */
31879+static noinline_for_stack
31880+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
31881+{
31882+ int err, sbits;
31883+ struct iattr ia;
31884+ struct inode *h_isrc;
31885+
5527c038 31886+ h_isrc = d_inode(h_src);
1facf9fc 31887+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
31888+ ia.ia_mode = h_isrc->i_mode;
31889+ ia.ia_uid = h_isrc->i_uid;
31890+ ia.ia_gid = h_isrc->i_gid;
31891+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
5527c038 31892+ au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags);
523b37e3
AM
31893+ /* no delegation since it is just created */
31894+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 31895+
31896+ /* is this nfs only? */
31897+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
31898+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
31899+ ia.ia_mode = h_isrc->i_mode;
523b37e3 31900+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 31901+ }
31902+
31903+ return err;
31904+}
31905+
31906+#define AuCpdown_PARENT_OPQ 1
31907+#define AuCpdown_WHED (1 << 1)
31908+#define AuCpdown_MADE_DIR (1 << 2)
31909+#define AuCpdown_DIROPQ (1 << 3)
31910+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
31911+#define au_fset_cpdown(flags, name) \
31912+ do { (flags) |= AuCpdown_##name; } while (0)
31913+#define au_fclr_cpdown(flags, name) \
31914+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 31915+
1facf9fc 31916+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 31917+ unsigned int *flags)
1facf9fc 31918+{
31919+ int err;
31920+ struct dentry *opq_dentry;
31921+
31922+ opq_dentry = au_diropq_create(dentry, bdst);
31923+ err = PTR_ERR(opq_dentry);
31924+ if (IS_ERR(opq_dentry))
31925+ goto out;
31926+ dput(opq_dentry);
c2b27bf2 31927+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 31928+
4f0767ce 31929+out:
1facf9fc 31930+ return err;
31931+}
31932+
31933+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
31934+ struct inode *dir, aufs_bindex_t bdst)
31935+{
31936+ int err;
31937+ struct path h_path;
31938+ struct au_branch *br;
31939+
31940+ br = au_sbr(dentry->d_sb, bdst);
31941+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
31942+ err = PTR_ERR(h_path.dentry);
31943+ if (IS_ERR(h_path.dentry))
31944+ goto out;
31945+
31946+ err = 0;
5527c038 31947+ if (d_is_positive(h_path.dentry)) {
86dc4139 31948+ h_path.mnt = au_br_mnt(br);
1facf9fc 31949+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
31950+ dentry);
31951+ }
31952+ dput(h_path.dentry);
31953+
4f0767ce 31954+out:
1facf9fc 31955+ return err;
31956+}
31957+
31958+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 31959+ struct au_pin *pin,
1facf9fc 31960+ struct dentry *h_parent, void *arg)
31961+{
31962+ int err, rerr;
5afbbe0d 31963+ aufs_bindex_t bopq, btop;
1facf9fc 31964+ struct path h_path;
31965+ struct dentry *parent;
31966+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 31967+ unsigned int *flags = arg;
1facf9fc 31968+
5afbbe0d 31969+ btop = au_dbtop(dentry);
1facf9fc 31970+ /* dentry is di-locked */
31971+ parent = dget_parent(dentry);
5527c038
JR
31972+ dir = d_inode(parent);
31973+ h_dir = d_inode(h_parent);
1facf9fc 31974+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
31975+ IMustLock(h_dir);
31976+
86dc4139 31977+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 31978+ if (unlikely(err < 0))
31979+ goto out;
31980+ h_path.dentry = au_h_dptr(dentry, bdst);
31981+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
31982+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
31983+ S_IRWXU | S_IRUGO | S_IXUGO);
31984+ if (unlikely(err))
31985+ goto out_put;
c2b27bf2 31986+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 31987+
1facf9fc 31988+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
31989+ au_fclr_cpdown(*flags, WHED);
31990+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 31991+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
31992+ au_fset_cpdown(*flags, WHED);
31993+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
31994+ au_fset_cpdown(*flags, PARENT_OPQ);
5527c038 31995+ h_inode = d_inode(h_path.dentry);
febd17d6 31996+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
c2b27bf2
AM
31997+ if (au_ftest_cpdown(*flags, WHED)) {
31998+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 31999+ if (unlikely(err)) {
febd17d6 32000+ inode_unlock(h_inode);
1facf9fc 32001+ goto out_dir;
32002+ }
32003+ }
32004+
5afbbe0d 32005+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, btop));
febd17d6 32006+ inode_unlock(h_inode);
1facf9fc 32007+ if (unlikely(err))
32008+ goto out_opq;
32009+
c2b27bf2 32010+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 32011+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
32012+ if (unlikely(err))
32013+ goto out_opq;
32014+ }
32015+
5527c038 32016+ inode = d_inode(dentry);
5afbbe0d
AM
32017+ if (au_ibbot(inode) < bdst)
32018+ au_set_ibbot(inode, bdst);
1facf9fc 32019+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
32020+ au_hi_flags(inode, /*isdir*/1));
076b876e 32021+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
1facf9fc 32022+ goto out; /* success */
32023+
32024+ /* revert */
4f0767ce 32025+out_opq:
c2b27bf2 32026+ if (au_ftest_cpdown(*flags, DIROPQ)) {
febd17d6 32027+ inode_lock_nested(h_inode, AuLsc_I_CHILD);
1facf9fc 32028+ rerr = au_diropq_remove(dentry, bdst);
febd17d6 32029+ inode_unlock(h_inode);
1facf9fc 32030+ if (unlikely(rerr)) {
523b37e3
AM
32031+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
32032+ dentry, bdst, rerr);
1facf9fc 32033+ err = -EIO;
32034+ goto out;
32035+ }
32036+ }
4f0767ce 32037+out_dir:
c2b27bf2 32038+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 32039+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
32040+ if (unlikely(rerr)) {
523b37e3
AM
32041+ AuIOErr("failed removing %pd b%d (%d)\n",
32042+ dentry, bdst, rerr);
1facf9fc 32043+ err = -EIO;
32044+ }
32045+ }
4f0767ce 32046+out_put:
1facf9fc 32047+ au_set_h_dptr(dentry, bdst, NULL);
5afbbe0d
AM
32048+ if (au_dbbot(dentry) == bdst)
32049+ au_update_dbbot(dentry);
4f0767ce 32050+out:
1facf9fc 32051+ dput(parent);
32052+ return err;
32053+}
32054+
32055+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
32056+{
32057+ int err;
c2b27bf2 32058+ unsigned int flags;
1facf9fc 32059+
c2b27bf2
AM
32060+ flags = 0;
32061+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 32062+
32063+ return err;
32064+}
32065+
32066+/* ---------------------------------------------------------------------- */
32067+
32068+/* policies for create */
32069+
c2b27bf2 32070+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
32071+{
32072+ int err, i, j, ndentry;
32073+ aufs_bindex_t bopq;
32074+ struct au_dcsub_pages dpages;
32075+ struct au_dpage *dpage;
32076+ struct dentry **dentries, *parent, *d;
32077+
32078+ err = au_dpages_init(&dpages, GFP_NOFS);
32079+ if (unlikely(err))
32080+ goto out;
32081+ parent = dget_parent(dentry);
027c5e7a 32082+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
32083+ if (unlikely(err))
32084+ goto out_free;
32085+
32086+ err = bindex;
32087+ for (i = 0; i < dpages.ndpage; i++) {
32088+ dpage = dpages.dpages + i;
32089+ dentries = dpage->dentries;
32090+ ndentry = dpage->ndentry;
32091+ for (j = 0; j < ndentry; j++) {
32092+ d = dentries[j];
32093+ di_read_lock_parent2(d, !AuLock_IR);
32094+ bopq = au_dbdiropq(d);
32095+ di_read_unlock(d, !AuLock_IR);
32096+ if (bopq >= 0 && bopq < err)
32097+ err = bopq;
32098+ }
32099+ }
32100+
32101+out_free:
32102+ dput(parent);
32103+ au_dpages_free(&dpages);
32104+out:
32105+ return err;
32106+}
32107+
1facf9fc 32108+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
32109+{
32110+ for (; bindex >= 0; bindex--)
32111+ if (!au_br_rdonly(au_sbr(sb, bindex)))
32112+ return bindex;
32113+ return -EROFS;
32114+}
32115+
32116+/* top down parent */
392086de
AM
32117+static int au_wbr_create_tdp(struct dentry *dentry,
32118+ unsigned int flags __maybe_unused)
1facf9fc 32119+{
32120+ int err;
5afbbe0d 32121+ aufs_bindex_t btop, bindex;
1facf9fc 32122+ struct super_block *sb;
32123+ struct dentry *parent, *h_parent;
32124+
32125+ sb = dentry->d_sb;
5afbbe0d
AM
32126+ btop = au_dbtop(dentry);
32127+ err = btop;
32128+ if (!au_br_rdonly(au_sbr(sb, btop)))
1facf9fc 32129+ goto out;
32130+
32131+ err = -EROFS;
32132+ parent = dget_parent(dentry);
5afbbe0d 32133+ for (bindex = au_dbtop(parent); bindex < btop; bindex++) {
1facf9fc 32134+ h_parent = au_h_dptr(parent, bindex);
5527c038 32135+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 32136+ continue;
32137+
32138+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
32139+ err = bindex;
32140+ break;
32141+ }
32142+ }
32143+ dput(parent);
32144+
32145+ /* bottom up here */
4a4d8108 32146+ if (unlikely(err < 0)) {
5afbbe0d 32147+ err = au_wbr_bu(sb, btop - 1);
4a4d8108
AM
32148+ if (err >= 0)
32149+ err = au_wbr_nonopq(dentry, err);
32150+ }
1facf9fc 32151+
4f0767ce 32152+out:
1facf9fc 32153+ AuDbg("b%d\n", err);
32154+ return err;
32155+}
32156+
32157+/* ---------------------------------------------------------------------- */
32158+
32159+/* an exception for the policy other than tdp */
32160+static int au_wbr_create_exp(struct dentry *dentry)
32161+{
32162+ int err;
32163+ aufs_bindex_t bwh, bdiropq;
32164+ struct dentry *parent;
32165+
32166+ err = -1;
32167+ bwh = au_dbwh(dentry);
32168+ parent = dget_parent(dentry);
32169+ bdiropq = au_dbdiropq(parent);
32170+ if (bwh >= 0) {
32171+ if (bdiropq >= 0)
32172+ err = min(bdiropq, bwh);
32173+ else
32174+ err = bwh;
32175+ AuDbg("%d\n", err);
32176+ } else if (bdiropq >= 0) {
32177+ err = bdiropq;
32178+ AuDbg("%d\n", err);
32179+ }
32180+ dput(parent);
32181+
4a4d8108
AM
32182+ if (err >= 0)
32183+ err = au_wbr_nonopq(dentry, err);
32184+
1facf9fc 32185+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
32186+ err = -1;
32187+
32188+ AuDbg("%d\n", err);
32189+ return err;
32190+}
32191+
32192+/* ---------------------------------------------------------------------- */
32193+
32194+/* round robin */
32195+static int au_wbr_create_init_rr(struct super_block *sb)
32196+{
32197+ int err;
32198+
5afbbe0d 32199+ err = au_wbr_bu(sb, au_sbbot(sb));
1facf9fc 32200+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 32201+ /* smp_mb(); */
1facf9fc 32202+
32203+ AuDbg("b%d\n", err);
32204+ return err;
32205+}
32206+
392086de 32207+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 32208+{
32209+ int err, nbr;
32210+ unsigned int u;
5afbbe0d 32211+ aufs_bindex_t bindex, bbot;
1facf9fc 32212+ struct super_block *sb;
32213+ atomic_t *next;
32214+
32215+ err = au_wbr_create_exp(dentry);
32216+ if (err >= 0)
32217+ goto out;
32218+
32219+ sb = dentry->d_sb;
32220+ next = &au_sbi(sb)->si_wbr_rr_next;
5afbbe0d
AM
32221+ bbot = au_sbbot(sb);
32222+ nbr = bbot + 1;
32223+ for (bindex = 0; bindex <= bbot; bindex++) {
392086de 32224+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 32225+ err = atomic_dec_return(next) + 1;
32226+ /* modulo for 0 is meaningless */
32227+ if (unlikely(!err))
32228+ err = atomic_dec_return(next) + 1;
32229+ } else
32230+ err = atomic_read(next);
32231+ AuDbg("%d\n", err);
32232+ u = err;
32233+ err = u % nbr;
32234+ AuDbg("%d\n", err);
32235+ if (!au_br_rdonly(au_sbr(sb, err)))
32236+ break;
32237+ err = -EROFS;
32238+ }
32239+
4a4d8108
AM
32240+ if (err >= 0)
32241+ err = au_wbr_nonopq(dentry, err);
32242+
4f0767ce 32243+out:
1facf9fc 32244+ AuDbg("%d\n", err);
32245+ return err;
32246+}
32247+
32248+/* ---------------------------------------------------------------------- */
32249+
32250+/* most free space */
392086de 32251+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 32252+{
32253+ struct super_block *sb;
32254+ struct au_branch *br;
32255+ struct au_wbr_mfs *mfs;
392086de 32256+ struct dentry *h_parent;
5afbbe0d 32257+ aufs_bindex_t bindex, bbot;
1facf9fc 32258+ int err;
32259+ unsigned long long b, bavail;
7f207e10 32260+ struct path h_path;
1facf9fc 32261+ /* reduce the stack usage */
32262+ struct kstatfs *st;
32263+
32264+ st = kmalloc(sizeof(*st), GFP_NOFS);
32265+ if (unlikely(!st)) {
32266+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
32267+ return;
32268+ }
32269+
32270+ bavail = 0;
32271+ sb = dentry->d_sb;
32272+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 32273+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 32274+ mfs->mfs_bindex = -EROFS;
32275+ mfs->mfsrr_bytes = 0;
392086de
AM
32276+ if (!parent) {
32277+ bindex = 0;
5afbbe0d 32278+ bbot = au_sbbot(sb);
392086de 32279+ } else {
5afbbe0d
AM
32280+ bindex = au_dbtop(parent);
32281+ bbot = au_dbtaildir(parent);
392086de
AM
32282+ }
32283+
5afbbe0d 32284+ for (; bindex <= bbot; bindex++) {
392086de
AM
32285+ if (parent) {
32286+ h_parent = au_h_dptr(parent, bindex);
5527c038 32287+ if (!h_parent || d_is_negative(h_parent))
392086de
AM
32288+ continue;
32289+ }
1facf9fc 32290+ br = au_sbr(sb, bindex);
32291+ if (au_br_rdonly(br))
32292+ continue;
32293+
32294+ /* sb->s_root for NFS is unreliable */
86dc4139 32295+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
32296+ h_path.dentry = h_path.mnt->mnt_root;
32297+ err = vfs_statfs(&h_path, st);
1facf9fc 32298+ if (unlikely(err)) {
32299+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
32300+ continue;
32301+ }
32302+
32303+ /* when the available size is equal, select the lower one */
32304+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
32305+ || sizeof(b) < sizeof(st->f_bsize));
32306+ b = st->f_bavail * st->f_bsize;
32307+ br->br_wbr->wbr_bytes = b;
32308+ if (b >= bavail) {
32309+ bavail = b;
32310+ mfs->mfs_bindex = bindex;
32311+ mfs->mfs_jiffy = jiffies;
32312+ }
32313+ }
32314+
32315+ mfs->mfsrr_bytes = bavail;
32316+ AuDbg("b%d\n", mfs->mfs_bindex);
1c60b727 32317+ kfree(st);
1facf9fc 32318+}
32319+
392086de 32320+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 32321+{
32322+ int err;
392086de 32323+ struct dentry *parent;
1facf9fc 32324+ struct super_block *sb;
32325+ struct au_wbr_mfs *mfs;
32326+
32327+ err = au_wbr_create_exp(dentry);
32328+ if (err >= 0)
32329+ goto out;
32330+
32331+ sb = dentry->d_sb;
392086de
AM
32332+ parent = NULL;
32333+ if (au_ftest_wbr(flags, PARENT))
32334+ parent = dget_parent(dentry);
1facf9fc 32335+ mfs = &au_sbi(sb)->si_wbr_mfs;
32336+ mutex_lock(&mfs->mfs_lock);
32337+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
32338+ || mfs->mfs_bindex < 0
32339+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 32340+ au_mfs(dentry, parent);
1facf9fc 32341+ mutex_unlock(&mfs->mfs_lock);
32342+ err = mfs->mfs_bindex;
392086de 32343+ dput(parent);
1facf9fc 32344+
4a4d8108
AM
32345+ if (err >= 0)
32346+ err = au_wbr_nonopq(dentry, err);
32347+
4f0767ce 32348+out:
1facf9fc 32349+ AuDbg("b%d\n", err);
32350+ return err;
32351+}
32352+
32353+static int au_wbr_create_init_mfs(struct super_block *sb)
32354+{
32355+ struct au_wbr_mfs *mfs;
32356+
32357+ mfs = &au_sbi(sb)->si_wbr_mfs;
32358+ mutex_init(&mfs->mfs_lock);
32359+ mfs->mfs_jiffy = 0;
32360+ mfs->mfs_bindex = -EROFS;
32361+
32362+ return 0;
32363+}
32364+
32365+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
32366+{
32367+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
32368+ return 0;
32369+}
32370+
32371+/* ---------------------------------------------------------------------- */
32372+
f2c43d5f
AM
32373+/* top down regardless parent, and then mfs */
32374+static int au_wbr_create_tdmfs(struct dentry *dentry,
32375+ unsigned int flags __maybe_unused)
32376+{
32377+ int err;
32378+ aufs_bindex_t bwh, btail, bindex, bfound, bmfs;
32379+ unsigned long long watermark;
32380+ struct super_block *sb;
32381+ struct au_wbr_mfs *mfs;
32382+ struct au_branch *br;
32383+ struct dentry *parent;
32384+
32385+ sb = dentry->d_sb;
32386+ mfs = &au_sbi(sb)->si_wbr_mfs;
32387+ mutex_lock(&mfs->mfs_lock);
32388+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
32389+ || mfs->mfs_bindex < 0)
32390+ au_mfs(dentry, /*parent*/NULL);
32391+ watermark = mfs->mfsrr_watermark;
32392+ bmfs = mfs->mfs_bindex;
32393+ mutex_unlock(&mfs->mfs_lock);
32394+
32395+ /* another style of au_wbr_create_exp() */
32396+ bwh = au_dbwh(dentry);
32397+ parent = dget_parent(dentry);
32398+ btail = au_dbtaildir(parent);
32399+ if (bwh >= 0 && bwh < btail)
32400+ btail = bwh;
32401+
32402+ err = au_wbr_nonopq(dentry, btail);
32403+ if (unlikely(err < 0))
32404+ goto out;
32405+ btail = err;
32406+ bfound = -1;
32407+ for (bindex = 0; bindex <= btail; bindex++) {
32408+ br = au_sbr(sb, bindex);
32409+ if (au_br_rdonly(br))
32410+ continue;
32411+ if (br->br_wbr->wbr_bytes > watermark) {
32412+ bfound = bindex;
32413+ break;
32414+ }
32415+ }
32416+ err = bfound;
32417+ if (err < 0)
32418+ err = bmfs;
32419+
32420+out:
32421+ dput(parent);
32422+ AuDbg("b%d\n", err);
32423+ return err;
32424+}
32425+
32426+/* ---------------------------------------------------------------------- */
32427+
1facf9fc 32428+/* most free space and then round robin */
392086de 32429+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 32430+{
32431+ int err;
32432+ struct au_wbr_mfs *mfs;
32433+
392086de 32434+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 32435+ if (err >= 0) {
32436+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 32437+ mutex_lock(&mfs->mfs_lock);
1facf9fc 32438+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 32439+ err = au_wbr_create_rr(dentry, flags);
dece6358 32440+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 32441+ }
32442+
32443+ AuDbg("b%d\n", err);
32444+ return err;
32445+}
32446+
32447+static int au_wbr_create_init_mfsrr(struct super_block *sb)
32448+{
32449+ int err;
32450+
32451+ au_wbr_create_init_mfs(sb); /* ignore */
32452+ err = au_wbr_create_init_rr(sb);
32453+
32454+ return err;
32455+}
32456+
32457+/* ---------------------------------------------------------------------- */
32458+
32459+/* top down parent and most free space */
392086de 32460+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 32461+{
32462+ int err, e2;
32463+ unsigned long long b;
5afbbe0d 32464+ aufs_bindex_t bindex, btop, bbot;
1facf9fc 32465+ struct super_block *sb;
32466+ struct dentry *parent, *h_parent;
32467+ struct au_branch *br;
32468+
392086de 32469+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 32470+ if (unlikely(err < 0))
32471+ goto out;
32472+ parent = dget_parent(dentry);
5afbbe0d
AM
32473+ btop = au_dbtop(parent);
32474+ bbot = au_dbtaildir(parent);
32475+ if (btop == bbot)
1facf9fc 32476+ goto out_parent; /* success */
32477+
392086de 32478+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 32479+ if (e2 < 0)
32480+ goto out_parent; /* success */
32481+
32482+ /* when the available size is equal, select upper one */
32483+ sb = dentry->d_sb;
32484+ br = au_sbr(sb, err);
32485+ b = br->br_wbr->wbr_bytes;
32486+ AuDbg("b%d, %llu\n", err, b);
32487+
5afbbe0d 32488+ for (bindex = btop; bindex <= bbot; bindex++) {
1facf9fc 32489+ h_parent = au_h_dptr(parent, bindex);
5527c038 32490+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 32491+ continue;
32492+
32493+ br = au_sbr(sb, bindex);
32494+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
32495+ b = br->br_wbr->wbr_bytes;
32496+ err = bindex;
32497+ AuDbg("b%d, %llu\n", err, b);
32498+ }
32499+ }
32500+
4a4d8108
AM
32501+ if (err >= 0)
32502+ err = au_wbr_nonopq(dentry, err);
32503+
4f0767ce 32504+out_parent:
1facf9fc 32505+ dput(parent);
4f0767ce 32506+out:
1facf9fc 32507+ AuDbg("b%d\n", err);
32508+ return err;
32509+}
32510+
32511+/* ---------------------------------------------------------------------- */
32512+
392086de
AM
32513+/*
32514+ * - top down parent
32515+ * - most free space with parent
32516+ * - most free space round-robin regardless parent
32517+ */
32518+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
32519+{
32520+ int err;
32521+ unsigned long long watermark;
32522+ struct super_block *sb;
32523+ struct au_branch *br;
32524+ struct au_wbr_mfs *mfs;
32525+
32526+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
32527+ if (unlikely(err < 0))
32528+ goto out;
32529+
32530+ sb = dentry->d_sb;
32531+ br = au_sbr(sb, err);
32532+ mfs = &au_sbi(sb)->si_wbr_mfs;
32533+ mutex_lock(&mfs->mfs_lock);
32534+ watermark = mfs->mfsrr_watermark;
32535+ mutex_unlock(&mfs->mfs_lock);
32536+ if (br->br_wbr->wbr_bytes < watermark)
32537+ /* regardless the parent dir */
32538+ err = au_wbr_create_mfsrr(dentry, flags);
32539+
32540+out:
32541+ AuDbg("b%d\n", err);
32542+ return err;
32543+}
32544+
32545+/* ---------------------------------------------------------------------- */
32546+
1facf9fc 32547+/* policies for copyup */
32548+
32549+/* top down parent */
32550+static int au_wbr_copyup_tdp(struct dentry *dentry)
32551+{
392086de 32552+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 32553+}
32554+
32555+/* bottom up parent */
32556+static int au_wbr_copyup_bup(struct dentry *dentry)
32557+{
32558+ int err;
5afbbe0d 32559+ aufs_bindex_t bindex, btop;
1facf9fc 32560+ struct dentry *parent, *h_parent;
32561+ struct super_block *sb;
32562+
32563+ err = -EROFS;
32564+ sb = dentry->d_sb;
32565+ parent = dget_parent(dentry);
5afbbe0d
AM
32566+ btop = au_dbtop(parent);
32567+ for (bindex = au_dbtop(dentry); bindex >= btop; bindex--) {
1facf9fc 32568+ h_parent = au_h_dptr(parent, bindex);
5527c038 32569+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 32570+ continue;
32571+
32572+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
32573+ err = bindex;
32574+ break;
32575+ }
32576+ }
32577+ dput(parent);
32578+
32579+ /* bottom up here */
32580+ if (unlikely(err < 0))
5afbbe0d 32581+ err = au_wbr_bu(sb, btop - 1);
1facf9fc 32582+
32583+ AuDbg("b%d\n", err);
32584+ return err;
32585+}
32586+
32587+/* bottom up */
5afbbe0d 32588+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop)
1facf9fc 32589+{
32590+ int err;
32591+
5afbbe0d 32592+ err = au_wbr_bu(dentry->d_sb, btop);
4a4d8108 32593+ AuDbg("b%d\n", err);
5afbbe0d 32594+ if (err > btop)
4a4d8108 32595+ err = au_wbr_nonopq(dentry, err);
1facf9fc 32596+
32597+ AuDbg("b%d\n", err);
32598+ return err;
32599+}
32600+
076b876e
AM
32601+static int au_wbr_copyup_bu(struct dentry *dentry)
32602+{
32603+ int err;
5afbbe0d 32604+ aufs_bindex_t btop;
076b876e 32605+
5afbbe0d
AM
32606+ btop = au_dbtop(dentry);
32607+ err = au_wbr_do_copyup_bu(dentry, btop);
076b876e
AM
32608+ return err;
32609+}
32610+
1facf9fc 32611+/* ---------------------------------------------------------------------- */
32612+
32613+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
32614+ [AuWbrCopyup_TDP] = {
32615+ .copyup = au_wbr_copyup_tdp
32616+ },
32617+ [AuWbrCopyup_BUP] = {
32618+ .copyup = au_wbr_copyup_bup
32619+ },
32620+ [AuWbrCopyup_BU] = {
32621+ .copyup = au_wbr_copyup_bu
32622+ }
32623+};
32624+
32625+struct au_wbr_create_operations au_wbr_create_ops[] = {
32626+ [AuWbrCreate_TDP] = {
32627+ .create = au_wbr_create_tdp
32628+ },
32629+ [AuWbrCreate_RR] = {
32630+ .create = au_wbr_create_rr,
32631+ .init = au_wbr_create_init_rr
32632+ },
32633+ [AuWbrCreate_MFS] = {
32634+ .create = au_wbr_create_mfs,
32635+ .init = au_wbr_create_init_mfs,
32636+ .fin = au_wbr_create_fin_mfs
32637+ },
32638+ [AuWbrCreate_MFSV] = {
32639+ .create = au_wbr_create_mfs,
32640+ .init = au_wbr_create_init_mfs,
32641+ .fin = au_wbr_create_fin_mfs
32642+ },
32643+ [AuWbrCreate_MFSRR] = {
32644+ .create = au_wbr_create_mfsrr,
32645+ .init = au_wbr_create_init_mfsrr,
32646+ .fin = au_wbr_create_fin_mfs
32647+ },
32648+ [AuWbrCreate_MFSRRV] = {
32649+ .create = au_wbr_create_mfsrr,
32650+ .init = au_wbr_create_init_mfsrr,
32651+ .fin = au_wbr_create_fin_mfs
32652+ },
f2c43d5f
AM
32653+ [AuWbrCreate_TDMFS] = {
32654+ .create = au_wbr_create_tdmfs,
32655+ .init = au_wbr_create_init_mfs,
32656+ .fin = au_wbr_create_fin_mfs
32657+ },
32658+ [AuWbrCreate_TDMFSV] = {
32659+ .create = au_wbr_create_tdmfs,
32660+ .init = au_wbr_create_init_mfs,
32661+ .fin = au_wbr_create_fin_mfs
32662+ },
1facf9fc 32663+ [AuWbrCreate_PMFS] = {
32664+ .create = au_wbr_create_pmfs,
32665+ .init = au_wbr_create_init_mfs,
32666+ .fin = au_wbr_create_fin_mfs
32667+ },
32668+ [AuWbrCreate_PMFSV] = {
32669+ .create = au_wbr_create_pmfs,
32670+ .init = au_wbr_create_init_mfs,
32671+ .fin = au_wbr_create_fin_mfs
392086de
AM
32672+ },
32673+ [AuWbrCreate_PMFSRR] = {
32674+ .create = au_wbr_create_pmfsrr,
32675+ .init = au_wbr_create_init_mfsrr,
32676+ .fin = au_wbr_create_fin_mfs
32677+ },
32678+ [AuWbrCreate_PMFSRRV] = {
32679+ .create = au_wbr_create_pmfsrr,
32680+ .init = au_wbr_create_init_mfsrr,
32681+ .fin = au_wbr_create_fin_mfs
1facf9fc 32682+ }
32683+};
7f207e10
AM
32684diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
32685--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 32686+++ linux/fs/aufs/whout.c 2017-07-29 12:14:25.906375514 +0200
f2c43d5f 32687@@ -0,0 +1,1061 @@
1facf9fc 32688+/*
a2654f78 32689+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 32690+ *
32691+ * This program, aufs is free software; you can redistribute it and/or modify
32692+ * it under the terms of the GNU General Public License as published by
32693+ * the Free Software Foundation; either version 2 of the License, or
32694+ * (at your option) any later version.
dece6358
AM
32695+ *
32696+ * This program is distributed in the hope that it will be useful,
32697+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32698+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32699+ * GNU General Public License for more details.
32700+ *
32701+ * You should have received a copy of the GNU General Public License
523b37e3 32702+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32703+ */
32704+
32705+/*
32706+ * whiteout for logical deletion and opaque directory
32707+ */
32708+
1facf9fc 32709+#include "aufs.h"
32710+
32711+#define WH_MASK S_IRUGO
32712+
32713+/*
32714+ * If a directory contains this file, then it is opaque. We start with the
32715+ * .wh. flag so that it is blocked by lookup.
32716+ */
0c3ec466
AM
32717+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
32718+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 32719+
32720+/*
32721+ * generate whiteout name, which is NOT terminated by NULL.
32722+ * @name: original d_name.name
32723+ * @len: original d_name.len
32724+ * @wh: whiteout qstr
32725+ * returns zero when succeeds, otherwise error.
32726+ * succeeded value as wh->name should be freed by kfree().
32727+ */
32728+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
32729+{
32730+ char *p;
32731+
32732+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
32733+ return -ENAMETOOLONG;
32734+
32735+ wh->len = name->len + AUFS_WH_PFX_LEN;
32736+ p = kmalloc(wh->len, GFP_NOFS);
32737+ wh->name = p;
32738+ if (p) {
32739+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
32740+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
32741+ /* smp_mb(); */
32742+ return 0;
32743+ }
32744+ return -ENOMEM;
32745+}
32746+
32747+/* ---------------------------------------------------------------------- */
32748+
32749+/*
32750+ * test if the @wh_name exists under @h_parent.
32751+ * @try_sio specifies the necessary of super-io.
32752+ */
076b876e 32753+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
1facf9fc 32754+{
32755+ int err;
32756+ struct dentry *wh_dentry;
1facf9fc 32757+
1facf9fc 32758+ if (!try_sio)
b4510431 32759+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 32760+ else
076b876e 32761+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
1facf9fc 32762+ err = PTR_ERR(wh_dentry);
2000de60
JR
32763+ if (IS_ERR(wh_dentry)) {
32764+ if (err == -ENAMETOOLONG)
32765+ err = 0;
1facf9fc 32766+ goto out;
2000de60 32767+ }
1facf9fc 32768+
32769+ err = 0;
5527c038 32770+ if (d_is_negative(wh_dentry))
1facf9fc 32771+ goto out_wh; /* success */
32772+
32773+ err = 1;
7e9cd9fe 32774+ if (d_is_reg(wh_dentry))
1facf9fc 32775+ goto out_wh; /* success */
32776+
32777+ err = -EIO;
523b37e3 32778+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
5527c038 32779+ wh_dentry, d_inode(wh_dentry)->i_mode);
1facf9fc 32780+
4f0767ce 32781+out_wh:
1facf9fc 32782+ dput(wh_dentry);
4f0767ce 32783+out:
1facf9fc 32784+ return err;
32785+}
32786+
32787+/*
32788+ * test if the @h_dentry sets opaque or not.
32789+ */
076b876e 32790+int au_diropq_test(struct dentry *h_dentry)
1facf9fc 32791+{
32792+ int err;
32793+ struct inode *h_dir;
32794+
5527c038 32795+ h_dir = d_inode(h_dentry);
076b876e 32796+ err = au_wh_test(h_dentry, &diropq_name,
1facf9fc 32797+ au_test_h_perm_sio(h_dir, MAY_EXEC));
32798+ return err;
32799+}
32800+
32801+/*
32802+ * returns a negative dentry whose name is unique and temporary.
32803+ */
32804+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
32805+ struct qstr *prefix)
32806+{
1facf9fc 32807+ struct dentry *dentry;
32808+ int i;
027c5e7a 32809+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 32810+ *name, *p;
027c5e7a 32811+ /* strict atomic_t is unnecessary here */
1facf9fc 32812+ static unsigned short cnt;
32813+ struct qstr qs;
32814+
4a4d8108
AM
32815+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
32816+
1facf9fc 32817+ name = defname;
027c5e7a
AM
32818+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
32819+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 32820+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 32821+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 32822+ goto out;
32823+ dentry = ERR_PTR(-ENOMEM);
32824+ name = kmalloc(qs.len + 1, GFP_NOFS);
32825+ if (unlikely(!name))
32826+ goto out;
32827+ }
32828+
32829+ /* doubly whiteout-ed */
32830+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
32831+ p = name + AUFS_WH_PFX_LEN * 2;
32832+ memcpy(p, prefix->name, prefix->len);
32833+ p += prefix->len;
32834+ *p++ = '.';
4a4d8108 32835+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 32836+
32837+ qs.name = name;
32838+ for (i = 0; i < 3; i++) {
b752ccd1 32839+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
076b876e 32840+ dentry = au_sio_lkup_one(&qs, h_parent);
5527c038 32841+ if (IS_ERR(dentry) || d_is_negative(dentry))
1facf9fc 32842+ goto out_name;
32843+ dput(dentry);
32844+ }
0c3ec466 32845+ /* pr_warn("could not get random name\n"); */
1facf9fc 32846+ dentry = ERR_PTR(-EEXIST);
32847+ AuDbg("%.*s\n", AuLNPair(&qs));
32848+ BUG();
32849+
4f0767ce 32850+out_name:
1facf9fc 32851+ if (name != defname)
1c60b727 32852+ kfree(name);
4f0767ce 32853+out:
4a4d8108 32854+ AuTraceErrPtr(dentry);
1facf9fc 32855+ return dentry;
1facf9fc 32856+}
32857+
32858+/*
32859+ * rename the @h_dentry on @br to the whiteouted temporary name.
32860+ */
32861+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
32862+{
32863+ int err;
32864+ struct path h_path = {
86dc4139 32865+ .mnt = au_br_mnt(br)
1facf9fc 32866+ };
523b37e3 32867+ struct inode *h_dir, *delegated;
1facf9fc 32868+ struct dentry *h_parent;
32869+
32870+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5527c038 32871+ h_dir = d_inode(h_parent);
1facf9fc 32872+ IMustLock(h_dir);
32873+
32874+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
32875+ err = PTR_ERR(h_path.dentry);
32876+ if (IS_ERR(h_path.dentry))
32877+ goto out;
32878+
32879+ /* under the same dir, no need to lock_rename() */
523b37e3 32880+ delegated = NULL;
f2c43d5f
AM
32881+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated,
32882+ /*flags*/0);
1facf9fc 32883+ AuTraceErr(err);
523b37e3
AM
32884+ if (unlikely(err == -EWOULDBLOCK)) {
32885+ pr_warn("cannot retry for NFSv4 delegation"
32886+ " for an internal rename\n");
32887+ iput(delegated);
32888+ }
1facf9fc 32889+ dput(h_path.dentry);
32890+
4f0767ce 32891+out:
4a4d8108 32892+ AuTraceErr(err);
1facf9fc 32893+ return err;
32894+}
32895+
32896+/* ---------------------------------------------------------------------- */
32897+/*
32898+ * functions for removing a whiteout
32899+ */
32900+
32901+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
32902+{
523b37e3
AM
32903+ int err, force;
32904+ struct inode *delegated;
1facf9fc 32905+
32906+ /*
32907+ * forces superio when the dir has a sticky bit.
32908+ * this may be a violation of unix fs semantics.
32909+ */
32910+ force = (h_dir->i_mode & S_ISVTX)
5527c038 32911+ && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid);
523b37e3
AM
32912+ delegated = NULL;
32913+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
32914+ if (unlikely(err == -EWOULDBLOCK)) {
32915+ pr_warn("cannot retry for NFSv4 delegation"
32916+ " for an internal unlink\n");
32917+ iput(delegated);
32918+ }
32919+ return err;
1facf9fc 32920+}
32921+
32922+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
32923+ struct dentry *dentry)
32924+{
32925+ int err;
32926+
32927+ err = do_unlink_wh(h_dir, h_path);
32928+ if (!err && dentry)
32929+ au_set_dbwh(dentry, -1);
32930+
32931+ return err;
32932+}
32933+
32934+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
32935+ struct au_branch *br)
32936+{
32937+ int err;
32938+ struct path h_path = {
86dc4139 32939+ .mnt = au_br_mnt(br)
1facf9fc 32940+ };
32941+
32942+ err = 0;
b4510431 32943+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 32944+ if (IS_ERR(h_path.dentry))
32945+ err = PTR_ERR(h_path.dentry);
32946+ else {
5527c038
JR
32947+ if (d_is_reg(h_path.dentry))
32948+ err = do_unlink_wh(d_inode(h_parent), &h_path);
1facf9fc 32949+ dput(h_path.dentry);
32950+ }
32951+
32952+ return err;
32953+}
32954+
32955+/* ---------------------------------------------------------------------- */
32956+/*
32957+ * initialize/clean whiteout for a branch
32958+ */
32959+
32960+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
32961+ const int isdir)
32962+{
32963+ int err;
523b37e3 32964+ struct inode *delegated;
1facf9fc 32965+
5527c038 32966+ if (d_is_negative(whpath->dentry))
1facf9fc 32967+ return;
32968+
86dc4139
AM
32969+ if (isdir)
32970+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
32971+ else {
32972+ delegated = NULL;
32973+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
32974+ if (unlikely(err == -EWOULDBLOCK)) {
32975+ pr_warn("cannot retry for NFSv4 delegation"
32976+ " for an internal unlink\n");
32977+ iput(delegated);
32978+ }
32979+ }
1facf9fc 32980+ if (unlikely(err))
523b37e3
AM
32981+ pr_warn("failed removing %pd (%d), ignored.\n",
32982+ whpath->dentry, err);
1facf9fc 32983+}
32984+
32985+static int test_linkable(struct dentry *h_root)
32986+{
5527c038 32987+ struct inode *h_dir = d_inode(h_root);
1facf9fc 32988+
32989+ if (h_dir->i_op->link)
32990+ return 0;
32991+
523b37e3
AM
32992+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
32993+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 32994+ return -ENOSYS;
32995+}
32996+
32997+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
32998+static int au_whdir(struct inode *h_dir, struct path *path)
32999+{
33000+ int err;
33001+
33002+ err = -EEXIST;
5527c038 33003+ if (d_is_negative(path->dentry)) {
1facf9fc 33004+ int mode = S_IRWXU;
33005+
33006+ if (au_test_nfs(path->dentry->d_sb))
33007+ mode |= S_IXUGO;
86dc4139 33008+ err = vfsub_mkdir(h_dir, path, mode);
2000de60 33009+ } else if (d_is_dir(path->dentry))
1facf9fc 33010+ err = 0;
33011+ else
523b37e3 33012+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 33013+
33014+ return err;
33015+}
33016+
33017+struct au_wh_base {
33018+ const struct qstr *name;
33019+ struct dentry *dentry;
33020+};
33021+
33022+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
33023+ struct path *h_path)
33024+{
33025+ h_path->dentry = base[AuBrWh_BASE].dentry;
33026+ au_wh_clean(h_dir, h_path, /*isdir*/0);
33027+ h_path->dentry = base[AuBrWh_PLINK].dentry;
33028+ au_wh_clean(h_dir, h_path, /*isdir*/1);
33029+ h_path->dentry = base[AuBrWh_ORPH].dentry;
33030+ au_wh_clean(h_dir, h_path, /*isdir*/1);
33031+}
33032+
33033+/*
33034+ * returns tri-state,
c1595e42 33035+ * minus: error, caller should print the message
1facf9fc 33036+ * zero: succuess
c1595e42 33037+ * plus: error, caller should NOT print the message
1facf9fc 33038+ */
33039+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
33040+ int do_plink, struct au_wh_base base[],
33041+ struct path *h_path)
33042+{
33043+ int err;
33044+ struct inode *h_dir;
33045+
5527c038 33046+ h_dir = d_inode(h_root);
1facf9fc 33047+ h_path->dentry = base[AuBrWh_BASE].dentry;
33048+ au_wh_clean(h_dir, h_path, /*isdir*/0);
33049+ h_path->dentry = base[AuBrWh_PLINK].dentry;
33050+ if (do_plink) {
33051+ err = test_linkable(h_root);
33052+ if (unlikely(err)) {
33053+ err = 1;
33054+ goto out;
33055+ }
33056+
33057+ err = au_whdir(h_dir, h_path);
33058+ if (unlikely(err))
33059+ goto out;
33060+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
33061+ } else
33062+ au_wh_clean(h_dir, h_path, /*isdir*/1);
33063+ h_path->dentry = base[AuBrWh_ORPH].dentry;
33064+ err = au_whdir(h_dir, h_path);
33065+ if (unlikely(err))
33066+ goto out;
33067+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
33068+
4f0767ce 33069+out:
1facf9fc 33070+ return err;
33071+}
33072+
33073+/*
33074+ * for the moment, aufs supports the branch filesystem which does not support
33075+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
33076+ * copyup failed. finally, such filesystem will not be used as the writable
33077+ * branch.
33078+ *
33079+ * returns tri-state, see above.
33080+ */
33081+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
33082+ int do_plink, struct au_wh_base base[],
33083+ struct path *h_path)
33084+{
33085+ int err;
33086+ struct inode *h_dir;
33087+
1308ab2a 33088+ WbrWhMustWriteLock(wbr);
33089+
1facf9fc 33090+ err = test_linkable(h_root);
33091+ if (unlikely(err)) {
33092+ err = 1;
33093+ goto out;
33094+ }
33095+
33096+ /*
33097+ * todo: should this create be done in /sbin/mount.aufs helper?
33098+ */
33099+ err = -EEXIST;
5527c038
JR
33100+ h_dir = d_inode(h_root);
33101+ if (d_is_negative(base[AuBrWh_BASE].dentry)) {
86dc4139
AM
33102+ h_path->dentry = base[AuBrWh_BASE].dentry;
33103+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
7e9cd9fe 33104+ } else if (d_is_reg(base[AuBrWh_BASE].dentry))
1facf9fc 33105+ err = 0;
33106+ else
523b37e3 33107+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 33108+ if (unlikely(err))
33109+ goto out;
33110+
33111+ h_path->dentry = base[AuBrWh_PLINK].dentry;
33112+ if (do_plink) {
33113+ err = au_whdir(h_dir, h_path);
33114+ if (unlikely(err))
33115+ goto out;
33116+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
33117+ } else
33118+ au_wh_clean(h_dir, h_path, /*isdir*/1);
33119+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
33120+
33121+ h_path->dentry = base[AuBrWh_ORPH].dentry;
33122+ err = au_whdir(h_dir, h_path);
33123+ if (unlikely(err))
33124+ goto out;
33125+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
33126+
4f0767ce 33127+out:
1facf9fc 33128+ return err;
33129+}
33130+
33131+/*
33132+ * initialize the whiteout base file/dir for @br.
33133+ */
86dc4139 33134+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 33135+{
33136+ int err, i;
33137+ const unsigned char do_plink
33138+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 33139+ struct inode *h_dir;
86dc4139
AM
33140+ struct path path = br->br_path;
33141+ struct dentry *h_root = path.dentry;
1facf9fc 33142+ struct au_wbr *wbr = br->br_wbr;
33143+ static const struct qstr base_name[] = {
0c3ec466
AM
33144+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
33145+ sizeof(AUFS_BASE_NAME) - 1),
33146+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
33147+ sizeof(AUFS_PLINKDIR_NAME) - 1),
33148+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
33149+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 33150+ };
33151+ struct au_wh_base base[] = {
33152+ [AuBrWh_BASE] = {
33153+ .name = base_name + AuBrWh_BASE,
33154+ .dentry = NULL
33155+ },
33156+ [AuBrWh_PLINK] = {
33157+ .name = base_name + AuBrWh_PLINK,
33158+ .dentry = NULL
33159+ },
33160+ [AuBrWh_ORPH] = {
33161+ .name = base_name + AuBrWh_ORPH,
33162+ .dentry = NULL
33163+ }
33164+ };
33165+
1308ab2a 33166+ if (wbr)
33167+ WbrWhMustWriteLock(wbr);
1facf9fc 33168+
1facf9fc 33169+ for (i = 0; i < AuBrWh_Last; i++) {
33170+ /* doubly whiteouted */
33171+ struct dentry *d;
33172+
33173+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
33174+ err = PTR_ERR(d);
33175+ if (IS_ERR(d))
33176+ goto out;
33177+
33178+ base[i].dentry = d;
33179+ AuDebugOn(wbr
33180+ && wbr->wbr_wh[i]
33181+ && wbr->wbr_wh[i] != base[i].dentry);
33182+ }
33183+
33184+ if (wbr)
33185+ for (i = 0; i < AuBrWh_Last; i++) {
33186+ dput(wbr->wbr_wh[i]);
33187+ wbr->wbr_wh[i] = NULL;
33188+ }
33189+
33190+ err = 0;
1e00d052 33191+ if (!au_br_writable(br->br_perm)) {
5527c038 33192+ h_dir = d_inode(h_root);
1facf9fc 33193+ au_wh_init_ro(h_dir, base, &path);
1e00d052 33194+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 33195+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
33196+ if (err > 0)
33197+ goto out;
33198+ else if (err)
33199+ goto out_err;
1e00d052 33200+ } else {
1facf9fc 33201+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
33202+ if (err > 0)
33203+ goto out;
33204+ else if (err)
33205+ goto out_err;
1facf9fc 33206+ }
33207+ goto out; /* success */
33208+
4f0767ce 33209+out_err:
523b37e3
AM
33210+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
33211+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 33212+out:
1facf9fc 33213+ for (i = 0; i < AuBrWh_Last; i++)
33214+ dput(base[i].dentry);
33215+ return err;
33216+}
33217+
33218+/* ---------------------------------------------------------------------- */
33219+/*
33220+ * whiteouts are all hard-linked usually.
33221+ * when its link count reaches a ceiling, we create a new whiteout base
33222+ * asynchronously.
33223+ */
33224+
33225+struct reinit_br_wh {
33226+ struct super_block *sb;
33227+ struct au_branch *br;
33228+};
33229+
33230+static void reinit_br_wh(void *arg)
33231+{
33232+ int err;
33233+ aufs_bindex_t bindex;
33234+ struct path h_path;
33235+ struct reinit_br_wh *a = arg;
33236+ struct au_wbr *wbr;
523b37e3 33237+ struct inode *dir, *delegated;
1facf9fc 33238+ struct dentry *h_root;
33239+ struct au_hinode *hdir;
33240+
33241+ err = 0;
33242+ wbr = a->br->br_wbr;
33243+ /* big aufs lock */
33244+ si_noflush_write_lock(a->sb);
33245+ if (!au_br_writable(a->br->br_perm))
33246+ goto out;
33247+ bindex = au_br_index(a->sb, a->br->br_id);
33248+ if (unlikely(bindex < 0))
33249+ goto out;
33250+
1308ab2a 33251+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
5527c038 33252+ dir = d_inode(a->sb->s_root);
1facf9fc 33253+ hdir = au_hi(dir, bindex);
33254+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 33255+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 33256+
5afbbe0d 33257+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 33258+ wbr_wh_write_lock(wbr);
33259+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
33260+ h_root, a->br);
33261+ if (!err) {
86dc4139
AM
33262+ h_path.dentry = wbr->wbr_whbase;
33263+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
33264+ delegated = NULL;
33265+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
33266+ /*force*/0);
33267+ if (unlikely(err == -EWOULDBLOCK)) {
33268+ pr_warn("cannot retry for NFSv4 delegation"
33269+ " for an internal unlink\n");
33270+ iput(delegated);
33271+ }
1facf9fc 33272+ } else {
523b37e3 33273+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 33274+ err = 0;
33275+ }
33276+ dput(wbr->wbr_whbase);
33277+ wbr->wbr_whbase = NULL;
33278+ if (!err)
86dc4139 33279+ err = au_wh_init(a->br, a->sb);
1facf9fc 33280+ wbr_wh_write_unlock(wbr);
5afbbe0d 33281+ au_hn_inode_unlock(hdir);
1308ab2a 33282+ di_read_unlock(a->sb->s_root, AuLock_IR);
076b876e
AM
33283+ if (!err)
33284+ au_fhsm_wrote(a->sb, bindex, /*force*/0);
1facf9fc 33285+
4f0767ce 33286+out:
1facf9fc 33287+ if (wbr)
33288+ atomic_dec(&wbr->wbr_wh_running);
5afbbe0d 33289+ au_br_put(a->br);
1facf9fc 33290+ si_write_unlock(a->sb);
027c5e7a 33291+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1c60b727 33292+ kfree(arg);
1facf9fc 33293+ if (unlikely(err))
33294+ AuIOErr("err %d\n", err);
33295+}
33296+
33297+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
33298+{
33299+ int do_dec, wkq_err;
33300+ struct reinit_br_wh *arg;
33301+
33302+ do_dec = 1;
33303+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
33304+ goto out;
33305+
33306+ /* ignore ENOMEM */
33307+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
33308+ if (arg) {
33309+ /*
33310+ * dec(wh_running), kfree(arg) and dec(br_count)
33311+ * in reinit function
33312+ */
33313+ arg->sb = sb;
33314+ arg->br = br;
5afbbe0d 33315+ au_br_get(br);
53392da6 33316+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 33317+ if (unlikely(wkq_err)) {
33318+ atomic_dec(&br->br_wbr->wbr_wh_running);
5afbbe0d 33319+ au_br_put(br);
1c60b727 33320+ kfree(arg);
1facf9fc 33321+ }
33322+ do_dec = 0;
33323+ }
33324+
4f0767ce 33325+out:
1facf9fc 33326+ if (do_dec)
33327+ atomic_dec(&br->br_wbr->wbr_wh_running);
33328+}
33329+
33330+/* ---------------------------------------------------------------------- */
33331+
33332+/*
33333+ * create the whiteout @wh.
33334+ */
33335+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
33336+ struct dentry *wh)
33337+{
33338+ int err;
33339+ struct path h_path = {
33340+ .dentry = wh
33341+ };
33342+ struct au_branch *br;
33343+ struct au_wbr *wbr;
33344+ struct dentry *h_parent;
523b37e3 33345+ struct inode *h_dir, *delegated;
1facf9fc 33346+
33347+ h_parent = wh->d_parent; /* dir inode is locked */
5527c038 33348+ h_dir = d_inode(h_parent);
1facf9fc 33349+ IMustLock(h_dir);
33350+
33351+ br = au_sbr(sb, bindex);
86dc4139 33352+ h_path.mnt = au_br_mnt(br);
1facf9fc 33353+ wbr = br->br_wbr;
33354+ wbr_wh_read_lock(wbr);
33355+ if (wbr->wbr_whbase) {
523b37e3
AM
33356+ delegated = NULL;
33357+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
33358+ if (unlikely(err == -EWOULDBLOCK)) {
33359+ pr_warn("cannot retry for NFSv4 delegation"
33360+ " for an internal link\n");
33361+ iput(delegated);
33362+ }
1facf9fc 33363+ if (!err || err != -EMLINK)
33364+ goto out;
33365+
33366+ /* link count full. re-initialize br_whbase. */
33367+ kick_reinit_br_wh(sb, br);
33368+ }
33369+
33370+ /* return this error in this context */
b4510431 33371+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
076b876e
AM
33372+ if (!err)
33373+ au_fhsm_wrote(sb, bindex, /*force*/0);
1facf9fc 33374+
4f0767ce 33375+out:
1facf9fc 33376+ wbr_wh_read_unlock(wbr);
33377+ return err;
33378+}
33379+
33380+/* ---------------------------------------------------------------------- */
33381+
33382+/*
33383+ * create or remove the diropq.
33384+ */
33385+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
33386+ unsigned int flags)
33387+{
33388+ struct dentry *opq_dentry, *h_dentry;
33389+ struct super_block *sb;
33390+ struct au_branch *br;
33391+ int err;
33392+
33393+ sb = dentry->d_sb;
33394+ br = au_sbr(sb, bindex);
33395+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 33396+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 33397+ if (IS_ERR(opq_dentry))
33398+ goto out;
33399+
33400+ if (au_ftest_diropq(flags, CREATE)) {
33401+ err = link_or_create_wh(sb, bindex, opq_dentry);
33402+ if (!err) {
33403+ au_set_dbdiropq(dentry, bindex);
33404+ goto out; /* success */
33405+ }
33406+ } else {
33407+ struct path tmp = {
33408+ .dentry = opq_dentry,
86dc4139 33409+ .mnt = au_br_mnt(br)
1facf9fc 33410+ };
5527c038 33411+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp);
1facf9fc 33412+ if (!err)
33413+ au_set_dbdiropq(dentry, -1);
33414+ }
33415+ dput(opq_dentry);
33416+ opq_dentry = ERR_PTR(err);
33417+
4f0767ce 33418+out:
1facf9fc 33419+ return opq_dentry;
33420+}
33421+
33422+struct do_diropq_args {
33423+ struct dentry **errp;
33424+ struct dentry *dentry;
33425+ aufs_bindex_t bindex;
33426+ unsigned int flags;
33427+};
33428+
33429+static void call_do_diropq(void *args)
33430+{
33431+ struct do_diropq_args *a = args;
33432+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
33433+}
33434+
33435+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
33436+ unsigned int flags)
33437+{
33438+ struct dentry *diropq, *h_dentry;
33439+
33440+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 33441+ if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE))
1facf9fc 33442+ diropq = do_diropq(dentry, bindex, flags);
33443+ else {
33444+ int wkq_err;
33445+ struct do_diropq_args args = {
33446+ .errp = &diropq,
33447+ .dentry = dentry,
33448+ .bindex = bindex,
33449+ .flags = flags
33450+ };
33451+
33452+ wkq_err = au_wkq_wait(call_do_diropq, &args);
33453+ if (unlikely(wkq_err))
33454+ diropq = ERR_PTR(wkq_err);
33455+ }
33456+
33457+ return diropq;
33458+}
33459+
33460+/* ---------------------------------------------------------------------- */
33461+
33462+/*
33463+ * lookup whiteout dentry.
33464+ * @h_parent: lower parent dentry which must exist and be locked
33465+ * @base_name: name of dentry which will be whiteouted
33466+ * returns dentry for whiteout.
33467+ */
33468+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
33469+ struct au_branch *br)
33470+{
33471+ int err;
33472+ struct qstr wh_name;
33473+ struct dentry *wh_dentry;
33474+
33475+ err = au_wh_name_alloc(&wh_name, base_name);
33476+ wh_dentry = ERR_PTR(err);
33477+ if (!err) {
b4510431 33478+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1c60b727 33479+ kfree(wh_name.name);
1facf9fc 33480+ }
33481+ return wh_dentry;
33482+}
33483+
33484+/*
33485+ * link/create a whiteout for @dentry on @bindex.
33486+ */
33487+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
33488+ struct dentry *h_parent)
33489+{
33490+ struct dentry *wh_dentry;
33491+ struct super_block *sb;
33492+ int err;
33493+
33494+ sb = dentry->d_sb;
33495+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
5527c038 33496+ if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) {
1facf9fc 33497+ err = link_or_create_wh(sb, bindex, wh_dentry);
076b876e 33498+ if (!err) {
1facf9fc 33499+ au_set_dbwh(dentry, bindex);
076b876e
AM
33500+ au_fhsm_wrote(sb, bindex, /*force*/0);
33501+ } else {
1facf9fc 33502+ dput(wh_dentry);
33503+ wh_dentry = ERR_PTR(err);
33504+ }
33505+ }
33506+
33507+ return wh_dentry;
33508+}
33509+
33510+/* ---------------------------------------------------------------------- */
33511+
33512+/* Delete all whiteouts in this directory on branch bindex. */
33513+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
33514+ aufs_bindex_t bindex, struct au_branch *br)
33515+{
33516+ int err;
33517+ unsigned long ul, n;
33518+ struct qstr wh_name;
33519+ char *p;
33520+ struct hlist_head *head;
c06a8ce3 33521+ struct au_vdir_wh *pos;
1facf9fc 33522+ struct au_vdir_destr *str;
33523+
33524+ err = -ENOMEM;
537831f9 33525+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 33526+ wh_name.name = p;
33527+ if (unlikely(!wh_name.name))
33528+ goto out;
33529+
33530+ err = 0;
33531+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
33532+ p += AUFS_WH_PFX_LEN;
33533+ n = whlist->nh_num;
33534+ head = whlist->nh_head;
33535+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
33536+ hlist_for_each_entry(pos, head, wh_hash) {
33537+ if (pos->wh_bindex != bindex)
1facf9fc 33538+ continue;
33539+
c06a8ce3 33540+ str = &pos->wh_str;
1facf9fc 33541+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
33542+ memcpy(p, str->name, str->len);
33543+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
33544+ err = unlink_wh_name(h_dentry, &wh_name, br);
33545+ if (!err)
33546+ continue;
33547+ break;
33548+ }
33549+ AuIOErr("whiteout name too long %.*s\n",
33550+ str->len, str->name);
33551+ err = -EIO;
33552+ break;
33553+ }
33554+ }
1c60b727 33555+ free_page((unsigned long)wh_name.name);
1facf9fc 33556+
4f0767ce 33557+out:
1facf9fc 33558+ return err;
33559+}
33560+
33561+struct del_wh_children_args {
33562+ int *errp;
33563+ struct dentry *h_dentry;
1308ab2a 33564+ struct au_nhash *whlist;
1facf9fc 33565+ aufs_bindex_t bindex;
33566+ struct au_branch *br;
33567+};
33568+
33569+static void call_del_wh_children(void *args)
33570+{
33571+ struct del_wh_children_args *a = args;
1308ab2a 33572+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 33573+}
33574+
33575+/* ---------------------------------------------------------------------- */
33576+
33577+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
33578+{
33579+ struct au_whtmp_rmdir *whtmp;
dece6358 33580+ int err;
1308ab2a 33581+ unsigned int rdhash;
dece6358
AM
33582+
33583+ SiMustAnyLock(sb);
1facf9fc 33584+
be52b249 33585+ whtmp = kzalloc(sizeof(*whtmp), gfp);
dece6358
AM
33586+ if (unlikely(!whtmp)) {
33587+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 33588+ goto out;
dece6358 33589+ }
1facf9fc 33590+
1308ab2a 33591+ /* no estimation for dir size */
33592+ rdhash = au_sbi(sb)->si_rdhash;
33593+ if (!rdhash)
33594+ rdhash = AUFS_RDHASH_DEF;
33595+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
33596+ if (unlikely(err)) {
1c60b727 33597+ kfree(whtmp);
1308ab2a 33598+ whtmp = ERR_PTR(err);
33599+ }
dece6358 33600+
4f0767ce 33601+out:
dece6358 33602+ return whtmp;
1facf9fc 33603+}
33604+
33605+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
33606+{
027c5e7a 33607+ if (whtmp->br)
5afbbe0d 33608+ au_br_put(whtmp->br);
1facf9fc 33609+ dput(whtmp->wh_dentry);
33610+ iput(whtmp->dir);
dece6358 33611+ au_nhash_wh_free(&whtmp->whlist);
1c60b727 33612+ kfree(whtmp);
1facf9fc 33613+}
33614+
33615+/*
33616+ * rmdir the whiteouted temporary named dir @h_dentry.
33617+ * @whlist: whiteouted children.
33618+ */
33619+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
33620+ struct dentry *wh_dentry, struct au_nhash *whlist)
33621+{
33622+ int err;
2000de60 33623+ unsigned int h_nlink;
1facf9fc 33624+ struct path h_tmp;
33625+ struct inode *wh_inode, *h_dir;
33626+ struct au_branch *br;
33627+
5527c038 33628+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
1facf9fc 33629+ IMustLock(h_dir);
33630+
33631+ br = au_sbr(dir->i_sb, bindex);
5527c038 33632+ wh_inode = d_inode(wh_dentry);
febd17d6 33633+ inode_lock_nested(wh_inode, AuLsc_I_CHILD);
1facf9fc 33634+
33635+ /*
33636+ * someone else might change some whiteouts while we were sleeping.
33637+ * it means this whlist may have an obsoleted entry.
33638+ */
33639+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
33640+ err = del_wh_children(wh_dentry, whlist, bindex, br);
33641+ else {
33642+ int wkq_err;
33643+ struct del_wh_children_args args = {
33644+ .errp = &err,
33645+ .h_dentry = wh_dentry,
1308ab2a 33646+ .whlist = whlist,
1facf9fc 33647+ .bindex = bindex,
33648+ .br = br
33649+ };
33650+
33651+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
33652+ if (unlikely(wkq_err))
33653+ err = wkq_err;
33654+ }
febd17d6 33655+ inode_unlock(wh_inode);
1facf9fc 33656+
33657+ if (!err) {
33658+ h_tmp.dentry = wh_dentry;
86dc4139 33659+ h_tmp.mnt = au_br_mnt(br);
2000de60 33660+ h_nlink = h_dir->i_nlink;
1facf9fc 33661+ err = vfsub_rmdir(h_dir, &h_tmp);
2000de60
JR
33662+ /* some fs doesn't change the parent nlink in some cases */
33663+ h_nlink -= h_dir->i_nlink;
1facf9fc 33664+ }
33665+
33666+ if (!err) {
5afbbe0d 33667+ if (au_ibtop(dir) == bindex) {
7f207e10 33668+ /* todo: dir->i_mutex is necessary */
1facf9fc 33669+ au_cpup_attr_timesizes(dir);
2000de60
JR
33670+ if (h_nlink)
33671+ vfsub_drop_nlink(dir);
1facf9fc 33672+ }
33673+ return 0; /* success */
33674+ }
33675+
523b37e3 33676+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 33677+ return err;
33678+}
33679+
33680+static void call_rmdir_whtmp(void *args)
33681+{
33682+ int err;
e49829fe 33683+ aufs_bindex_t bindex;
1facf9fc 33684+ struct au_whtmp_rmdir *a = args;
33685+ struct super_block *sb;
33686+ struct dentry *h_parent;
33687+ struct inode *h_dir;
1facf9fc 33688+ struct au_hinode *hdir;
33689+
33690+ /* rmdir by nfsd may cause deadlock with this i_mutex */
febd17d6 33691+ /* inode_lock(a->dir); */
e49829fe 33692+ err = -EROFS;
1facf9fc 33693+ sb = a->dir->i_sb;
e49829fe
JR
33694+ si_read_lock(sb, !AuLock_FLUSH);
33695+ if (!au_br_writable(a->br->br_perm))
33696+ goto out;
33697+ bindex = au_br_index(sb, a->br->br_id);
33698+ if (unlikely(bindex < 0))
1facf9fc 33699+ goto out;
33700+
33701+ err = -EIO;
1facf9fc 33702+ ii_write_lock_parent(a->dir);
33703+ h_parent = dget_parent(a->wh_dentry);
5527c038 33704+ h_dir = d_inode(h_parent);
e49829fe 33705+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
33706+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
33707+ if (unlikely(err))
33708+ goto out_mnt;
5afbbe0d 33709+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
33710+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
33711+ a->br);
86dc4139
AM
33712+ if (!err)
33713+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
5afbbe0d 33714+ au_hn_inode_unlock(hdir);
86dc4139
AM
33715+ vfsub_mnt_drop_write(au_br_mnt(a->br));
33716+
33717+out_mnt:
1facf9fc 33718+ dput(h_parent);
33719+ ii_write_unlock(a->dir);
4f0767ce 33720+out:
febd17d6 33721+ /* inode_unlock(a->dir); */
1facf9fc 33722+ au_whtmp_rmdir_free(a);
027c5e7a
AM
33723+ si_read_unlock(sb);
33724+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 33725+ if (unlikely(err))
33726+ AuIOErr("err %d\n", err);
33727+}
33728+
33729+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
33730+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
33731+{
33732+ int wkq_err;
e49829fe 33733+ struct super_block *sb;
1facf9fc 33734+
33735+ IMustLock(dir);
33736+
33737+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 33738+ sb = dir->i_sb;
1facf9fc 33739+ args->dir = au_igrab(dir);
e49829fe 33740+ args->br = au_sbr(sb, bindex);
5afbbe0d 33741+ au_br_get(args->br);
1facf9fc 33742+ args->wh_dentry = dget(wh_dentry);
53392da6 33743+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 33744+ if (unlikely(wkq_err)) {
523b37e3 33745+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 33746+ au_whtmp_rmdir_free(args);
33747+ }
33748+}
7f207e10
AM
33749diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
33750--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
3c1bdaff
AM
33751+++ linux/fs/aufs/whout.h 2017-09-05 10:42:11.058755349 +0200
33752@@ -0,0 +1,85 @@
1facf9fc 33753+/*
a2654f78 33754+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 33755+ *
33756+ * This program, aufs is free software; you can redistribute it and/or modify
33757+ * it under the terms of the GNU General Public License as published by
33758+ * the Free Software Foundation; either version 2 of the License, or
33759+ * (at your option) any later version.
dece6358
AM
33760+ *
33761+ * This program is distributed in the hope that it will be useful,
33762+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33763+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33764+ * GNU General Public License for more details.
33765+ *
33766+ * You should have received a copy of the GNU General Public License
523b37e3 33767+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33768+ */
33769+
33770+/*
33771+ * whiteout for logical deletion and opaque directory
33772+ */
33773+
33774+#ifndef __AUFS_WHOUT_H__
33775+#define __AUFS_WHOUT_H__
33776+
33777+#ifdef __KERNEL__
33778+
1facf9fc 33779+#include "dir.h"
33780+
33781+/* whout.c */
33782+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
076b876e
AM
33783+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
33784+int au_diropq_test(struct dentry *h_dentry);
3c1bdaff 33785+struct au_branch;
1facf9fc 33786+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
33787+ struct qstr *prefix);
33788+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
33789+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
33790+ struct dentry *dentry);
86dc4139 33791+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 33792+
33793+/* diropq flags */
33794+#define AuDiropq_CREATE 1
33795+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
33796+#define au_fset_diropq(flags, name) \
33797+ do { (flags) |= AuDiropq_##name; } while (0)
33798+#define au_fclr_diropq(flags, name) \
33799+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 33800+
33801+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
33802+ unsigned int flags);
33803+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
33804+ struct au_branch *br);
33805+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
33806+ struct dentry *h_parent);
33807+
33808+/* real rmdir for the whiteout-ed dir */
33809+struct au_whtmp_rmdir {
33810+ struct inode *dir;
e49829fe 33811+ struct au_branch *br;
1facf9fc 33812+ struct dentry *wh_dentry;
dece6358 33813+ struct au_nhash whlist;
1facf9fc 33814+};
33815+
33816+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
33817+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
33818+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
33819+ struct dentry *wh_dentry, struct au_nhash *whlist);
33820+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
33821+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
33822+
33823+/* ---------------------------------------------------------------------- */
33824+
33825+static inline struct dentry *au_diropq_create(struct dentry *dentry,
33826+ aufs_bindex_t bindex)
33827+{
33828+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
33829+}
33830+
33831+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
33832+{
33833+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
33834+}
33835+
33836+#endif /* __KERNEL__ */
33837+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
33838diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
33839--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 33840+++ linux/fs/aufs/wkq.c 2017-07-29 12:14:25.906375514 +0200
f0c0a007 33841@@ -0,0 +1,213 @@
1facf9fc 33842+/*
a2654f78 33843+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 33844+ *
33845+ * This program, aufs is free software; you can redistribute it and/or modify
33846+ * it under the terms of the GNU General Public License as published by
33847+ * the Free Software Foundation; either version 2 of the License, or
33848+ * (at your option) any later version.
dece6358
AM
33849+ *
33850+ * This program is distributed in the hope that it will be useful,
33851+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33852+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33853+ * GNU General Public License for more details.
33854+ *
33855+ * You should have received a copy of the GNU General Public License
523b37e3 33856+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33857+ */
33858+
33859+/*
33860+ * workqueue for asynchronous/super-io operations
33861+ * todo: try new dredential scheme
33862+ */
33863+
dece6358 33864+#include <linux/module.h>
1facf9fc 33865+#include "aufs.h"
33866+
9dbd164d 33867+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 33868+
9dbd164d 33869+static struct workqueue_struct *au_wkq;
1facf9fc 33870+
33871+struct au_wkinfo {
33872+ struct work_struct wk;
7f207e10 33873+ struct kobject *kobj;
1facf9fc 33874+
33875+ unsigned int flags; /* see wkq.h */
33876+
33877+ au_wkq_func_t func;
33878+ void *args;
33879+
1facf9fc 33880+ struct completion *comp;
33881+};
33882+
33883+/* ---------------------------------------------------------------------- */
33884+
1facf9fc 33885+static void wkq_func(struct work_struct *wk)
33886+{
33887+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
33888+
2dfbb274 33889+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
33890+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
33891+
1facf9fc 33892+ wkinfo->func(wkinfo->args);
1facf9fc 33893+ if (au_ftest_wkq(wkinfo->flags, WAIT))
33894+ complete(wkinfo->comp);
33895+ else {
7f207e10 33896+ kobject_put(wkinfo->kobj);
9dbd164d 33897+ module_put(THIS_MODULE); /* todo: ?? */
1c60b727 33898+ kfree(wkinfo);
1facf9fc 33899+ }
33900+}
33901+
33902+/*
33903+ * Since struct completion is large, try allocating it dynamically.
33904+ */
c2b27bf2 33905+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 33906+#define AuWkqCompDeclare(name) struct completion *comp = NULL
33907+
33908+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
33909+{
33910+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
33911+ if (*comp) {
33912+ init_completion(*comp);
33913+ wkinfo->comp = *comp;
33914+ return 0;
33915+ }
33916+ return -ENOMEM;
33917+}
33918+
33919+static void au_wkq_comp_free(struct completion *comp)
33920+{
1c60b727 33921+ kfree(comp);
1facf9fc 33922+}
33923+
33924+#else
33925+
33926+/* no braces */
33927+#define AuWkqCompDeclare(name) \
33928+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
33929+ struct completion *comp = &_ ## name
33930+
33931+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
33932+{
33933+ wkinfo->comp = *comp;
33934+ return 0;
33935+}
33936+
33937+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
33938+{
33939+ /* empty */
33940+}
33941+#endif /* 4KSTACKS */
33942+
53392da6 33943+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 33944+{
53392da6
AM
33945+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
33946+ if (au_wkq_test()) {
38d290e6
JR
33947+ AuWarn1("wkq from wkq, unless silly-rename on NFS,"
33948+ " due to a dead dir by UDBA?\n");
53392da6
AM
33949+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
33950+ }
33951+ } else
33952+ au_dbg_verify_kthread();
33953+
33954+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 33955+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 33956+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
33957+ } else {
33958+ INIT_WORK(&wkinfo->wk, wkq_func);
33959+ schedule_work(&wkinfo->wk);
33960+ }
1facf9fc 33961+}
33962+
7f207e10
AM
33963+/*
33964+ * Be careful. It is easy to make deadlock happen.
33965+ * processA: lock, wkq and wait
33966+ * processB: wkq and wait, lock in wkq
33967+ * --> deadlock
33968+ */
b752ccd1 33969+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 33970+{
33971+ int err;
33972+ AuWkqCompDeclare(comp);
33973+ struct au_wkinfo wkinfo = {
b752ccd1 33974+ .flags = flags,
1facf9fc 33975+ .func = func,
33976+ .args = args
33977+ };
33978+
33979+ err = au_wkq_comp_alloc(&wkinfo, &comp);
33980+ if (!err) {
53392da6 33981+ au_wkq_run(&wkinfo);
1facf9fc 33982+ /* no timeout, no interrupt */
33983+ wait_for_completion(wkinfo.comp);
33984+ au_wkq_comp_free(comp);
4a4d8108 33985+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 33986+ }
33987+
33988+ return err;
33989+
33990+}
33991+
027c5e7a
AM
33992+/*
33993+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
33994+ * problem in a concurrent umounting.
33995+ */
53392da6
AM
33996+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
33997+ unsigned int flags)
1facf9fc 33998+{
33999+ int err;
34000+ struct au_wkinfo *wkinfo;
34001+
f0c0a007 34002+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
1facf9fc 34003+
34004+ /*
34005+ * wkq_func() must free this wkinfo.
34006+ * it highly depends upon the implementation of workqueue.
34007+ */
34008+ err = 0;
34009+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
34010+ if (wkinfo) {
7f207e10 34011+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 34012+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 34013+ wkinfo->func = func;
34014+ wkinfo->args = args;
34015+ wkinfo->comp = NULL;
7f207e10 34016+ kobject_get(wkinfo->kobj);
9dbd164d 34017+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 34018+
53392da6 34019+ au_wkq_run(wkinfo);
1facf9fc 34020+ } else {
34021+ err = -ENOMEM;
e49829fe 34022+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 34023+ }
34024+
34025+ return err;
34026+}
34027+
34028+/* ---------------------------------------------------------------------- */
34029+
34030+void au_nwt_init(struct au_nowait_tasks *nwt)
34031+{
f0c0a007
AM
34032+ atomic_set(&nwt->nw_len, 0);
34033+ /* smp_mb(); */ /* atomic_set */
1facf9fc 34034+ init_waitqueue_head(&nwt->nw_wq);
34035+}
34036+
34037+void au_wkq_fin(void)
34038+{
9dbd164d 34039+ destroy_workqueue(au_wkq);
1facf9fc 34040+}
34041+
34042+int __init au_wkq_init(void)
34043+{
9dbd164d 34044+ int err;
b752ccd1
AM
34045+
34046+ err = 0;
86dc4139 34047+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
34048+ if (IS_ERR(au_wkq))
34049+ err = PTR_ERR(au_wkq);
34050+ else if (!au_wkq)
34051+ err = -ENOMEM;
b752ccd1
AM
34052+
34053+ return err;
1facf9fc 34054+}
7f207e10
AM
34055diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
34056--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
1c60b727 34057+++ linux/fs/aufs/wkq.h 2017-07-29 12:14:25.906375514 +0200
f0c0a007 34058@@ -0,0 +1,93 @@
1facf9fc 34059+/*
a2654f78 34060+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 34061+ *
34062+ * This program, aufs is free software; you can redistribute it and/or modify
34063+ * it under the terms of the GNU General Public License as published by
34064+ * the Free Software Foundation; either version 2 of the License, or
34065+ * (at your option) any later version.
dece6358
AM
34066+ *
34067+ * This program is distributed in the hope that it will be useful,
34068+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34069+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34070+ * GNU General Public License for more details.
34071+ *
34072+ * You should have received a copy of the GNU General Public License
523b37e3 34073+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 34074+ */
34075+
34076+/*
34077+ * workqueue for asynchronous/super-io operations
34078+ * todo: try new credentials management scheme
34079+ */
34080+
34081+#ifndef __AUFS_WKQ_H__
34082+#define __AUFS_WKQ_H__
34083+
34084+#ifdef __KERNEL__
34085+
5afbbe0d
AM
34086+#include <linux/percpu_counter.h>
34087+
dece6358
AM
34088+struct super_block;
34089+
1facf9fc 34090+/* ---------------------------------------------------------------------- */
34091+
34092+/*
34093+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
34094+ */
34095+struct au_nowait_tasks {
f0c0a007 34096+ atomic_t nw_len;
1facf9fc 34097+ wait_queue_head_t nw_wq;
34098+};
34099+
34100+/* ---------------------------------------------------------------------- */
34101+
34102+typedef void (*au_wkq_func_t)(void *args);
34103+
34104+/* wkq flags */
34105+#define AuWkq_WAIT 1
9dbd164d 34106+#define AuWkq_NEST (1 << 1)
1facf9fc 34107+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
34108+#define au_fset_wkq(flags, name) \
34109+ do { (flags) |= AuWkq_##name; } while (0)
34110+#define au_fclr_wkq(flags, name) \
34111+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 34112+
9dbd164d
AM
34113+#ifndef CONFIG_AUFS_HNOTIFY
34114+#undef AuWkq_NEST
34115+#define AuWkq_NEST 0
34116+#endif
34117+
1facf9fc 34118+/* wkq.c */
b752ccd1 34119+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
34120+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
34121+ unsigned int flags);
1facf9fc 34122+void au_nwt_init(struct au_nowait_tasks *nwt);
34123+int __init au_wkq_init(void);
34124+void au_wkq_fin(void);
34125+
34126+/* ---------------------------------------------------------------------- */
34127+
53392da6
AM
34128+static inline int au_wkq_test(void)
34129+{
34130+ return current->flags & PF_WQ_WORKER;
34131+}
34132+
b752ccd1 34133+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 34134+{
b752ccd1 34135+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 34136+}
34137+
34138+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
34139+{
f0c0a007 34140+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 34141+ wake_up_all(&nwt->nw_wq);
34142+}
34143+
34144+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
34145+{
f0c0a007 34146+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
1facf9fc 34147+ return 0;
34148+}
34149+
34150+#endif /* __KERNEL__ */
34151+#endif /* __AUFS_WKQ_H__ */
c1595e42
JR
34152diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
34153--- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100
3c1bdaff 34154+++ linux/fs/aufs/xattr.c 2017-09-05 10:42:11.058755349 +0200
a2654f78 34155@@ -0,0 +1,357 @@
c1595e42 34156+/*
a2654f78 34157+ * Copyright (C) 2014-2017 Junjiro R. Okajima
c1595e42
JR
34158+ *
34159+ * This program, aufs is free software; you can redistribute it and/or modify
34160+ * it under the terms of the GNU General Public License as published by
34161+ * the Free Software Foundation; either version 2 of the License, or
34162+ * (at your option) any later version.
34163+ *
34164+ * This program is distributed in the hope that it will be useful,
34165+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34166+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34167+ * GNU General Public License for more details.
34168+ *
34169+ * You should have received a copy of the GNU General Public License
34170+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
34171+ */
34172+
34173+/*
34174+ * handling xattr functions
34175+ */
34176+
a2654f78
AM
34177+#include <linux/fs.h>
34178+#include <linux/posix_acl_xattr.h>
c1595e42
JR
34179+#include <linux/xattr.h>
34180+#include "aufs.h"
34181+
34182+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
34183+{
34184+ if (!ignore_flags)
34185+ goto out;
34186+ switch (err) {
34187+ case -ENOMEM:
34188+ case -EDQUOT:
34189+ goto out;
34190+ }
34191+
34192+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
34193+ err = 0;
34194+ goto out;
34195+ }
34196+
34197+#define cmp(brattr, prefix) do { \
34198+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \
34199+ XATTR_##prefix##_PREFIX_LEN)) { \
34200+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \
34201+ err = 0; \
34202+ goto out; \
34203+ } \
34204+ } while (0)
34205+
34206+ cmp(SEC, SECURITY);
34207+ cmp(SYS, SYSTEM);
34208+ cmp(TR, TRUSTED);
34209+ cmp(USR, USER);
34210+#undef cmp
34211+
34212+ if (ignore_flags & AuBrAttr_ICEX_OTH)
34213+ err = 0;
34214+
34215+out:
34216+ return err;
34217+}
34218+
34219+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
34220+
34221+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe
AM
34222+ char *name, char **buf, unsigned int ignore_flags,
34223+ unsigned int verbose)
c1595e42
JR
34224+{
34225+ int err;
34226+ ssize_t ssz;
34227+ struct inode *h_idst;
34228+
34229+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
34230+ err = ssz;
34231+ if (unlikely(err <= 0)) {
c1595e42
JR
34232+ if (err == -ENODATA
34233+ || (err == -EOPNOTSUPP
b912730e 34234+ && ((ignore_flags & au_xattr_out_of_list)
5527c038 34235+ || (au_test_nfs_noacl(d_inode(h_src))
b912730e
AM
34236+ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)
34237+ || !strcmp(name,
34238+ XATTR_NAME_POSIX_ACL_DEFAULT))))
34239+ ))
c1595e42 34240+ err = 0;
b912730e
AM
34241+ if (err && (verbose || au_debug_test()))
34242+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
34243+ goto out;
34244+ }
34245+
34246+ /* unlock it temporary */
5527c038 34247+ h_idst = d_inode(h_dst);
febd17d6 34248+ inode_unlock(h_idst);
c1595e42 34249+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
febd17d6 34250+ inode_lock_nested(h_idst, AuLsc_I_CHILD2);
c1595e42 34251+ if (unlikely(err)) {
7e9cd9fe
AM
34252+ if (verbose || au_debug_test())
34253+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
34254+ err = au_xattr_ignore(err, name, ignore_flags);
34255+ }
34256+
34257+out:
34258+ return err;
34259+}
34260+
7e9cd9fe
AM
34261+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
34262+ unsigned int verbose)
c1595e42
JR
34263+{
34264+ int err, unlocked, acl_access, acl_default;
34265+ ssize_t ssz;
34266+ struct inode *h_isrc, *h_idst;
34267+ char *value, *p, *o, *e;
34268+
34269+ /* try stopping to update the source inode while we are referencing */
7e9cd9fe 34270+ /* there should not be the parent-child relationship between them */
5527c038
JR
34271+ h_isrc = d_inode(h_src);
34272+ h_idst = d_inode(h_dst);
febd17d6 34273+ inode_unlock(h_idst);
3c1bdaff 34274+ vfsub_inode_lock_shared_nested(h_isrc, AuLsc_I_CHILD);
febd17d6 34275+ inode_lock_nested(h_idst, AuLsc_I_CHILD2);
c1595e42
JR
34276+ unlocked = 0;
34277+
34278+ /* some filesystems don't list POSIX ACL, for example tmpfs */
34279+ ssz = vfs_listxattr(h_src, NULL, 0);
34280+ err = ssz;
34281+ if (unlikely(err < 0)) {
34282+ AuTraceErr(err);
34283+ if (err == -ENODATA
34284+ || err == -EOPNOTSUPP)
34285+ err = 0; /* ignore */
34286+ goto out;
34287+ }
34288+
34289+ err = 0;
34290+ p = NULL;
34291+ o = NULL;
34292+ if (ssz) {
34293+ err = -ENOMEM;
34294+ p = kmalloc(ssz, GFP_NOFS);
34295+ o = p;
34296+ if (unlikely(!p))
34297+ goto out;
34298+ err = vfs_listxattr(h_src, p, ssz);
34299+ }
3c1bdaff 34300+ inode_unlock_shared(h_isrc);
c1595e42
JR
34301+ unlocked = 1;
34302+ AuDbg("err %d, ssz %zd\n", err, ssz);
34303+ if (unlikely(err < 0))
34304+ goto out_free;
34305+
34306+ err = 0;
34307+ e = p + ssz;
34308+ value = NULL;
34309+ acl_access = 0;
34310+ acl_default = 0;
34311+ while (!err && p < e) {
34312+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
34313+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
34314+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
34315+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
34316+ - 1);
7e9cd9fe
AM
34317+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags,
34318+ verbose);
c1595e42
JR
34319+ p += strlen(p) + 1;
34320+ }
34321+ AuTraceErr(err);
34322+ ignore_flags |= au_xattr_out_of_list;
34323+ if (!err && !acl_access) {
34324+ err = au_do_cpup_xattr(h_dst, h_src,
34325+ XATTR_NAME_POSIX_ACL_ACCESS, &value,
7e9cd9fe 34326+ ignore_flags, verbose);
c1595e42
JR
34327+ AuTraceErr(err);
34328+ }
34329+ if (!err && !acl_default) {
34330+ err = au_do_cpup_xattr(h_dst, h_src,
34331+ XATTR_NAME_POSIX_ACL_DEFAULT, &value,
7e9cd9fe 34332+ ignore_flags, verbose);
c1595e42
JR
34333+ AuTraceErr(err);
34334+ }
34335+
f0c0a007 34336+ if (value)
1c60b727 34337+ kfree(value);
c1595e42
JR
34338+
34339+out_free:
f0c0a007 34340+ if (o)
1c60b727 34341+ kfree(o);
c1595e42
JR
34342+out:
34343+ if (!unlocked)
3c1bdaff 34344+ inode_unlock_shared(h_isrc);
c1595e42
JR
34345+ AuTraceErr(err);
34346+ return err;
34347+}
34348+
34349+/* ---------------------------------------------------------------------- */
34350+
a2654f78
AM
34351+static int au_smack_reentering(struct super_block *sb)
34352+{
34353+#if IS_ENABLED(CONFIG_SECURITY_SMACK)
34354+ /*
34355+ * as a part of lookup, smack_d_instantiate() is called, and it calls
34356+ * i_op->getxattr(). ouch.
34357+ */
34358+ return si_pid_test(sb);
34359+#else
34360+ return 0;
34361+#endif
34362+}
34363+
c1595e42
JR
34364+enum {
34365+ AU_XATTR_LIST,
34366+ AU_XATTR_GET
34367+};
34368+
34369+struct au_lgxattr {
34370+ int type;
34371+ union {
34372+ struct {
34373+ char *list;
34374+ size_t size;
34375+ } list;
34376+ struct {
34377+ const char *name;
34378+ void *value;
34379+ size_t size;
34380+ } get;
34381+ } u;
34382+};
34383+
34384+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
34385+{
34386+ ssize_t err;
a2654f78 34387+ int reenter;
c1595e42
JR
34388+ struct path h_path;
34389+ struct super_block *sb;
34390+
34391+ sb = dentry->d_sb;
a2654f78
AM
34392+ reenter = au_smack_reentering(sb);
34393+ if (!reenter) {
34394+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
34395+ if (unlikely(err))
34396+ goto out;
34397+ }
34398+ err = au_h_path_getattr(dentry, /*force*/1, &h_path, reenter);
c1595e42
JR
34399+ if (unlikely(err))
34400+ goto out_si;
34401+ if (unlikely(!h_path.dentry))
34402+ /* illegally overlapped or something */
34403+ goto out_di; /* pretending success */
34404+
34405+ /* always topmost entry only */
34406+ switch (arg->type) {
34407+ case AU_XATTR_LIST:
34408+ err = vfs_listxattr(h_path.dentry,
34409+ arg->u.list.list, arg->u.list.size);
34410+ break;
34411+ case AU_XATTR_GET:
5afbbe0d 34412+ AuDebugOn(d_is_negative(h_path.dentry));
c1595e42
JR
34413+ err = vfs_getxattr(h_path.dentry,
34414+ arg->u.get.name, arg->u.get.value,
34415+ arg->u.get.size);
34416+ break;
34417+ }
34418+
34419+out_di:
a2654f78
AM
34420+ if (!reenter)
34421+ di_read_unlock(dentry, AuLock_IR);
c1595e42 34422+out_si:
a2654f78
AM
34423+ if (!reenter)
34424+ si_read_unlock(sb);
c1595e42
JR
34425+out:
34426+ AuTraceErr(err);
34427+ return err;
34428+}
34429+
34430+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
34431+{
34432+ struct au_lgxattr arg = {
34433+ .type = AU_XATTR_LIST,
34434+ .u.list = {
34435+ .list = list,
34436+ .size = size
34437+ },
34438+ };
34439+
34440+ return au_lgxattr(dentry, &arg);
34441+}
34442+
f2c43d5f
AM
34443+static ssize_t au_getxattr(struct dentry *dentry,
34444+ struct inode *inode __maybe_unused,
34445+ const char *name, void *value, size_t size)
c1595e42
JR
34446+{
34447+ struct au_lgxattr arg = {
34448+ .type = AU_XATTR_GET,
34449+ .u.get = {
34450+ .name = name,
34451+ .value = value,
34452+ .size = size
34453+ },
34454+ };
34455+
34456+ return au_lgxattr(dentry, &arg);
34457+}
34458+
f2c43d5f
AM
34459+static int au_setxattr(struct dentry *dentry, struct inode *inode,
34460+ const char *name, const void *value, size_t size,
34461+ int flags)
c1595e42 34462+{
f2c43d5f 34463+ struct au_sxattr arg = {
c1595e42
JR
34464+ .type = AU_XATTR_SET,
34465+ .u.set = {
34466+ .name = name,
34467+ .value = value,
34468+ .size = size,
34469+ .flags = flags
34470+ },
34471+ };
34472+
f2c43d5f 34473+ return au_sxattr(dentry, inode, &arg);
c1595e42
JR
34474+}
34475+
34476+/* ---------------------------------------------------------------------- */
34477+
f2c43d5f
AM
34478+static int au_xattr_get(const struct xattr_handler *handler,
34479+ struct dentry *dentry, struct inode *inode,
34480+ const char *name, void *buffer, size_t size)
c1595e42 34481+{
f2c43d5f 34482+ return au_getxattr(dentry, inode, name, buffer, size);
c1595e42
JR
34483+}
34484+
f2c43d5f
AM
34485+static int au_xattr_set(const struct xattr_handler *handler,
34486+ struct dentry *dentry, struct inode *inode,
34487+ const char *name, const void *value, size_t size,
34488+ int flags)
c1595e42 34489+{
f2c43d5f 34490+ return au_setxattr(dentry, inode, name, value, size, flags);
c1595e42
JR
34491+}
34492+
34493+static const struct xattr_handler au_xattr_handler = {
f2c43d5f
AM
34494+ .name = "",
34495+ .prefix = "",
c1595e42
JR
34496+ .get = au_xattr_get,
34497+ .set = au_xattr_set
c1595e42
JR
34498+};
34499+
34500+static const struct xattr_handler *au_xattr_handlers[] = {
a2654f78
AM
34501+#ifdef CONFIG_FS_POSIX_ACL
34502+ &posix_acl_access_xattr_handler,
34503+ &posix_acl_default_xattr_handler,
34504+#endif
34505+ &au_xattr_handler, /* must be last */
f2c43d5f 34506+ NULL
c1595e42
JR
34507+};
34508+
34509+void au_xattr_init(struct super_block *sb)
34510+{
f2c43d5f 34511+ sb->s_xattr = au_xattr_handlers;
c1595e42 34512+}
7f207e10
AM
34513diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
34514--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
1c60b727 34515+++ linux/fs/aufs/xino.c 2017-07-29 12:14:25.906375514 +0200
521ced18 34516@@ -0,0 +1,1415 @@
1facf9fc 34517+/*
a2654f78 34518+ * Copyright (C) 2005-2017 Junjiro R. Okajima
1facf9fc 34519+ *
34520+ * This program, aufs is free software; you can redistribute it and/or modify
34521+ * it under the terms of the GNU General Public License as published by
34522+ * the Free Software Foundation; either version 2 of the License, or
34523+ * (at your option) any later version.
dece6358
AM
34524+ *
34525+ * This program is distributed in the hope that it will be useful,
34526+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34527+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34528+ * GNU General Public License for more details.
34529+ *
34530+ * You should have received a copy of the GNU General Public License
523b37e3 34531+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 34532+ */
34533+
34534+/*
34535+ * external inode number translation table and bitmap
34536+ */
34537+
34538+#include <linux/seq_file.h>
392086de 34539+#include <linux/statfs.h>
1facf9fc 34540+#include "aufs.h"
34541+
9dbd164d 34542+/* todo: unnecessary to support mmap_sem since kernel-space? */
5527c038 34543+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 34544+ loff_t *pos)
34545+{
34546+ ssize_t err;
34547+ mm_segment_t oldfs;
b752ccd1
AM
34548+ union {
34549+ void *k;
34550+ char __user *u;
34551+ } buf;
1facf9fc 34552+
b752ccd1 34553+ buf.k = kbuf;
1facf9fc 34554+ oldfs = get_fs();
34555+ set_fs(KERNEL_DS);
34556+ do {
34557+ /* todo: signal_pending? */
b752ccd1 34558+ err = func(file, buf.u, size, pos);
1facf9fc 34559+ } while (err == -EAGAIN || err == -EINTR);
34560+ set_fs(oldfs);
34561+
34562+#if 0 /* reserved for future use */
34563+ if (err > 0)
2000de60 34564+ fsnotify_access(file->f_path.dentry);
1facf9fc 34565+#endif
34566+
34567+ return err;
34568+}
34569+
34570+/* ---------------------------------------------------------------------- */
34571+
be52b249
AM
34572+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
34573+ size_t size, loff_t *pos);
34574+
5527c038 34575+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf,
1facf9fc 34576+ size_t size, loff_t *pos)
34577+{
34578+ ssize_t err;
34579+ mm_segment_t oldfs;
b752ccd1
AM
34580+ union {
34581+ void *k;
34582+ const char __user *u;
34583+ } buf;
be52b249
AM
34584+ int i;
34585+ const int prevent_endless = 10;
1facf9fc 34586+
be52b249 34587+ i = 0;
b752ccd1 34588+ buf.k = kbuf;
1facf9fc 34589+ oldfs = get_fs();
34590+ set_fs(KERNEL_DS);
1facf9fc 34591+ do {
b752ccd1 34592+ err = func(file, buf.u, size, pos);
be52b249
AM
34593+ if (err == -EINTR
34594+ && !au_wkq_test()
34595+ && fatal_signal_pending(current)) {
34596+ set_fs(oldfs);
34597+ err = xino_fwrite_wkq(func, file, kbuf, size, pos);
34598+ BUG_ON(err == -EINTR);
34599+ oldfs = get_fs();
34600+ set_fs(KERNEL_DS);
34601+ }
34602+ } while (i++ < prevent_endless
34603+ && (err == -EAGAIN || err == -EINTR));
1facf9fc 34604+ set_fs(oldfs);
34605+
34606+#if 0 /* reserved for future use */
34607+ if (err > 0)
2000de60 34608+ fsnotify_modify(file->f_path.dentry);
1facf9fc 34609+#endif
34610+
34611+ return err;
34612+}
34613+
34614+struct do_xino_fwrite_args {
34615+ ssize_t *errp;
5527c038 34616+ vfs_writef_t func;
1facf9fc 34617+ struct file *file;
34618+ void *buf;
34619+ size_t size;
34620+ loff_t *pos;
34621+};
34622+
34623+static void call_do_xino_fwrite(void *args)
34624+{
34625+ struct do_xino_fwrite_args *a = args;
34626+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
34627+}
34628+
be52b249
AM
34629+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf,
34630+ size_t size, loff_t *pos)
34631+{
34632+ ssize_t err;
34633+ int wkq_err;
34634+ struct do_xino_fwrite_args args = {
34635+ .errp = &err,
34636+ .func = func,
34637+ .file = file,
34638+ .buf = buf,
34639+ .size = size,
34640+ .pos = pos
34641+ };
34642+
34643+ /*
34644+ * it breaks RLIMIT_FSIZE and normal user's limit,
34645+ * users should care about quota and real 'filesystem full.'
34646+ */
34647+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
34648+ if (unlikely(wkq_err))
34649+ err = wkq_err;
34650+
34651+ return err;
34652+}
34653+
5527c038
JR
34654+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
34655+ size_t size, loff_t *pos)
1facf9fc 34656+{
34657+ ssize_t err;
34658+
b752ccd1
AM
34659+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
34660+ lockdep_off();
34661+ err = do_xino_fwrite(func, file, buf, size, pos);
34662+ lockdep_on();
be52b249
AM
34663+ } else
34664+ err = xino_fwrite_wkq(func, file, buf, size, pos);
1facf9fc 34665+
34666+ return err;
34667+}
34668+
34669+/* ---------------------------------------------------------------------- */
34670+
34671+/*
34672+ * create a new xinofile at the same place/path as @base_file.
34673+ */
34674+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
34675+{
34676+ struct file *file;
4a4d8108 34677+ struct dentry *base, *parent;
523b37e3 34678+ struct inode *dir, *delegated;
1facf9fc 34679+ struct qstr *name;
1308ab2a 34680+ struct path path;
4a4d8108 34681+ int err;
1facf9fc 34682+
2000de60 34683+ base = base_file->f_path.dentry;
1facf9fc 34684+ parent = base->d_parent; /* dir inode is locked */
5527c038 34685+ dir = d_inode(parent);
1facf9fc 34686+ IMustLock(dir);
34687+
34688+ file = ERR_PTR(-EINVAL);
34689+ name = &base->d_name;
4a4d8108
AM
34690+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
34691+ if (IS_ERR(path.dentry)) {
34692+ file = (void *)path.dentry;
523b37e3
AM
34693+ pr_err("%pd lookup err %ld\n",
34694+ base, PTR_ERR(path.dentry));
1facf9fc 34695+ goto out;
34696+ }
34697+
34698+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 34699+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 34700+ if (unlikely(err)) {
34701+ file = ERR_PTR(err);
523b37e3 34702+ pr_err("%pd create err %d\n", base, err);
1facf9fc 34703+ goto out_dput;
34704+ }
34705+
c06a8ce3 34706+ path.mnt = base_file->f_path.mnt;
4a4d8108 34707+ file = vfsub_dentry_open(&path,
7f207e10 34708+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 34709+ /* | __FMODE_NONOTIFY */);
1facf9fc 34710+ if (IS_ERR(file)) {
523b37e3 34711+ pr_err("%pd open err %ld\n", base, PTR_ERR(file));
1facf9fc 34712+ goto out_dput;
34713+ }
34714+
523b37e3
AM
34715+ delegated = NULL;
34716+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
34717+ if (unlikely(err == -EWOULDBLOCK)) {
34718+ pr_warn("cannot retry for NFSv4 delegation"
34719+ " for an internal unlink\n");
34720+ iput(delegated);
34721+ }
1facf9fc 34722+ if (unlikely(err)) {
523b37e3 34723+ pr_err("%pd unlink err %d\n", base, err);
1facf9fc 34724+ goto out_fput;
34725+ }
34726+
34727+ if (copy_src) {
34728+ /* no one can touch copy_src xino */
c06a8ce3 34729+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 34730+ if (unlikely(err)) {
523b37e3 34731+ pr_err("%pd copy err %d\n", base, err);
1facf9fc 34732+ goto out_fput;
34733+ }
34734+ }
34735+ goto out_dput; /* success */
34736+
4f0767ce 34737+out_fput:
1facf9fc 34738+ fput(file);
34739+ file = ERR_PTR(err);
4f0767ce 34740+out_dput:
4a4d8108 34741+ dput(path.dentry);
4f0767ce 34742+out:
1facf9fc 34743+ return file;
34744+}
34745+
34746+struct au_xino_lock_dir {
34747+ struct au_hinode *hdir;
34748+ struct dentry *parent;
febd17d6 34749+ struct inode *dir;
1facf9fc 34750+};
34751+
34752+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
34753+ struct au_xino_lock_dir *ldir)
34754+{
34755+ aufs_bindex_t brid, bindex;
34756+
34757+ ldir->hdir = NULL;
34758+ bindex = -1;
34759+ brid = au_xino_brid(sb);
34760+ if (brid >= 0)
34761+ bindex = au_br_index(sb, brid);
34762+ if (bindex >= 0) {
5527c038 34763+ ldir->hdir = au_hi(d_inode(sb->s_root), bindex);
5afbbe0d 34764+ au_hn_inode_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 34765+ } else {
2000de60 34766+ ldir->parent = dget_parent(xino->f_path.dentry);
febd17d6
JR
34767+ ldir->dir = d_inode(ldir->parent);
34768+ inode_lock_nested(ldir->dir, AuLsc_I_PARENT);
1facf9fc 34769+ }
34770+}
34771+
34772+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
34773+{
34774+ if (ldir->hdir)
5afbbe0d 34775+ au_hn_inode_unlock(ldir->hdir);
1facf9fc 34776+ else {
febd17d6 34777+ inode_unlock(ldir->dir);
1facf9fc 34778+ dput(ldir->parent);
34779+ }
34780+}
34781+
34782+/* ---------------------------------------------------------------------- */
34783+
34784+/* trucate xino files asynchronously */
34785+
34786+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
34787+{
34788+ int err;
392086de
AM
34789+ unsigned long jiffy;
34790+ blkcnt_t blocks;
5afbbe0d 34791+ aufs_bindex_t bi, bbot;
392086de 34792+ struct kstatfs *st;
1facf9fc 34793+ struct au_branch *br;
34794+ struct file *new_xino, *file;
34795+ struct super_block *h_sb;
34796+ struct au_xino_lock_dir ldir;
34797+
392086de 34798+ err = -ENOMEM;
be52b249 34799+ st = kmalloc(sizeof(*st), GFP_NOFS);
392086de
AM
34800+ if (unlikely(!st))
34801+ goto out;
34802+
1facf9fc 34803+ err = -EINVAL;
5afbbe0d
AM
34804+ bbot = au_sbbot(sb);
34805+ if (unlikely(bindex < 0 || bbot < bindex))
392086de 34806+ goto out_st;
1facf9fc 34807+ br = au_sbr(sb, bindex);
34808+ file = br->br_xino.xi_file;
34809+ if (!file)
392086de
AM
34810+ goto out_st;
34811+
34812+ err = vfs_statfs(&file->f_path, st);
34813+ if (unlikely(err))
34814+ AuErr1("statfs err %d, ignored\n", err);
34815+ jiffy = jiffies;
34816+ blocks = file_inode(file)->i_blocks;
34817+ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
34818+ bindex, (u64)blocks, st->f_bfree, st->f_blocks);
1facf9fc 34819+
34820+ au_xino_lock_dir(sb, file, &ldir);
34821+ /* mnt_want_write() is unnecessary here */
34822+ new_xino = au_xino_create2(file, file);
34823+ au_xino_unlock_dir(&ldir);
34824+ err = PTR_ERR(new_xino);
392086de
AM
34825+ if (IS_ERR(new_xino)) {
34826+ pr_err("err %d, ignored\n", err);
34827+ goto out_st;
34828+ }
1facf9fc 34829+ err = 0;
34830+ fput(file);
34831+ br->br_xino.xi_file = new_xino;
34832+
86dc4139 34833+ h_sb = au_br_sb(br);
5afbbe0d 34834+ for (bi = 0; bi <= bbot; bi++) {
1facf9fc 34835+ if (unlikely(bi == bindex))
34836+ continue;
34837+ br = au_sbr(sb, bi);
86dc4139 34838+ if (au_br_sb(br) != h_sb)
1facf9fc 34839+ continue;
34840+
34841+ fput(br->br_xino.xi_file);
34842+ br->br_xino.xi_file = new_xino;
34843+ get_file(new_xino);
34844+ }
34845+
392086de
AM
34846+ err = vfs_statfs(&new_xino->f_path, st);
34847+ if (!err) {
34848+ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
34849+ bindex, (u64)file_inode(new_xino)->i_blocks,
34850+ st->f_bfree, st->f_blocks);
34851+ if (file_inode(new_xino)->i_blocks < blocks)
34852+ au_sbi(sb)->si_xino_jiffy = jiffy;
34853+ } else
34854+ AuErr1("statfs err %d, ignored\n", err);
34855+
34856+out_st:
1c60b727 34857+ kfree(st);
4f0767ce 34858+out:
1facf9fc 34859+ return err;
34860+}
34861+
34862+struct xino_do_trunc_args {
34863+ struct super_block *sb;
34864+ struct au_branch *br;
34865+};
34866+
34867+static void xino_do_trunc(void *_args)
34868+{
34869+ struct xino_do_trunc_args *args = _args;
34870+ struct super_block *sb;
34871+ struct au_branch *br;
34872+ struct inode *dir;
34873+ int err;
34874+ aufs_bindex_t bindex;
34875+
34876+ err = 0;
34877+ sb = args->sb;
5527c038 34878+ dir = d_inode(sb->s_root);
1facf9fc 34879+ br = args->br;
34880+
34881+ si_noflush_write_lock(sb);
34882+ ii_read_lock_parent(dir);
34883+ bindex = au_br_index(sb, br->br_id);
34884+ err = au_xino_trunc(sb, bindex);
1facf9fc 34885+ ii_read_unlock(dir);
34886+ if (unlikely(err))
392086de 34887+ pr_warn("err b%d, (%d)\n", bindex, err);
1facf9fc 34888+ atomic_dec(&br->br_xino_running);
5afbbe0d 34889+ au_br_put(br);
1facf9fc 34890+ si_write_unlock(sb);
027c5e7a 34891+ au_nwt_done(&au_sbi(sb)->si_nowait);
1c60b727 34892+ kfree(args);
1facf9fc 34893+}
34894+
392086de
AM
34895+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
34896+{
34897+ int err;
34898+ struct kstatfs st;
34899+ struct au_sbinfo *sbinfo;
34900+
34901+ /* todo: si_xino_expire and the ratio should be customizable */
34902+ sbinfo = au_sbi(sb);
34903+ if (time_before(jiffies,
34904+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
34905+ return 0;
34906+
34907+ /* truncation border */
34908+ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
34909+ if (unlikely(err)) {
34910+ AuErr1("statfs err %d, ignored\n", err);
34911+ return 0;
34912+ }
34913+ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
34914+ return 0;
34915+
34916+ return 1;
34917+}
34918+
1facf9fc 34919+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
34920+{
34921+ struct xino_do_trunc_args *args;
34922+ int wkq_err;
34923+
392086de 34924+ if (!xino_trunc_test(sb, br))
1facf9fc 34925+ return;
34926+
34927+ if (atomic_inc_return(&br->br_xino_running) > 1)
34928+ goto out;
34929+
34930+ /* lock and kfree() will be called in trunc_xino() */
34931+ args = kmalloc(sizeof(*args), GFP_NOFS);
34932+ if (unlikely(!args)) {
34933+ AuErr1("no memory\n");
f0c0a007 34934+ goto out;
1facf9fc 34935+ }
34936+
5afbbe0d 34937+ au_br_get(br);
1facf9fc 34938+ args->sb = sb;
34939+ args->br = br;
53392da6 34940+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 34941+ if (!wkq_err)
34942+ return; /* success */
34943+
4a4d8108 34944+ pr_err("wkq %d\n", wkq_err);
5afbbe0d 34945+ au_br_put(br);
1c60b727 34946+ kfree(args);
1facf9fc 34947+
4f0767ce 34948+out:
e49829fe 34949+ atomic_dec(&br->br_xino_running);
1facf9fc 34950+}
34951+
34952+/* ---------------------------------------------------------------------- */
34953+
5527c038 34954+static int au_xino_do_write(vfs_writef_t write, struct file *file,
1facf9fc 34955+ ino_t h_ino, ino_t ino)
34956+{
34957+ loff_t pos;
34958+ ssize_t sz;
34959+
34960+ pos = h_ino;
34961+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
34962+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
34963+ return -EFBIG;
34964+ }
34965+ pos *= sizeof(ino);
34966+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
34967+ if (sz == sizeof(ino))
34968+ return 0; /* success */
34969+
34970+ AuIOErr("write failed (%zd)\n", sz);
34971+ return -EIO;
34972+}
34973+
34974+/*
34975+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
34976+ * at the position of @h_ino.
34977+ * even if @ino is zero, it is written to the xinofile and means no entry.
34978+ * if the size of the xino file on a specific filesystem exceeds the watermark,
34979+ * try truncating it.
34980+ */
34981+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
34982+ ino_t ino)
34983+{
34984+ int err;
34985+ unsigned int mnt_flags;
34986+ struct au_branch *br;
34987+
34988+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
34989+ || ((loff_t)-1) > 0);
dece6358 34990+ SiMustAnyLock(sb);
1facf9fc 34991+
34992+ mnt_flags = au_mntflags(sb);
34993+ if (!au_opt_test(mnt_flags, XINO))
34994+ return 0;
34995+
34996+ br = au_sbr(sb, bindex);
34997+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
34998+ h_ino, ino);
34999+ if (!err) {
35000+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 35001+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 35002+ xino_try_trunc(sb, br);
35003+ return 0; /* success */
35004+ }
35005+
35006+ AuIOErr("write failed (%d)\n", err);
35007+ return -EIO;
35008+}
35009+
35010+/* ---------------------------------------------------------------------- */
35011+
35012+/* aufs inode number bitmap */
35013+
35014+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
35015+static ino_t xib_calc_ino(unsigned long pindex, int bit)
35016+{
35017+ ino_t ino;
35018+
35019+ AuDebugOn(bit < 0 || page_bits <= bit);
35020+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
35021+ return ino;
35022+}
35023+
35024+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
35025+{
35026+ AuDebugOn(ino < AUFS_FIRST_INO);
35027+ ino -= AUFS_FIRST_INO;
35028+ *pindex = ino / page_bits;
35029+ *bit = ino % page_bits;
35030+}
35031+
35032+static int xib_pindex(struct super_block *sb, unsigned long pindex)
35033+{
35034+ int err;
35035+ loff_t pos;
35036+ ssize_t sz;
35037+ struct au_sbinfo *sbinfo;
35038+ struct file *xib;
35039+ unsigned long *p;
35040+
35041+ sbinfo = au_sbi(sb);
35042+ MtxMustLock(&sbinfo->si_xib_mtx);
35043+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
35044+ || !au_opt_test(sbinfo->si_mntflags, XINO));
35045+
35046+ if (pindex == sbinfo->si_xib_last_pindex)
35047+ return 0;
35048+
35049+ xib = sbinfo->si_xib;
35050+ p = sbinfo->si_xib_buf;
35051+ pos = sbinfo->si_xib_last_pindex;
35052+ pos *= PAGE_SIZE;
35053+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
35054+ if (unlikely(sz != PAGE_SIZE))
35055+ goto out;
35056+
35057+ pos = pindex;
35058+ pos *= PAGE_SIZE;
c06a8ce3 35059+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 35060+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
35061+ else {
35062+ memset(p, 0, PAGE_SIZE);
35063+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
35064+ }
35065+ if (sz == PAGE_SIZE) {
35066+ sbinfo->si_xib_last_pindex = pindex;
35067+ return 0; /* success */
35068+ }
35069+
4f0767ce 35070+out:
b752ccd1
AM
35071+ AuIOErr1("write failed (%zd)\n", sz);
35072+ err = sz;
35073+ if (sz >= 0)
35074+ err = -EIO;
35075+ return err;
35076+}
35077+
35078+/* ---------------------------------------------------------------------- */
35079+
35080+static void au_xib_clear_bit(struct inode *inode)
35081+{
35082+ int err, bit;
35083+ unsigned long pindex;
35084+ struct super_block *sb;
35085+ struct au_sbinfo *sbinfo;
35086+
35087+ AuDebugOn(inode->i_nlink);
35088+
35089+ sb = inode->i_sb;
35090+ xib_calc_bit(inode->i_ino, &pindex, &bit);
35091+ AuDebugOn(page_bits <= bit);
35092+ sbinfo = au_sbi(sb);
35093+ mutex_lock(&sbinfo->si_xib_mtx);
35094+ err = xib_pindex(sb, pindex);
35095+ if (!err) {
35096+ clear_bit(bit, sbinfo->si_xib_buf);
35097+ sbinfo->si_xib_next_bit = bit;
35098+ }
35099+ mutex_unlock(&sbinfo->si_xib_mtx);
35100+}
35101+
35102+/* for s_op->delete_inode() */
35103+void au_xino_delete_inode(struct inode *inode, const int unlinked)
35104+{
35105+ int err;
35106+ unsigned int mnt_flags;
5afbbe0d 35107+ aufs_bindex_t bindex, bbot, bi;
b752ccd1
AM
35108+ unsigned char try_trunc;
35109+ struct au_iinfo *iinfo;
35110+ struct super_block *sb;
35111+ struct au_hinode *hi;
35112+ struct inode *h_inode;
35113+ struct au_branch *br;
5527c038 35114+ vfs_writef_t xwrite;
b752ccd1 35115+
5afbbe0d
AM
35116+ AuDebugOn(au_is_bad_inode(inode));
35117+
b752ccd1
AM
35118+ sb = inode->i_sb;
35119+ mnt_flags = au_mntflags(sb);
35120+ if (!au_opt_test(mnt_flags, XINO)
35121+ || inode->i_ino == AUFS_ROOT_INO)
35122+ return;
35123+
35124+ if (unlinked) {
35125+ au_xigen_inc(inode);
35126+ au_xib_clear_bit(inode);
35127+ }
35128+
35129+ iinfo = au_ii(inode);
5afbbe0d 35130+ bindex = iinfo->ii_btop;
b752ccd1
AM
35131+ if (bindex < 0)
35132+ return;
1facf9fc 35133+
b752ccd1
AM
35134+ xwrite = au_sbi(sb)->si_xwrite;
35135+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
5afbbe0d
AM
35136+ hi = au_hinode(iinfo, bindex);
35137+ bbot = iinfo->ii_bbot;
35138+ for (; bindex <= bbot; bindex++, hi++) {
b752ccd1
AM
35139+ h_inode = hi->hi_inode;
35140+ if (!h_inode
35141+ || (!unlinked && h_inode->i_nlink))
35142+ continue;
1facf9fc 35143+
b752ccd1
AM
35144+ /* inode may not be revalidated */
35145+ bi = au_br_index(sb, hi->hi_id);
35146+ if (bi < 0)
35147+ continue;
1facf9fc 35148+
b752ccd1
AM
35149+ br = au_sbr(sb, bi);
35150+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
35151+ h_inode->i_ino, /*ino*/0);
35152+ if (!err && try_trunc
86dc4139 35153+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 35154+ xino_try_trunc(sb, br);
1facf9fc 35155+ }
1facf9fc 35156+}
35157+
35158+/* get an unused inode number from bitmap */
35159+ino_t au_xino_new_ino(struct super_block *sb)
35160+{
35161+ ino_t ino;
35162+ unsigned long *p, pindex, ul, pend;
35163+ struct au_sbinfo *sbinfo;
35164+ struct file *file;
35165+ int free_bit, err;
35166+
35167+ if (!au_opt_test(au_mntflags(sb), XINO))
35168+ return iunique(sb, AUFS_FIRST_INO);
35169+
35170+ sbinfo = au_sbi(sb);
35171+ mutex_lock(&sbinfo->si_xib_mtx);
35172+ p = sbinfo->si_xib_buf;
35173+ free_bit = sbinfo->si_xib_next_bit;
35174+ if (free_bit < page_bits && !test_bit(free_bit, p))
35175+ goto out; /* success */
35176+ free_bit = find_first_zero_bit(p, page_bits);
35177+ if (free_bit < page_bits)
35178+ goto out; /* success */
35179+
35180+ pindex = sbinfo->si_xib_last_pindex;
35181+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
35182+ err = xib_pindex(sb, ul);
35183+ if (unlikely(err))
35184+ goto out_err;
35185+ free_bit = find_first_zero_bit(p, page_bits);
35186+ if (free_bit < page_bits)
35187+ goto out; /* success */
35188+ }
35189+
35190+ file = sbinfo->si_xib;
c06a8ce3 35191+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 35192+ for (ul = pindex + 1; ul <= pend; ul++) {
35193+ err = xib_pindex(sb, ul);
35194+ if (unlikely(err))
35195+ goto out_err;
35196+ free_bit = find_first_zero_bit(p, page_bits);
35197+ if (free_bit < page_bits)
35198+ goto out; /* success */
35199+ }
35200+ BUG();
35201+
4f0767ce 35202+out:
1facf9fc 35203+ set_bit(free_bit, p);
7f207e10 35204+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 35205+ pindex = sbinfo->si_xib_last_pindex;
35206+ mutex_unlock(&sbinfo->si_xib_mtx);
35207+ ino = xib_calc_ino(pindex, free_bit);
35208+ AuDbg("i%lu\n", (unsigned long)ino);
35209+ return ino;
4f0767ce 35210+out_err:
1facf9fc 35211+ mutex_unlock(&sbinfo->si_xib_mtx);
35212+ AuDbg("i0\n");
35213+ return 0;
35214+}
35215+
35216+/*
35217+ * read @ino from xinofile for the specified branch{@sb, @bindex}
35218+ * at the position of @h_ino.
35219+ * if @ino does not exist and @do_new is true, get new one.
35220+ */
35221+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
35222+ ino_t *ino)
35223+{
35224+ int err;
35225+ ssize_t sz;
35226+ loff_t pos;
35227+ struct file *file;
35228+ struct au_sbinfo *sbinfo;
35229+
35230+ *ino = 0;
35231+ if (!au_opt_test(au_mntflags(sb), XINO))
35232+ return 0; /* no xino */
35233+
35234+ err = 0;
35235+ sbinfo = au_sbi(sb);
35236+ pos = h_ino;
35237+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
35238+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
35239+ return -EFBIG;
35240+ }
35241+ pos *= sizeof(*ino);
35242+
35243+ file = au_sbr(sb, bindex)->br_xino.xi_file;
c06a8ce3 35244+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 35245+ return 0; /* no ino */
35246+
35247+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
35248+ if (sz == sizeof(*ino))
35249+ return 0; /* success */
35250+
35251+ err = sz;
35252+ if (unlikely(sz >= 0)) {
35253+ err = -EIO;
35254+ AuIOErr("xino read error (%zd)\n", sz);
35255+ }
35256+
35257+ return err;
35258+}
35259+
35260+/* ---------------------------------------------------------------------- */
35261+
35262+/* create and set a new xino file */
35263+
35264+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
35265+{
35266+ struct file *file;
35267+ struct dentry *h_parent, *d;
b912730e 35268+ struct inode *h_dir, *inode;
1facf9fc 35269+ int err;
35270+
35271+ /*
35272+ * at mount-time, and the xino file is the default path,
4a4d8108 35273+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 35274+ * when a user specified the xino, we cannot get au_hdir to be ignored.
35275+ */
7f207e10 35276+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 35277+ /* | __FMODE_NONOTIFY */,
1facf9fc 35278+ S_IRUGO | S_IWUGO);
35279+ if (IS_ERR(file)) {
35280+ if (!silent)
4a4d8108 35281+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 35282+ return file;
35283+ }
35284+
35285+ /* keep file count */
b912730e
AM
35286+ err = 0;
35287+ inode = file_inode(file);
2000de60 35288+ h_parent = dget_parent(file->f_path.dentry);
5527c038 35289+ h_dir = d_inode(h_parent);
febd17d6 35290+ inode_lock_nested(h_dir, AuLsc_I_PARENT);
1facf9fc 35291+ /* mnt_want_write() is unnecessary here */
523b37e3 35292+ /* no delegation since it is just created */
b912730e
AM
35293+ if (inode->i_nlink)
35294+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL,
35295+ /*force*/0);
febd17d6 35296+ inode_unlock(h_dir);
1facf9fc 35297+ dput(h_parent);
35298+ if (unlikely(err)) {
35299+ if (!silent)
4a4d8108 35300+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 35301+ goto out;
35302+ }
35303+
35304+ err = -EINVAL;
2000de60 35305+ d = file->f_path.dentry;
1facf9fc 35306+ if (unlikely(sb == d->d_sb)) {
35307+ if (!silent)
4a4d8108 35308+ pr_err("%s must be outside\n", fname);
1facf9fc 35309+ goto out;
35310+ }
35311+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
35312+ if (!silent)
4a4d8108
AM
35313+ pr_err("xino doesn't support %s(%s)\n",
35314+ fname, au_sbtype(d->d_sb));
1facf9fc 35315+ goto out;
35316+ }
35317+ return file; /* success */
35318+
4f0767ce 35319+out:
1facf9fc 35320+ fput(file);
35321+ file = ERR_PTR(err);
35322+ return file;
35323+}
35324+
35325+/*
35326+ * find another branch who is on the same filesystem of the specified
5afbbe0d 35327+ * branch{@btgt}. search until @bbot.
1facf9fc 35328+ */
35329+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
5afbbe0d 35330+ aufs_bindex_t bbot)
1facf9fc 35331+{
35332+ aufs_bindex_t bindex;
35333+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
35334+
35335+ for (bindex = 0; bindex < btgt; bindex++)
35336+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
35337+ return bindex;
5afbbe0d 35338+ for (bindex++; bindex <= bbot; bindex++)
1facf9fc 35339+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
35340+ return bindex;
35341+ return -1;
35342+}
35343+
35344+/* ---------------------------------------------------------------------- */
35345+
35346+/*
35347+ * initialize the xinofile for the specified branch @br
35348+ * at the place/path where @base_file indicates.
35349+ * test whether another branch is on the same filesystem or not,
35350+ * if @do_test is true.
35351+ */
35352+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
35353+ struct file *base_file, int do_test)
35354+{
35355+ int err;
35356+ ino_t ino;
5afbbe0d 35357+ aufs_bindex_t bbot, bindex;
1facf9fc 35358+ struct au_branch *shared_br, *b;
35359+ struct file *file;
35360+ struct super_block *tgt_sb;
35361+
35362+ shared_br = NULL;
5afbbe0d 35363+ bbot = au_sbbot(sb);
1facf9fc 35364+ if (do_test) {
86dc4139 35365+ tgt_sb = au_br_sb(br);
5afbbe0d 35366+ for (bindex = 0; bindex <= bbot; bindex++) {
1facf9fc 35367+ b = au_sbr(sb, bindex);
86dc4139 35368+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 35369+ shared_br = b;
35370+ break;
35371+ }
35372+ }
35373+ }
35374+
35375+ if (!shared_br || !shared_br->br_xino.xi_file) {
35376+ struct au_xino_lock_dir ldir;
35377+
35378+ au_xino_lock_dir(sb, base_file, &ldir);
35379+ /* mnt_want_write() is unnecessary here */
35380+ file = au_xino_create2(base_file, NULL);
35381+ au_xino_unlock_dir(&ldir);
35382+ err = PTR_ERR(file);
35383+ if (IS_ERR(file))
35384+ goto out;
35385+ br->br_xino.xi_file = file;
35386+ } else {
35387+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
35388+ get_file(br->br_xino.xi_file);
35389+ }
35390+
35391+ ino = AUFS_ROOT_INO;
35392+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
35393+ h_ino, ino);
b752ccd1
AM
35394+ if (unlikely(err)) {
35395+ fput(br->br_xino.xi_file);
35396+ br->br_xino.xi_file = NULL;
35397+ }
1facf9fc 35398+
4f0767ce 35399+out:
1facf9fc 35400+ return err;
35401+}
35402+
35403+/* ---------------------------------------------------------------------- */
35404+
35405+/* trucate a xino bitmap file */
35406+
35407+/* todo: slow */
35408+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
35409+{
35410+ int err, bit;
35411+ ssize_t sz;
35412+ unsigned long pindex;
35413+ loff_t pos, pend;
35414+ struct au_sbinfo *sbinfo;
5527c038 35415+ vfs_readf_t func;
1facf9fc 35416+ ino_t *ino;
35417+ unsigned long *p;
35418+
35419+ err = 0;
35420+ sbinfo = au_sbi(sb);
dece6358 35421+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 35422+ p = sbinfo->si_xib_buf;
35423+ func = sbinfo->si_xread;
c06a8ce3 35424+ pend = vfsub_f_size_read(file);
1facf9fc 35425+ pos = 0;
35426+ while (pos < pend) {
35427+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
35428+ err = sz;
35429+ if (unlikely(sz <= 0))
35430+ goto out;
35431+
35432+ err = 0;
35433+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
35434+ if (unlikely(*ino < AUFS_FIRST_INO))
35435+ continue;
35436+
35437+ xib_calc_bit(*ino, &pindex, &bit);
35438+ AuDebugOn(page_bits <= bit);
35439+ err = xib_pindex(sb, pindex);
35440+ if (!err)
35441+ set_bit(bit, p);
35442+ else
35443+ goto out;
35444+ }
35445+ }
35446+
4f0767ce 35447+out:
1facf9fc 35448+ return err;
35449+}
35450+
35451+static int xib_restore(struct super_block *sb)
35452+{
35453+ int err;
5afbbe0d 35454+ aufs_bindex_t bindex, bbot;
1facf9fc 35455+ void *page;
35456+
35457+ err = -ENOMEM;
35458+ page = (void *)__get_free_page(GFP_NOFS);
35459+ if (unlikely(!page))
35460+ goto out;
35461+
35462+ err = 0;
5afbbe0d
AM
35463+ bbot = au_sbbot(sb);
35464+ for (bindex = 0; !err && bindex <= bbot; bindex++)
1facf9fc 35465+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
35466+ err = do_xib_restore
35467+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
35468+ else
35469+ AuDbg("b%d\n", bindex);
1c60b727 35470+ free_page((unsigned long)page);
1facf9fc 35471+
4f0767ce 35472+out:
1facf9fc 35473+ return err;
35474+}
35475+
35476+int au_xib_trunc(struct super_block *sb)
35477+{
35478+ int err;
35479+ ssize_t sz;
35480+ loff_t pos;
35481+ struct au_xino_lock_dir ldir;
35482+ struct au_sbinfo *sbinfo;
35483+ unsigned long *p;
35484+ struct file *file;
35485+
dece6358
AM
35486+ SiMustWriteLock(sb);
35487+
1facf9fc 35488+ err = 0;
35489+ sbinfo = au_sbi(sb);
35490+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
35491+ goto out;
35492+
35493+ file = sbinfo->si_xib;
c06a8ce3 35494+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 35495+ goto out;
35496+
35497+ au_xino_lock_dir(sb, file, &ldir);
35498+ /* mnt_want_write() is unnecessary here */
35499+ file = au_xino_create2(sbinfo->si_xib, NULL);
35500+ au_xino_unlock_dir(&ldir);
35501+ err = PTR_ERR(file);
35502+ if (IS_ERR(file))
35503+ goto out;
35504+ fput(sbinfo->si_xib);
35505+ sbinfo->si_xib = file;
35506+
35507+ p = sbinfo->si_xib_buf;
35508+ memset(p, 0, PAGE_SIZE);
35509+ pos = 0;
35510+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
35511+ if (unlikely(sz != PAGE_SIZE)) {
35512+ err = sz;
35513+ AuIOErr("err %d\n", err);
35514+ if (sz >= 0)
35515+ err = -EIO;
35516+ goto out;
35517+ }
35518+
35519+ mutex_lock(&sbinfo->si_xib_mtx);
35520+ /* mnt_want_write() is unnecessary here */
35521+ err = xib_restore(sb);
35522+ mutex_unlock(&sbinfo->si_xib_mtx);
35523+
35524+out:
35525+ return err;
35526+}
35527+
35528+/* ---------------------------------------------------------------------- */
35529+
35530+/*
35531+ * xino mount option handlers
35532+ */
1facf9fc 35533+
35534+/* xino bitmap */
35535+static void xino_clear_xib(struct super_block *sb)
35536+{
35537+ struct au_sbinfo *sbinfo;
35538+
dece6358
AM
35539+ SiMustWriteLock(sb);
35540+
1facf9fc 35541+ sbinfo = au_sbi(sb);
35542+ sbinfo->si_xread = NULL;
35543+ sbinfo->si_xwrite = NULL;
35544+ if (sbinfo->si_xib)
35545+ fput(sbinfo->si_xib);
35546+ sbinfo->si_xib = NULL;
f0c0a007 35547+ if (sbinfo->si_xib_buf)
1c60b727 35548+ free_page((unsigned long)sbinfo->si_xib_buf);
1facf9fc 35549+ sbinfo->si_xib_buf = NULL;
35550+}
35551+
35552+static int au_xino_set_xib(struct super_block *sb, struct file *base)
35553+{
35554+ int err;
35555+ loff_t pos;
35556+ struct au_sbinfo *sbinfo;
35557+ struct file *file;
35558+
dece6358
AM
35559+ SiMustWriteLock(sb);
35560+
1facf9fc 35561+ sbinfo = au_sbi(sb);
35562+ file = au_xino_create2(base, sbinfo->si_xib);
35563+ err = PTR_ERR(file);
35564+ if (IS_ERR(file))
35565+ goto out;
35566+ if (sbinfo->si_xib)
35567+ fput(sbinfo->si_xib);
35568+ sbinfo->si_xib = file;
5527c038
JR
35569+ sbinfo->si_xread = vfs_readf(file);
35570+ sbinfo->si_xwrite = vfs_writef(file);
1facf9fc 35571+
35572+ err = -ENOMEM;
35573+ if (!sbinfo->si_xib_buf)
35574+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
35575+ if (unlikely(!sbinfo->si_xib_buf))
35576+ goto out_unset;
35577+
35578+ sbinfo->si_xib_last_pindex = 0;
35579+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 35580+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 35581+ pos = 0;
35582+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
35583+ PAGE_SIZE, &pos);
35584+ if (unlikely(err != PAGE_SIZE))
35585+ goto out_free;
35586+ }
35587+ err = 0;
35588+ goto out; /* success */
35589+
4f0767ce 35590+out_free:
f0c0a007 35591+ if (sbinfo->si_xib_buf)
1c60b727 35592+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
35593+ sbinfo->si_xib_buf = NULL;
35594+ if (err >= 0)
35595+ err = -EIO;
4f0767ce 35596+out_unset:
b752ccd1
AM
35597+ fput(sbinfo->si_xib);
35598+ sbinfo->si_xib = NULL;
35599+ sbinfo->si_xread = NULL;
35600+ sbinfo->si_xwrite = NULL;
4f0767ce 35601+out:
b752ccd1 35602+ return err;
1facf9fc 35603+}
35604+
b752ccd1
AM
35605+/* xino for each branch */
35606+static void xino_clear_br(struct super_block *sb)
35607+{
5afbbe0d 35608+ aufs_bindex_t bindex, bbot;
b752ccd1 35609+ struct au_branch *br;
1facf9fc 35610+
5afbbe0d
AM
35611+ bbot = au_sbbot(sb);
35612+ for (bindex = 0; bindex <= bbot; bindex++) {
b752ccd1
AM
35613+ br = au_sbr(sb, bindex);
35614+ if (!br || !br->br_xino.xi_file)
35615+ continue;
35616+
35617+ fput(br->br_xino.xi_file);
35618+ br->br_xino.xi_file = NULL;
35619+ }
35620+}
35621+
35622+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 35623+{
35624+ int err;
b752ccd1 35625+ ino_t ino;
5afbbe0d 35626+ aufs_bindex_t bindex, bbot, bshared;
b752ccd1
AM
35627+ struct {
35628+ struct file *old, *new;
35629+ } *fpair, *p;
35630+ struct au_branch *br;
35631+ struct inode *inode;
5527c038 35632+ vfs_writef_t writef;
1facf9fc 35633+
b752ccd1
AM
35634+ SiMustWriteLock(sb);
35635+
35636+ err = -ENOMEM;
5afbbe0d
AM
35637+ bbot = au_sbbot(sb);
35638+ fpair = kcalloc(bbot + 1, sizeof(*fpair), GFP_NOFS);
b752ccd1 35639+ if (unlikely(!fpair))
1facf9fc 35640+ goto out;
35641+
5527c038 35642+ inode = d_inode(sb->s_root);
b752ccd1
AM
35643+ ino = AUFS_ROOT_INO;
35644+ writef = au_sbi(sb)->si_xwrite;
5afbbe0d 35645+ for (bindex = 0, p = fpair; bindex <= bbot; bindex++, p++) {
b752ccd1
AM
35646+ bshared = is_sb_shared(sb, bindex, bindex - 1);
35647+ if (bshared >= 0) {
35648+ /* shared xino */
35649+ *p = fpair[bshared];
35650+ get_file(p->new);
35651+ }
35652+
35653+ if (!p->new) {
35654+ /* new xino */
5afbbe0d 35655+ br = au_sbr(sb, bindex);
b752ccd1
AM
35656+ p->old = br->br_xino.xi_file;
35657+ p->new = au_xino_create2(base, br->br_xino.xi_file);
35658+ err = PTR_ERR(p->new);
35659+ if (IS_ERR(p->new)) {
35660+ p->new = NULL;
35661+ goto out_pair;
35662+ }
35663+ }
35664+
35665+ err = au_xino_do_write(writef, p->new,
35666+ au_h_iptr(inode, bindex)->i_ino, ino);
35667+ if (unlikely(err))
35668+ goto out_pair;
35669+ }
35670+
5afbbe0d 35671+ for (bindex = 0, p = fpair; bindex <= bbot; bindex++, p++) {
b752ccd1
AM
35672+ br = au_sbr(sb, bindex);
35673+ if (br->br_xino.xi_file)
35674+ fput(br->br_xino.xi_file);
35675+ get_file(p->new);
35676+ br->br_xino.xi_file = p->new;
35677+ }
1facf9fc 35678+
4f0767ce 35679+out_pair:
5afbbe0d 35680+ for (bindex = 0, p = fpair; bindex <= bbot; bindex++, p++)
b752ccd1
AM
35681+ if (p->new)
35682+ fput(p->new);
35683+ else
35684+ break;
1c60b727 35685+ kfree(fpair);
4f0767ce 35686+out:
1facf9fc 35687+ return err;
35688+}
b752ccd1
AM
35689+
35690+void au_xino_clr(struct super_block *sb)
35691+{
35692+ struct au_sbinfo *sbinfo;
35693+
35694+ au_xigen_clr(sb);
35695+ xino_clear_xib(sb);
35696+ xino_clear_br(sb);
35697+ sbinfo = au_sbi(sb);
35698+ /* lvalue, do not call au_mntflags() */
35699+ au_opt_clr(sbinfo->si_mntflags, XINO);
35700+}
35701+
35702+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
35703+{
35704+ int err, skip;
35705+ struct dentry *parent, *cur_parent;
35706+ struct qstr *dname, *cur_name;
35707+ struct file *cur_xino;
35708+ struct inode *dir;
35709+ struct au_sbinfo *sbinfo;
35710+
35711+ SiMustWriteLock(sb);
35712+
35713+ err = 0;
35714+ sbinfo = au_sbi(sb);
2000de60 35715+ parent = dget_parent(xino->file->f_path.dentry);
b752ccd1
AM
35716+ if (remount) {
35717+ skip = 0;
2000de60 35718+ dname = &xino->file->f_path.dentry->d_name;
b752ccd1
AM
35719+ cur_xino = sbinfo->si_xib;
35720+ if (cur_xino) {
2000de60
JR
35721+ cur_parent = dget_parent(cur_xino->f_path.dentry);
35722+ cur_name = &cur_xino->f_path.dentry->d_name;
b752ccd1 35723+ skip = (cur_parent == parent
38d290e6 35724+ && au_qstreq(dname, cur_name));
b752ccd1
AM
35725+ dput(cur_parent);
35726+ }
35727+ if (skip)
35728+ goto out;
35729+ }
35730+
35731+ au_opt_set(sbinfo->si_mntflags, XINO);
5527c038 35732+ dir = d_inode(parent);
febd17d6 35733+ inode_lock_nested(dir, AuLsc_I_PARENT);
b752ccd1
AM
35734+ /* mnt_want_write() is unnecessary here */
35735+ err = au_xino_set_xib(sb, xino->file);
35736+ if (!err)
35737+ err = au_xigen_set(sb, xino->file);
35738+ if (!err)
35739+ err = au_xino_set_br(sb, xino->file);
febd17d6 35740+ inode_unlock(dir);
b752ccd1
AM
35741+ if (!err)
35742+ goto out; /* success */
35743+
35744+ /* reset all */
35745+ AuIOErr("failed creating xino(%d).\n", err);
c1595e42
JR
35746+ au_xigen_clr(sb);
35747+ xino_clear_xib(sb);
b752ccd1 35748+
4f0767ce 35749+out:
b752ccd1
AM
35750+ dput(parent);
35751+ return err;
35752+}
35753+
35754+/* ---------------------------------------------------------------------- */
35755+
35756+/*
35757+ * create a xinofile at the default place/path.
35758+ */
35759+struct file *au_xino_def(struct super_block *sb)
35760+{
35761+ struct file *file;
35762+ char *page, *p;
35763+ struct au_branch *br;
35764+ struct super_block *h_sb;
35765+ struct path path;
5afbbe0d 35766+ aufs_bindex_t bbot, bindex, bwr;
b752ccd1
AM
35767+
35768+ br = NULL;
5afbbe0d 35769+ bbot = au_sbbot(sb);
b752ccd1 35770+ bwr = -1;
5afbbe0d 35771+ for (bindex = 0; bindex <= bbot; bindex++) {
b752ccd1
AM
35772+ br = au_sbr(sb, bindex);
35773+ if (au_br_writable(br->br_perm)
86dc4139 35774+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
35775+ bwr = bindex;
35776+ break;
35777+ }
35778+ }
35779+
7f207e10
AM
35780+ if (bwr >= 0) {
35781+ file = ERR_PTR(-ENOMEM);
537831f9 35782+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
35783+ if (unlikely(!page))
35784+ goto out;
86dc4139 35785+ path.mnt = au_br_mnt(br);
7f207e10
AM
35786+ path.dentry = au_h_dptr(sb->s_root, bwr);
35787+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
35788+ file = (void *)p;
35789+ if (!IS_ERR(p)) {
35790+ strcat(p, "/" AUFS_XINO_FNAME);
35791+ AuDbg("%s\n", p);
35792+ file = au_xino_create(sb, p, /*silent*/0);
35793+ if (!IS_ERR(file))
35794+ au_xino_brid_set(sb, br->br_id);
35795+ }
1c60b727 35796+ free_page((unsigned long)page);
7f207e10
AM
35797+ } else {
35798+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
35799+ if (IS_ERR(file))
35800+ goto out;
2000de60 35801+ h_sb = file->f_path.dentry->d_sb;
7f207e10
AM
35802+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
35803+ pr_err("xino doesn't support %s(%s)\n",
35804+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
35805+ fput(file);
35806+ file = ERR_PTR(-EINVAL);
35807+ }
35808+ if (!IS_ERR(file))
35809+ au_xino_brid_set(sb, -1);
35810+ }
0c5527e5 35811+
7f207e10
AM
35812+out:
35813+ return file;
35814+}
35815+
35816+/* ---------------------------------------------------------------------- */
35817+
35818+int au_xino_path(struct seq_file *seq, struct file *file)
35819+{
35820+ int err;
35821+
35822+ err = au_seq_path(seq, &file->f_path);
79b8bda9 35823+ if (unlikely(err))
7f207e10
AM
35824+ goto out;
35825+
7f207e10
AM
35826+#define Deleted "\\040(deleted)"
35827+ seq->count -= sizeof(Deleted) - 1;
35828+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
35829+ sizeof(Deleted) - 1));
35830+#undef Deleted
35831+
35832+out:
35833+ return err;
35834+}
521ced18
JR
35835+
35836+/* ---------------------------------------------------------------------- */
35837+
35838+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex,
35839+ ino_t h_ino, int idx)
35840+{
35841+ struct au_xino_file *xino;
35842+
35843+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
35844+ xino = &au_sbr(sb, bindex)->br_xino;
35845+ AuDebugOn(idx < 0 || xino->xi_nondir.total <= idx);
35846+
35847+ spin_lock(&xino->xi_nondir.spin);
35848+ AuDebugOn(xino->xi_nondir.array[idx] != h_ino);
35849+ xino->xi_nondir.array[idx] = 0;
35850+ spin_unlock(&xino->xi_nondir.spin);
35851+ wake_up_all(&xino->xi_nondir.wqh);
35852+}
35853+
35854+static int au_xinondir_find(struct au_xino_file *xino, ino_t h_ino)
35855+{
35856+ int found, total, i;
35857+
35858+ found = -1;
35859+ total = xino->xi_nondir.total;
35860+ for (i = 0; i < total; i++) {
35861+ if (xino->xi_nondir.array[i] != h_ino)
35862+ continue;
35863+ found = i;
35864+ break;
35865+ }
35866+
35867+ return found;
35868+}
35869+
35870+static int au_xinondir_expand(struct au_xino_file *xino)
35871+{
35872+ int err, sz;
35873+ ino_t *p;
35874+
35875+ BUILD_BUG_ON(KMALLOC_MAX_SIZE > INT_MAX);
35876+
35877+ err = -ENOMEM;
35878+ sz = xino->xi_nondir.total * sizeof(ino_t);
35879+ if (unlikely(sz > KMALLOC_MAX_SIZE / 2))
35880+ goto out;
35881+ p = au_kzrealloc(xino->xi_nondir.array, sz, sz << 1, GFP_ATOMIC,
35882+ /*may_shrink*/0);
35883+ if (p) {
35884+ xino->xi_nondir.array = p;
35885+ xino->xi_nondir.total <<= 1;
35886+ AuDbg("xi_nondir.total %d\n", xino->xi_nondir.total);
35887+ err = 0;
35888+ }
35889+
35890+out:
35891+ return err;
35892+}
35893+
35894+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
35895+ int *idx)
35896+{
35897+ int err, found, empty;
35898+ struct au_xino_file *xino;
35899+
35900+ err = 0;
35901+ *idx = -1;
35902+ if (!au_opt_test(au_mntflags(sb), XINO))
35903+ goto out; /* no xino */
35904+
35905+ xino = &au_sbr(sb, bindex)->br_xino;
35906+
35907+again:
35908+ spin_lock(&xino->xi_nondir.spin);
35909+ found = au_xinondir_find(xino, h_ino);
35910+ if (found == -1) {
35911+ empty = au_xinondir_find(xino, /*h_ino*/0);
35912+ if (empty == -1) {
35913+ empty = xino->xi_nondir.total;
35914+ err = au_xinondir_expand(xino);
35915+ if (unlikely(err))
35916+ goto out_unlock;
35917+ }
35918+ xino->xi_nondir.array[empty] = h_ino;
35919+ *idx = empty;
35920+ } else {
35921+ spin_unlock(&xino->xi_nondir.spin);
35922+ wait_event(xino->xi_nondir.wqh,
35923+ xino->xi_nondir.array[found] != h_ino);
35924+ goto again;
35925+ }
35926+
35927+out_unlock:
35928+ spin_unlock(&xino->xi_nondir.spin);
35929+out:
35930+ return err;
35931+}
537831f9
AM
35932diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
35933--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
3c1bdaff 35934+++ linux/include/uapi/linux/aufs_type.h 2017-09-05 10:42:11.058755349 +0200
c1595e42 35935@@ -0,0 +1,419 @@
7f207e10 35936+/*
a2654f78 35937+ * Copyright (C) 2005-2017 Junjiro R. Okajima
7f207e10
AM
35938+ *
35939+ * This program, aufs is free software; you can redistribute it and/or modify
35940+ * it under the terms of the GNU General Public License as published by
35941+ * the Free Software Foundation; either version 2 of the License, or
35942+ * (at your option) any later version.
35943+ *
35944+ * This program is distributed in the hope that it will be useful,
35945+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35946+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35947+ * GNU General Public License for more details.
35948+ *
35949+ * You should have received a copy of the GNU General Public License
523b37e3 35950+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
35951+ */
35952+
35953+#ifndef __AUFS_TYPE_H__
35954+#define __AUFS_TYPE_H__
35955+
f6c5ef8b
AM
35956+#define AUFS_NAME "aufs"
35957+
9dbd164d 35958+#ifdef __KERNEL__
f6c5ef8b
AM
35959+/*
35960+ * define it before including all other headers.
35961+ * sched.h may use pr_* macros before defining "current", so define the
35962+ * no-current version first, and re-define later.
35963+ */
35964+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
35965+#include <linux/sched.h>
35966+#undef pr_fmt
a2a7ad62
AM
35967+#define pr_fmt(fmt) \
35968+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
35969+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
35970+#else
35971+#include <stdint.h>
35972+#include <sys/types.h>
f6c5ef8b 35973+#endif /* __KERNEL__ */
7f207e10 35974+
f6c5ef8b
AM
35975+#include <linux/limits.h>
35976+
3c1bdaff 35977+#define AUFS_VERSION "4.x-rcN-20170904"
7f207e10
AM
35978+
35979+/* todo? move this to linux-2.6.19/include/magic.h */
35980+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
35981+
35982+/* ---------------------------------------------------------------------- */
35983+
35984+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 35985+typedef int8_t aufs_bindex_t;
7f207e10
AM
35986+#define AUFS_BRANCH_MAX 127
35987+#else
9dbd164d 35988+typedef int16_t aufs_bindex_t;
7f207e10
AM
35989+#ifdef CONFIG_AUFS_BRANCH_MAX_511
35990+#define AUFS_BRANCH_MAX 511
35991+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
35992+#define AUFS_BRANCH_MAX 1023
35993+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
35994+#define AUFS_BRANCH_MAX 32767
35995+#endif
35996+#endif
35997+
35998+#ifdef __KERNEL__
35999+#ifndef AUFS_BRANCH_MAX
36000+#error unknown CONFIG_AUFS_BRANCH_MAX value
36001+#endif
36002+#endif /* __KERNEL__ */
36003+
36004+/* ---------------------------------------------------------------------- */
36005+
7f207e10
AM
36006+#define AUFS_FSTYPE AUFS_NAME
36007+
36008+#define AUFS_ROOT_INO 2
36009+#define AUFS_FIRST_INO 11
36010+
36011+#define AUFS_WH_PFX ".wh."
36012+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
36013+#define AUFS_WH_TMP_LEN 4
86dc4139 36014+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
36015+#define AUFS_MAX_NAMELEN (NAME_MAX \
36016+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
36017+ - 1 /* dot */\
36018+ - AUFS_WH_TMP_LEN) /* hex */
36019+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
36020+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
36021+#define AUFS_XINO_DEF_SEC 30 /* seconds */
36022+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
36023+#define AUFS_DIRWH_DEF 3
36024+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 36025+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
36026+#define AUFS_RDBLK_DEF 512 /* bytes */
36027+#define AUFS_RDHASH_DEF 32
36028+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
36029+#define AUFS_MFS_DEF_SEC 30 /* seconds */
36030+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
076b876e 36031+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
86dc4139 36032+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
36033+
36034+/* pseudo-link maintenace under /proc */
36035+#define AUFS_PLINK_MAINT_NAME "plink_maint"
36036+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
36037+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
36038+
36039+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
36040+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
36041+
36042+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
36043+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
36044+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
36045+
36046+/* doubly whiteouted */
36047+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
36048+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
36049+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
36050+
1e00d052 36051+/* branch permissions and attributes */
7f207e10
AM
36052+#define AUFS_BRPERM_RW "rw"
36053+#define AUFS_BRPERM_RO "ro"
36054+#define AUFS_BRPERM_RR "rr"
076b876e
AM
36055+#define AUFS_BRATTR_COO_REG "coo_reg"
36056+#define AUFS_BRATTR_COO_ALL "coo_all"
36057+#define AUFS_BRATTR_FHSM "fhsm"
36058+#define AUFS_BRATTR_UNPIN "unpin"
c1595e42
JR
36059+#define AUFS_BRATTR_ICEX "icex"
36060+#define AUFS_BRATTR_ICEX_SEC "icexsec"
36061+#define AUFS_BRATTR_ICEX_SYS "icexsys"
36062+#define AUFS_BRATTR_ICEX_TR "icextr"
36063+#define AUFS_BRATTR_ICEX_USR "icexusr"
36064+#define AUFS_BRATTR_ICEX_OTH "icexoth"
1e00d052
AM
36065+#define AUFS_BRRATTR_WH "wh"
36066+#define AUFS_BRWATTR_NLWH "nolwh"
076b876e
AM
36067+#define AUFS_BRWATTR_MOO "moo"
36068+
36069+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
36070+#define AuBrPerm_RO (1 << 1) /* readonly */
36071+#define AuBrPerm_RR (1 << 2) /* natively readonly */
36072+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
36073+
36074+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
36075+#define AuBrAttr_COO_ALL (1 << 4)
36076+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
36077+
36078+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
36079+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
c1595e42
JR
36080+ branch. meaningless since
36081+ linux-3.18-rc1 */
36082+
36083+/* ignore error in copying XATTR */
36084+#define AuBrAttr_ICEX_SEC (1 << 7)
36085+#define AuBrAttr_ICEX_SYS (1 << 8)
36086+#define AuBrAttr_ICEX_TR (1 << 9)
36087+#define AuBrAttr_ICEX_USR (1 << 10)
36088+#define AuBrAttr_ICEX_OTH (1 << 11)
36089+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \
36090+ | AuBrAttr_ICEX_SYS \
36091+ | AuBrAttr_ICEX_TR \
36092+ | AuBrAttr_ICEX_USR \
36093+ | AuBrAttr_ICEX_OTH)
36094+
36095+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */
076b876e
AM
36096+#define AuBrRAttr_Mask AuBrRAttr_WH
36097+
c1595e42
JR
36098+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */
36099+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */
076b876e
AM
36100+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
36101+
36102+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
36103+
c1595e42 36104+/* #warning test userspace */
076b876e
AM
36105+#ifdef __KERNEL__
36106+#ifndef CONFIG_AUFS_FHSM
36107+#undef AuBrAttr_FHSM
36108+#define AuBrAttr_FHSM 0
36109+#endif
c1595e42
JR
36110+#ifndef CONFIG_AUFS_XATTR
36111+#undef AuBrAttr_ICEX
36112+#define AuBrAttr_ICEX 0
36113+#undef AuBrAttr_ICEX_SEC
36114+#define AuBrAttr_ICEX_SEC 0
36115+#undef AuBrAttr_ICEX_SYS
36116+#define AuBrAttr_ICEX_SYS 0
36117+#undef AuBrAttr_ICEX_TR
36118+#define AuBrAttr_ICEX_TR 0
36119+#undef AuBrAttr_ICEX_USR
36120+#define AuBrAttr_ICEX_USR 0
36121+#undef AuBrAttr_ICEX_OTH
36122+#define AuBrAttr_ICEX_OTH 0
36123+#endif
076b876e
AM
36124+#endif
36125+
36126+/* the longest combination */
c1595e42
JR
36127+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
36128+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
36129+ "+" AUFS_BRATTR_COO_REG \
36130+ "+" AUFS_BRATTR_FHSM \
36131+ "+" AUFS_BRATTR_UNPIN \
7e9cd9fe
AM
36132+ "+" AUFS_BRATTR_ICEX_SEC \
36133+ "+" AUFS_BRATTR_ICEX_SYS \
36134+ "+" AUFS_BRATTR_ICEX_USR \
36135+ "+" AUFS_BRATTR_ICEX_OTH \
076b876e
AM
36136+ "+" AUFS_BRWATTR_NLWH)
36137+
36138+typedef struct {
36139+ char a[AuBrPermStrSz];
36140+} au_br_perm_str_t;
36141+
36142+static inline int au_br_writable(int brperm)
36143+{
36144+ return brperm & AuBrPerm_RW;
36145+}
36146+
36147+static inline int au_br_whable(int brperm)
36148+{
36149+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
36150+}
36151+
36152+static inline int au_br_wh_linkable(int brperm)
36153+{
36154+ return !(brperm & AuBrWAttr_NoLinkWH);
36155+}
36156+
36157+static inline int au_br_cmoo(int brperm)
36158+{
36159+ return brperm & AuBrAttr_CMOO_Mask;
36160+}
36161+
36162+static inline int au_br_fhsm(int brperm)
36163+{
36164+ return brperm & AuBrAttr_FHSM;
36165+}
7f207e10
AM
36166+
36167+/* ---------------------------------------------------------------------- */
36168+
36169+/* ioctl */
36170+enum {
36171+ /* readdir in userspace */
36172+ AuCtl_RDU,
36173+ AuCtl_RDU_INO,
36174+
076b876e
AM
36175+ AuCtl_WBR_FD, /* pathconf wrapper */
36176+ AuCtl_IBUSY, /* busy inode */
36177+ AuCtl_MVDOWN, /* move-down */
36178+ AuCtl_BR, /* info about branches */
36179+ AuCtl_FHSM_FD /* connection for fhsm */
7f207e10
AM
36180+};
36181+
36182+/* borrowed from linux/include/linux/kernel.h */
36183+#ifndef ALIGN
36184+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
36185+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
36186+#endif
36187+
36188+/* borrowed from linux/include/linux/compiler-gcc3.h */
36189+#ifndef __aligned
36190+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
36191+#endif
36192+
36193+#ifdef __KERNEL__
36194+#ifndef __packed
7f207e10
AM
36195+#define __packed __attribute__((packed))
36196+#endif
53392da6 36197+#endif
7f207e10
AM
36198+
36199+struct au_rdu_cookie {
9dbd164d
AM
36200+ uint64_t h_pos;
36201+ int16_t bindex;
36202+ uint8_t flags;
36203+ uint8_t pad;
36204+ uint32_t generation;
7f207e10
AM
36205+} __aligned(8);
36206+
36207+struct au_rdu_ent {
9dbd164d
AM
36208+ uint64_t ino;
36209+ int16_t bindex;
36210+ uint8_t type;
36211+ uint8_t nlen;
36212+ uint8_t wh;
7f207e10
AM
36213+ char name[0];
36214+} __aligned(8);
36215+
36216+static inline int au_rdu_len(int nlen)
36217+{
36218+ /* include the terminating NULL */
36219+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 36220+ sizeof(uint64_t));
7f207e10
AM
36221+}
36222+
36223+union au_rdu_ent_ul {
36224+ struct au_rdu_ent __user *e;
9dbd164d 36225+ uint64_t ul;
7f207e10
AM
36226+};
36227+
36228+enum {
36229+ AufsCtlRduV_SZ,
36230+ AufsCtlRduV_End
36231+};
36232+
36233+struct aufs_rdu {
36234+ /* input */
36235+ union {
9dbd164d
AM
36236+ uint64_t sz; /* AuCtl_RDU */
36237+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
36238+ };
36239+ union au_rdu_ent_ul ent;
9dbd164d 36240+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
36241+
36242+ /* input/output */
9dbd164d 36243+ uint32_t blk;
7f207e10
AM
36244+
36245+ /* output */
36246+ union au_rdu_ent_ul tail;
36247+ /* number of entries which were added in a single call */
9dbd164d
AM
36248+ uint64_t rent;
36249+ uint8_t full;
36250+ uint8_t shwh;
7f207e10
AM
36251+
36252+ struct au_rdu_cookie cookie;
36253+} __aligned(8);
36254+
1e00d052
AM
36255+/* ---------------------------------------------------------------------- */
36256+
36257+struct aufs_wbr_fd {
9dbd164d
AM
36258+ uint32_t oflags;
36259+ int16_t brid;
1e00d052
AM
36260+} __aligned(8);
36261+
36262+/* ---------------------------------------------------------------------- */
36263+
027c5e7a 36264+struct aufs_ibusy {
9dbd164d
AM
36265+ uint64_t ino, h_ino;
36266+ int16_t bindex;
027c5e7a
AM
36267+} __aligned(8);
36268+
1e00d052
AM
36269+/* ---------------------------------------------------------------------- */
36270+
392086de
AM
36271+/* error code for move-down */
36272+/* the actual message strings are implemented in aufs-util.git */
36273+enum {
36274+ EAU_MVDOWN_OPAQUE = 1,
36275+ EAU_MVDOWN_WHITEOUT,
36276+ EAU_MVDOWN_UPPER,
36277+ EAU_MVDOWN_BOTTOM,
36278+ EAU_MVDOWN_NOUPPER,
36279+ EAU_MVDOWN_NOLOWERBR,
36280+ EAU_Last
36281+};
36282+
c2b27bf2 36283+/* flags for move-down */
392086de
AM
36284+#define AUFS_MVDOWN_DMSG 1
36285+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
36286+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
36287+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
36288+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
36289+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
36290+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
36291+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
36292+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
076b876e
AM
36293+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
36294+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
36295+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
36296+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
c2b27bf2 36297+
076b876e 36298+/* index for move-down */
392086de
AM
36299+enum {
36300+ AUFS_MVDOWN_UPPER,
36301+ AUFS_MVDOWN_LOWER,
36302+ AUFS_MVDOWN_NARRAY
36303+};
36304+
076b876e
AM
36305+/*
36306+ * additional info of move-down
36307+ * number of free blocks and inodes.
36308+ * subset of struct kstatfs, but smaller and always 64bit.
36309+ */
36310+struct aufs_stfs {
36311+ uint64_t f_blocks;
36312+ uint64_t f_bavail;
36313+ uint64_t f_files;
36314+ uint64_t f_ffree;
36315+};
36316+
36317+struct aufs_stbr {
36318+ int16_t brid; /* optional input */
36319+ int16_t bindex; /* output */
36320+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
36321+} __aligned(8);
36322+
c2b27bf2 36323+struct aufs_mvdown {
076b876e
AM
36324+ uint32_t flags; /* input/output */
36325+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
36326+ int8_t au_errno; /* output */
36327+} __aligned(8);
36328+
36329+/* ---------------------------------------------------------------------- */
36330+
36331+union aufs_brinfo {
36332+ /* PATH_MAX may differ between kernel-space and user-space */
36333+ char _spacer[4096];
392086de 36334+ struct {
076b876e
AM
36335+ int16_t id;
36336+ int perm;
36337+ char path[0];
36338+ };
c2b27bf2
AM
36339+} __aligned(8);
36340+
36341+/* ---------------------------------------------------------------------- */
36342+
7f207e10
AM
36343+#define AuCtlType 'A'
36344+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
36345+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
36346+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
36347+ struct aufs_wbr_fd)
027c5e7a 36348+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
36349+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
36350+ struct aufs_mvdown)
076b876e
AM
36351+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
36352+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
7f207e10
AM
36353+
36354+#endif /* __AUFS_TYPE_H__ */
ffa93bbd 36355aufs4.x-rcN loopback patch
5527c038
JR
36356
36357diff --git a/drivers/block/loop.c b/drivers/block/loop.c
3c1bdaff 36358index 10707c3..af32e47 100644
5527c038
JR
36359--- a/drivers/block/loop.c
36360+++ b/drivers/block/loop.c
ffa93bbd 36361@@ -547,7 +547,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
5527c038
JR
36362 }
36363
36364 struct switch_request {
36365- struct file *file;
36366+ struct file *file, *virt_file;
36367 struct completion wait;
36368 };
36369
ffa93bbd 36370@@ -573,6 +573,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
5527c038
JR
36371 mapping = file->f_mapping;
36372 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
36373 lo->lo_backing_file = file;
36374+ lo->lo_backing_virt_file = p->virt_file;
36375 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
36376 mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
36377 lo->old_gfp_mask = mapping_gfp_mask(mapping);
ffa93bbd 36378@@ -585,11 +586,13 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
5527c038
JR
36379 * First it needs to flush existing IO, it does this by sending a magic
36380 * BIO down the pipe. The completion of this BIO does the actual switch.
36381 */
36382-static int loop_switch(struct loop_device *lo, struct file *file)
36383+static int loop_switch(struct loop_device *lo, struct file *file,
36384+ struct file *virt_file)
36385 {
36386 struct switch_request w;
36387
36388 w.file = file;
36389+ w.virt_file = virt_file;
36390
36391 /* freeze queue and wait for completion of scheduled requests */
36392 blk_mq_freeze_queue(lo->lo_queue);
3c1bdaff
AM
36393@@ -611,7 +614,16 @@ static int loop_flush(struct loop_device *lo)
36394 /* loop not yet configured, no running thread, nothing to flush */
36395 if (lo->lo_state != Lo_bound)
36396 return 0;
36397- return loop_switch(lo, NULL);
36398+ return loop_switch(lo, NULL, NULL);
36399+}
36400+
5527c038
JR
36401+static struct file *loop_real_file(struct file *file)
36402+{
36403+ struct file *f = NULL;
36404+
36405+ if (file->f_path.dentry->d_sb->s_op->real_loop)
36406+ f = file->f_path.dentry->d_sb->s_op->real_loop(file);
36407+ return f;
3c1bdaff
AM
36408 }
36409
c2c0f25c 36410 static void loop_reread_partitions(struct loop_device *lo,
ffa93bbd 36411@@ -648,6 +660,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
36412 unsigned int arg)
36413 {
36414 struct file *file, *old_file;
36415+ struct file *f, *virt_file = NULL, *old_virt_file;
36416 struct inode *inode;
36417 int error;
36418
ffa93bbd 36419@@ -664,9 +677,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
36420 file = fget(arg);
36421 if (!file)
36422 goto out;
36423+ f = loop_real_file(file);
36424+ if (f) {
36425+ virt_file = file;
36426+ file = f;
36427+ get_file(file);
36428+ }
36429
36430 inode = file->f_mapping->host;
36431 old_file = lo->lo_backing_file;
36432+ old_virt_file = lo->lo_backing_virt_file;
36433
36434 error = -EINVAL;
36435
ffa93bbd 36436@@ -678,17 +698,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
36437 goto out_putf;
36438
36439 /* and ... switch */
36440- error = loop_switch(lo, file);
36441+ error = loop_switch(lo, file, virt_file);
36442 if (error)
36443 goto out_putf;
36444
36445 fput(old_file);
36446+ if (old_virt_file)
36447+ fput(old_virt_file);
36448 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
c2c0f25c 36449 loop_reread_partitions(lo, bdev);
5527c038
JR
36450 return 0;
36451
36452 out_putf:
36453 fput(file);
36454+ if (virt_file)
36455+ fput(virt_file);
36456 out:
36457 return error;
36458 }
3c1bdaff 36459@@ -882,7 +906,7 @@ static int loop_prepare_queue(struct loop_device *lo)
5527c038
JR
36460 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
36461 struct block_device *bdev, unsigned int arg)
36462 {
36463- struct file *file, *f;
36464+ struct file *file, *f, *virt_file = NULL;
36465 struct inode *inode;
36466 struct address_space *mapping;
36467 unsigned lo_blocksize;
3c1bdaff 36468@@ -897,6 +921,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
36469 file = fget(arg);
36470 if (!file)
36471 goto out;
36472+ f = loop_real_file(file);
36473+ if (f) {
36474+ virt_file = file;
36475+ file = f;
36476+ get_file(file);
36477+ }
36478
36479 error = -EBUSY;
36480 if (lo->lo_state != Lo_unbound)
3c1bdaff 36481@@ -949,6 +979,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
36482 lo->lo_device = bdev;
36483 lo->lo_flags = lo_flags;
36484 lo->lo_backing_file = file;
36485+ lo->lo_backing_virt_file = virt_file;
36486 lo->transfer = NULL;
36487 lo->ioctl = NULL;
36488 lo->lo_sizelimit = 0;
3c1bdaff 36489@@ -981,6 +1012,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
36490
36491 out_putf:
36492 fput(file);
36493+ if (virt_file)
36494+ fput(virt_file);
36495 out:
36496 /* This is safe: open() is still holding a reference. */
36497 module_put(THIS_MODULE);
3c1bdaff 36498@@ -1027,6 +1060,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
5527c038
JR
36499 static int loop_clr_fd(struct loop_device *lo)
36500 {
36501 struct file *filp = lo->lo_backing_file;
36502+ struct file *virt_filp = lo->lo_backing_virt_file;
36503 gfp_t gfp = lo->old_gfp_mask;
36504 struct block_device *bdev = lo->lo_device;
36505
3c1bdaff 36506@@ -1058,6 +1092,7 @@ static int loop_clr_fd(struct loop_device *lo)
5527c038
JR
36507 spin_lock_irq(&lo->lo_lock);
36508 lo->lo_state = Lo_rundown;
36509 lo->lo_backing_file = NULL;
36510+ lo->lo_backing_virt_file = NULL;
36511 spin_unlock_irq(&lo->lo_lock);
36512
36513 loop_release_xfer(lo);
3c1bdaff 36514@@ -1102,6 +1137,8 @@ static int loop_clr_fd(struct loop_device *lo)
5527c038
JR
36515 * bd_mutex which is usually taken before lo_ctl_mutex.
36516 */
36517 fput(filp);
36518+ if (virt_filp)
36519+ fput(virt_filp);
36520 return 0;
36521 }
36522
36523diff --git a/drivers/block/loop.h b/drivers/block/loop.h
ffa93bbd 36524index fecd3f9..6b3a7c9 100644
5527c038
JR
36525--- a/drivers/block/loop.h
36526+++ b/drivers/block/loop.h
36527@@ -46,7 +46,7 @@ struct loop_device {
36528 int (*ioctl)(struct loop_device *, int cmd,
36529 unsigned long arg);
36530
36531- struct file * lo_backing_file;
36532+ struct file * lo_backing_file, *lo_backing_virt_file;
36533 struct block_device *lo_device;
36534 unsigned lo_blocksize;
36535 void *key_data;
36536diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
1c60b727 36537index 870717e..ea7fee0 100644
5527c038
JR
36538--- a/fs/aufs/f_op.c
36539+++ b/fs/aufs/f_op.c
1c60b727 36540@@ -357,7 +357,7 @@ static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
5527c038
JR
36541 if (IS_ERR(h_file))
36542 goto out;
36543
36544- if (au_test_loopback_kthread()) {
36545+ if (0 && au_test_loopback_kthread()) {
36546 au_warn_loopback(h_file->f_path.dentry->d_sb);
36547 if (file->f_mapping != h_file->f_mapping) {
36548 file->f_mapping = h_file->f_mapping;
36549diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
1c60b727 36550index e35f015..b37f1ae 100644
5527c038
JR
36551--- a/fs/aufs/loop.c
36552+++ b/fs/aufs/loop.c
e2f27e51 36553@@ -132,3 +132,19 @@ void au_loopback_fin(void)
79b8bda9 36554 symbol_put(loop_backing_file);
1c60b727 36555 kfree(au_warn_loopback_array);
5527c038
JR
36556 }
36557+
36558+/* ---------------------------------------------------------------------- */
36559+
36560+/* support the loopback block device insude aufs */
36561+
36562+struct file *aufs_real_loop(struct file *file)
36563+{
36564+ struct file *f;
36565+
36566+ BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
36567+ fi_read_lock(file);
36568+ f = au_hf_top(file);
36569+ fi_read_unlock(file);
36570+ AuDebugOn(!f);
36571+ return f;
36572+}
36573diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
a2654f78 36574index e2df495..36e5052 100644
5527c038
JR
36575--- a/fs/aufs/loop.h
36576+++ b/fs/aufs/loop.h
a2654f78 36577@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
5527c038
JR
36578
36579 int au_loopback_init(void);
36580 void au_loopback_fin(void);
36581+
36582+struct file *aufs_real_loop(struct file *file);
36583 #else
36584+AuStub(struct file *, loop_backing_file, return NULL)
36585+
36586 AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
36587 struct dentry *h_adding)
36588 AuStubInt0(au_test_loopback_kthread, void)
a2654f78 36589@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
5527c038
JR
36590
36591 AuStubInt0(au_loopback_init, void)
36592 AuStubVoid(au_loopback_fin, void)
36593+
36594+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
36595 #endif /* BLK_DEV_LOOP */
36596
36597 #endif /* __KERNEL__ */
36598diff --git a/fs/aufs/super.c b/fs/aufs/super.c
1c60b727 36599index 5455fb1..8b9df60 100644
5527c038
JR
36600--- a/fs/aufs/super.c
36601+++ b/fs/aufs/super.c
a2654f78 36602@@ -837,7 +837,10 @@ static const struct super_operations aufs_sop = {
5527c038
JR
36603 .statfs = aufs_statfs,
36604 .put_super = aufs_put_super,
36605 .sync_fs = aufs_sync_fs,
36606- .remount_fs = aufs_remount_fs
36607+ .remount_fs = aufs_remount_fs,
36608+#ifdef CONFIG_AUFS_BDEV_LOOP
36609+ .real_loop = aufs_real_loop
36610+#endif
36611 };
36612
36613 /* ---------------------------------------------------------------------- */
36614diff --git a/include/linux/fs.h b/include/linux/fs.h
3c1bdaff 36615index 9b21bb5..f7124fa 100644
5527c038
JR
36616--- a/include/linux/fs.h
36617+++ b/include/linux/fs.h
3c1bdaff 36618@@ -1814,6 +1814,10 @@ struct super_operations {
5527c038
JR
36619 struct shrink_control *);
36620 long (*free_cached_objects)(struct super_block *,
36621 struct shrink_control *);
36622+#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
36623+ /* and aufs */
36624+ struct file *(*real_loop)(struct file *);
36625+#endif
36626 };
36627
36628 /*
This page took 6.198949 seconds and 4 git commands to generate.