]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs4.patch
- disable fw userspace loader (obsolete option, no longer supported by udev, causes...
[packages/kernel.git] / kernel-aufs4.patch
CommitLineData
79b8bda9 1aufs4.3 kbuild patch
7f207e10
AM
2
3diff --git a/fs/Kconfig b/fs/Kconfig
79b8bda9 4index da3f32f..b9879fe 100644
7f207e10
AM
5--- a/fs/Kconfig
6+++ b/fs/Kconfig
79b8bda9 7@@ -215,6 +215,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
79b8bda9 16index f79cf40..7562a4d 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
79b8bda9 19@@ -125,3 +125,4 @@ obj-y += exofs/ # Multiple modules
7f207e10 20 obj-$(CONFIG_CEPH_FS) += ceph/
bf0370f2 21 obj-$(CONFIG_PSTORE) += pstore/
c06a8ce3 22 obj-$(CONFIG_EFIVAR_FS) += efivarfs/
86dc4139 23+obj-$(CONFIG_AUFS_FS) += aufs/
c06a8ce3 24diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
79b8bda9 25index f7b2db4..47098aed 100644
c06a8ce3
AM
26--- a/include/uapi/linux/Kbuild
27+++ b/include/uapi/linux/Kbuild
5527c038 28@@ -59,6 +59,7 @@ header-y += atmsvc.h
03673fb0
JR
29 header-y += atm_tcp.h
30 header-y += atm_zatm.h
c06a8ce3
AM
31 header-y += audit.h
32+header-y += aufs_type.h
c06a8ce3 33 header-y += auto_fs4.h
03673fb0 34 header-y += auto_fs.h
c06a8ce3 35 header-y += auxvec.h
79b8bda9 36aufs4.3 base patch
7f207e10 37
c1595e42 38diff --git a/MAINTAINERS b/MAINTAINERS
79b8bda9 39index 747c653..53ecc33 100644
c1595e42
JR
40--- a/MAINTAINERS
41+++ b/MAINTAINERS
79b8bda9 42@@ -1985,6 +1985,19 @@ F: include/linux/audit.h
c1595e42
JR
43 F: include/uapi/linux/audit.h
44 F: kernel/audit*
45
46+AUFS (advanced multi layered unification filesystem) FILESYSTEM
47+M: "J. R. Okajima" <hooanon05g@gmail.com>
48+L: linux-unionfs@vger.kernel.org
49+L: aufs-users@lists.sourceforge.net (members only)
50+W: http://aufs.sourceforge.net
5527c038 51+T: git://github.com/sfjro/aufs4-linux.git
c1595e42
JR
52+S: Supported
53+F: Documentation/filesystems/aufs/
54+F: Documentation/ABI/testing/debugfs-aufs
55+F: Documentation/ABI/testing/sysfs-aufs
56+F: fs/aufs/
57+F: include/uapi/linux/aufs_type.h
58+
59 AUXILIARY DISPLAY DRIVERS
60 M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
61 W: http://miguelojeda.es/auxdisplay.htm
392086de 62diff --git a/drivers/block/loop.c b/drivers/block/loop.c
79b8bda9 63index 674f800a..291ec9e 100644
392086de
AM
64--- a/drivers/block/loop.c
65+++ b/drivers/block/loop.c
c2c0f25c 66@@ -560,6 +560,24 @@ static inline int is_loop_device(struct file *file)
392086de
AM
67 return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
68 }
69
70+/*
71+ * for AUFS
72+ * no get/put for file.
73+ */
74+struct file *loop_backing_file(struct super_block *sb)
75+{
76+ struct file *ret;
77+ struct loop_device *l;
78+
79+ ret = NULL;
80+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
81+ l = sb->s_bdev->bd_disk->private_data;
82+ ret = l->lo_backing_file;
83+ }
84+ return ret;
85+}
86+EXPORT_SYMBOL(loop_backing_file);
87+
88 /* loop sysfs attributes */
89
90 static ssize_t loop_attr_show(struct device *dev, char *page,
c1595e42 91diff --git a/fs/dcache.c b/fs/dcache.c
79b8bda9 92index 5c33aeb..8aa7f26 100644
c1595e42
JR
93--- a/fs/dcache.c
94+++ b/fs/dcache.c
79b8bda9 95@@ -1167,7 +1167,7 @@ enum d_walk_ret {
c1595e42
JR
96 *
97 * The @enter() and @finish() callbacks are called with d_lock held.
98 */
99-static void d_walk(struct dentry *parent, void *data,
100+void d_walk(struct dentry *parent, void *data,
101 enum d_walk_ret (*enter)(void *, struct dentry *),
102 void (*finish)(void *))
103 {
5527c038
JR
104diff --git a/fs/read_write.c b/fs/read_write.c
105index 819ef3f..fd0414e 100644
106--- a/fs/read_write.c
107+++ b/fs/read_write.c
108@@ -494,6 +494,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
109 }
110 EXPORT_SYMBOL(__vfs_write);
111
112+vfs_readf_t vfs_readf(struct file *file)
113+{
114+ const struct file_operations *fop = file->f_op;
115+
116+ if (fop->read)
117+ return fop->read;
118+ if (fop->read_iter)
119+ return new_sync_read;
120+ return ERR_PTR(-ENOSYS);
121+}
122+
123+vfs_writef_t vfs_writef(struct file *file)
124+{
125+ const struct file_operations *fop = file->f_op;
126+
127+ if (fop->write)
128+ return fop->write;
129+ if (fop->write_iter)
130+ return new_sync_write;
131+ return ERR_PTR(-ENOSYS);
132+}
133+
134 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
135 {
136 mm_segment_t old_fs;
7f207e10 137diff --git a/fs/splice.c b/fs/splice.c
c2c0f25c 138index 5fc1e50..5f8385a 100644
7f207e10
AM
139--- a/fs/splice.c
140+++ b/fs/splice.c
c2c0f25c 141@@ -1102,8 +1102,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
142 /*
143 * Attempt to initiate a splice from pipe to file.
144 */
145-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
146- loff_t *ppos, size_t len, unsigned int flags)
147+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
148+ loff_t *ppos, size_t len, unsigned int flags)
149 {
150 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
151 loff_t *, size_t, unsigned int);
c2c0f25c 152@@ -1119,9 +1119,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
153 /*
154 * Attempt to initiate a splice from a file to a pipe.
155 */
156-static long do_splice_to(struct file *in, loff_t *ppos,
157- struct pipe_inode_info *pipe, size_t len,
158- unsigned int flags)
159+long do_splice_to(struct file *in, loff_t *ppos,
160+ struct pipe_inode_info *pipe, size_t len,
161+ unsigned int flags)
162 {
163 ssize_t (*splice_read)(struct file *, loff_t *,
164 struct pipe_inode_info *, size_t, unsigned int);
b912730e
AM
165diff --git a/include/linux/file.h b/include/linux/file.h
166index f87d308..9a290b3 100644
167--- a/include/linux/file.h
168+++ b/include/linux/file.h
169@@ -19,6 +19,7 @@ struct dentry;
170 struct path;
171 extern struct file *alloc_file(struct path *, fmode_t mode,
172 const struct file_operations *fop);
173+extern struct file *get_empty_filp(void);
174
175 static inline void fput_light(struct file *file, int fput_needed)
176 {
5527c038 177diff --git a/include/linux/fs.h b/include/linux/fs.h
79b8bda9 178index 72d8a84..fabd9d7a 100644
5527c038
JR
179--- a/include/linux/fs.h
180+++ b/include/linux/fs.h
79b8bda9 181@@ -1687,6 +1687,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
5527c038
JR
182 struct iovec *fast_pointer,
183 struct iovec **ret_pointer);
184
185+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *);
186+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t,
187+ loff_t *);
188+vfs_readf_t vfs_readf(struct file *file);
189+vfs_writef_t vfs_writef(struct file *file);
190+
191 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
192 extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
193 extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
1e00d052 194diff --git a/include/linux/splice.h b/include/linux/splice.h
076b876e 195index da2751d..2e0fca6 100644
1e00d052
AM
196--- a/include/linux/splice.h
197+++ b/include/linux/splice.h
076b876e 198@@ -83,4 +83,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
199 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
200
201 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
1e00d052
AM
202+
203+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
204+ loff_t *ppos, size_t len, unsigned int flags);
205+extern long do_splice_to(struct file *in, loff_t *ppos,
206+ struct pipe_inode_info *pipe, size_t len,
207+ unsigned int flags);
208 #endif
79b8bda9 209aufs4.3 mmap patch
fb47a38f
JR
210
211diff --git a/fs/buffer.c b/fs/buffer.c
79b8bda9 212index 82283ab..477e5f3 100644
fb47a38f
JR
213--- a/fs/buffer.c
214+++ b/fs/buffer.c
c2c0f25c 215@@ -2473,7 +2473,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
fb47a38f
JR
216 * Update file times before taking page lock. We may end up failing the
217 * fault so this update may be superfluous but who really cares...
218 */
219- file_update_time(vma->vm_file);
220+ vma_file_update_time(vma);
221
222 ret = __block_page_mkwrite(vma, vmf, get_block);
223 sb_end_pagefault(sb);
c1595e42 224diff --git a/fs/proc/base.c b/fs/proc/base.c
79b8bda9 225index b25eee4..c83d588 100644
c1595e42
JR
226--- a/fs/proc/base.c
227+++ b/fs/proc/base.c
79b8bda9 228@@ -1914,7 +1914,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
c1595e42
JR
229 down_read(&mm->mmap_sem);
230 vma = find_exact_vma(mm, vm_start, vm_end);
231 if (vma && vma->vm_file) {
232- *path = vma->vm_file->f_path;
233+ *path = vma_pr_or_file(vma)->f_path;
234 path_get(path);
235 rc = 0;
236 }
fb47a38f 237diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
c2c0f25c 238index f8595e8..cb8eda0 100644
fb47a38f
JR
239--- a/fs/proc/nommu.c
240+++ b/fs/proc/nommu.c
076b876e 241@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
fb47a38f
JR
242 file = region->vm_file;
243
244 if (file) {
245- struct inode *inode = file_inode(region->vm_file);
246+ struct inode *inode;
076b876e 247+
fb47a38f
JR
248+ file = vmr_pr_or_file(region);
249+ inode = file_inode(file);
250 dev = inode->i_sb->s_dev;
251 ino = inode->i_ino;
252 }
253diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
79b8bda9 254index e2d46ad..5e7e631 100644
fb47a38f
JR
255--- a/fs/proc/task_mmu.c
256+++ b/fs/proc/task_mmu.c
79b8bda9 257@@ -280,7 +280,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
fb47a38f
JR
258 const char *name = NULL;
259
260 if (file) {
261- struct inode *inode = file_inode(vma->vm_file);
262+ struct inode *inode;
076b876e 263+
fb47a38f
JR
264+ file = vma_pr_or_file(vma);
265+ inode = file_inode(file);
266 dev = inode->i_sb->s_dev;
267 ino = inode->i_ino;
268 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
79b8bda9 269@@ -1465,7 +1468,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
076b876e
AM
270 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
271 struct vm_area_struct *vma = v;
272 struct numa_maps *md = &numa_priv->md;
273- struct file *file = vma->vm_file;
274+ struct file *file = vma_pr_or_file(vma);
076b876e 275 struct mm_struct *mm = vma->vm_mm;
7e9cd9fe
AM
276 struct mm_walk walk = {
277 .hugetlb_entry = gather_hugetlb_stats,
fb47a38f 278diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
c2c0f25c 279index e0d64c9..7aa92db 100644
fb47a38f
JR
280--- a/fs/proc/task_nommu.c
281+++ b/fs/proc/task_nommu.c
c1595e42 282@@ -160,7 +160,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
fb47a38f
JR
283 file = vma->vm_file;
284
285 if (file) {
286- struct inode *inode = file_inode(vma->vm_file);
287+ struct inode *inode;
076b876e 288+
b912730e 289+ file = vma_pr_or_file(vma);
fb47a38f
JR
290+ inode = file_inode(file);
291 dev = inode->i_sb->s_dev;
292 ino = inode->i_ino;
293 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
294diff --git a/include/linux/mm.h b/include/linux/mm.h
79b8bda9 295index 80001de..9248b97 100644
fb47a38f
JR
296--- a/include/linux/mm.h
297+++ b/include/linux/mm.h
79b8bda9 298@@ -1211,6 +1211,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
fb47a38f
JR
299 }
300 #endif
301
076b876e
AM
302+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
303+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
304+ int);
305+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
306+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
fb47a38f 307+
fb47a38f
JR
308+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
309+ __LINE__)
310+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
311+ __LINE__)
312+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
313+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
b912730e
AM
314+
315+#ifndef CONFIG_MMU
076b876e
AM
316+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
317+extern void vmr_do_fput(struct vm_region *, const char[], int);
318+
319+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
320+ __LINE__)
321+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
b912730e 322+#endif /* !CONFIG_MMU */
fb47a38f
JR
323+
324 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
325 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
326 void *buf, int len, int write);
327diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
79b8bda9 328index 3d6baa7..750ca95 100644
fb47a38f
JR
329--- a/include/linux/mm_types.h
330+++ b/include/linux/mm_types.h
79b8bda9 331@@ -250,6 +250,7 @@ struct vm_region {
fb47a38f
JR
332 unsigned long vm_top; /* region allocated to here */
333 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
334 struct file *vm_file; /* the backing file or NULL */
335+ struct file *vm_prfile; /* the virtual backing file or NULL */
336
337 int vm_usage; /* region usage count (access under nommu_region_sem) */
338 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
79b8bda9 339@@ -324,6 +325,7 @@ struct vm_area_struct {
fb47a38f
JR
340 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
341 units, *not* PAGE_CACHE_SIZE */
342 struct file * vm_file; /* File we map to (can be NULL). */
343+ struct file *vm_prfile; /* shadow of vm_file */
344 void * vm_private_data; /* was vm_pte (shared mem) */
345
346 #ifndef CONFIG_MMU
347diff --git a/kernel/fork.c b/kernel/fork.c
79b8bda9 348index 2845623..71004bd 100644
fb47a38f
JR
349--- a/kernel/fork.c
350+++ b/kernel/fork.c
79b8bda9 351@@ -462,7 +462,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
fb47a38f
JR
352 struct inode *inode = file_inode(file);
353 struct address_space *mapping = file->f_mapping;
354
355- get_file(file);
356+ vma_get_file(tmp);
357 if (tmp->vm_flags & VM_DENYWRITE)
358 atomic_dec(&inode->i_writecount);
2000de60 359 i_mmap_lock_write(mapping);
076b876e 360diff --git a/mm/Makefile b/mm/Makefile
79b8bda9 361index 2ed4319..e3a53f5 100644
076b876e
AM
362--- a/mm/Makefile
363+++ b/mm/Makefile
7e9cd9fe 364@@ -21,7 +21,7 @@ obj-y := filemap.o mempool.o oom_kill.o \
076b876e 365 mm_init.o mmu_context.o percpu.o slab_common.o \
c1595e42 366 compaction.o vmacache.o \
076b876e 367 interval_tree.o list_lru.o workingset.o \
7e9cd9fe
AM
368- debug.o $(mmu-y)
369+ prfile.o debug.o $(mmu-y)
076b876e
AM
370
371 obj-y += init-mm.o
372
fb47a38f 373diff --git a/mm/filemap.c b/mm/filemap.c
79b8bda9 374index 327910c..7bbc372 100644
fb47a38f
JR
375--- a/mm/filemap.c
376+++ b/mm/filemap.c
c2c0f25c 377@@ -2089,7 +2089,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
fb47a38f
JR
378 int ret = VM_FAULT_LOCKED;
379
380 sb_start_pagefault(inode->i_sb);
381- file_update_time(vma->vm_file);
382+ vma_file_update_time(vma);
383 lock_page(page);
384 if (page->mapping != inode->i_mapping) {
385 unlock_page(page);
fb47a38f 386diff --git a/mm/memory.c b/mm/memory.c
79b8bda9 387index deb679c..df2ce3e 100644
fb47a38f
JR
388--- a/mm/memory.c
389+++ b/mm/memory.c
79b8bda9 390@@ -2035,7 +2035,7 @@ static inline int wp_page_reuse(struct mm_struct *mm,
fb47a38f 391 }
7e9cd9fe 392
b912730e
AM
393 if (!page_mkwrite)
394- file_update_time(vma->vm_file);
395+ vma_file_update_time(vma);
396 }
397
398 return VM_FAULT_WRITE;
fb47a38f 399diff --git a/mm/mmap.c b/mm/mmap.c
79b8bda9 400index 79bcc9f..da28c8a 100644
fb47a38f
JR
401--- a/mm/mmap.c
402+++ b/mm/mmap.c
79b8bda9 403@@ -275,7 +275,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
fb47a38f
JR
404 if (vma->vm_ops && vma->vm_ops->close)
405 vma->vm_ops->close(vma);
406 if (vma->vm_file)
407- fput(vma->vm_file);
408+ vma_fput(vma);
409 mpol_put(vma_policy(vma));
410 kmem_cache_free(vm_area_cachep, vma);
411 return next;
79b8bda9 412@@ -887,7 +887,7 @@ again: remove_next = 1 + (end > next->vm_end);
fb47a38f
JR
413 if (remove_next) {
414 if (file) {
415 uprobe_munmap(next, next->vm_start, next->vm_end);
416- fput(file);
417+ vma_fput(vma);
418 }
419 if (next->anon_vma)
420 anon_vma_merge(vma, next);
79b8bda9 421@@ -1683,8 +1683,8 @@ out:
35939ee7
JR
422 return addr;
423
fb47a38f 424 unmap_and_free_vma:
fb47a38f
JR
425+ vma_fput(vma);
426 vma->vm_file = NULL;
427- fput(file);
428
429 /* Undo any partial mapping done by a device driver. */
430 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
79b8bda9 431@@ -2485,7 +2485,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
432 goto out_free_mpol;
433
434 if (new->vm_file)
435- get_file(new->vm_file);
436+ vma_get_file(new);
437
438 if (new->vm_ops && new->vm_ops->open)
439 new->vm_ops->open(new);
79b8bda9 440@@ -2504,7 +2504,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
441 if (new->vm_ops && new->vm_ops->close)
442 new->vm_ops->close(new);
443 if (new->vm_file)
444- fput(new->vm_file);
445+ vma_fput(new);
446 unlink_anon_vmas(new);
447 out_free_mpol:
448 mpol_put(vma_policy(new));
79b8bda9 449@@ -2646,7 +2646,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
7e9cd9fe
AM
450 struct vm_area_struct *vma;
451 unsigned long populate = 0;
452 unsigned long ret = -EINVAL;
453- struct file *file;
454
455 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. "
456 "See Documentation/vm/remap_file_pages.txt.\n",
79b8bda9 457@@ -2690,10 +2689,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
7e9cd9fe
AM
458 munlock_vma_pages_range(vma, start, start + size);
459 }
460
461- file = get_file(vma->vm_file);
462+ vma_get_file(vma);
463 ret = do_mmap_pgoff(vma->vm_file, start, size,
464 prot, flags, pgoff, &populate);
465- fput(file);
466+ vma_fput(vma);
467 out:
468 up_write(&mm->mmap_sem);
469 if (populate)
79b8bda9
AM
470@@ -2963,7 +2962,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
471 if (anon_vma_clone(new_vma, vma))
472 goto out_free_mempol;
473 if (new_vma->vm_file)
474- get_file(new_vma->vm_file);
475+ vma_get_file(new_vma);
476 if (new_vma->vm_ops && new_vma->vm_ops->open)
477 new_vma->vm_ops->open(new_vma);
478 vma_link(mm, new_vma, prev, rb_link, rb_parent);
fb47a38f 479diff --git a/mm/nommu.c b/mm/nommu.c
79b8bda9 480index ab14a20..fffc566 100644
fb47a38f
JR
481--- a/mm/nommu.c
482+++ b/mm/nommu.c
c2c0f25c 483@@ -671,7 +671,7 @@ static void __put_nommu_region(struct vm_region *region)
fb47a38f
JR
484 up_write(&nommu_region_sem);
485
486 if (region->vm_file)
487- fput(region->vm_file);
488+ vmr_fput(region);
489
490 /* IO memory and memory shared directly out of the pagecache
491 * from ramfs/tmpfs mustn't be released here */
c2c0f25c 492@@ -829,7 +829,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
fb47a38f
JR
493 if (vma->vm_ops && vma->vm_ops->close)
494 vma->vm_ops->close(vma);
495 if (vma->vm_file)
496- fput(vma->vm_file);
497+ vma_fput(vma);
498 put_nommu_region(vma->vm_region);
499 kmem_cache_free(vm_area_cachep, vma);
500 }
79b8bda9 501@@ -1355,7 +1355,7 @@ unsigned long do_mmap(struct file *file,
fb47a38f
JR
502 goto error_just_free;
503 }
504 }
505- fput(region->vm_file);
506+ vmr_fput(region);
507 kmem_cache_free(vm_region_jar, region);
508 region = pregion;
509 result = start;
79b8bda9 510@@ -1430,10 +1430,10 @@ error_just_free:
fb47a38f
JR
511 up_write(&nommu_region_sem);
512 error:
513 if (region->vm_file)
514- fput(region->vm_file);
515+ vmr_fput(region);
516 kmem_cache_free(vm_region_jar, region);
517 if (vma->vm_file)
518- fput(vma->vm_file);
519+ vma_fput(vma);
520 kmem_cache_free(vm_area_cachep, vma);
fb47a38f 521 return ret;
c2c0f25c 522
076b876e
AM
523diff --git a/mm/prfile.c b/mm/prfile.c
524new file mode 100644
c2c0f25c 525index 0000000..b323b8a
076b876e
AM
526--- /dev/null
527+++ b/mm/prfile.c
528@@ -0,0 +1,86 @@
529+/*
530+ * Mainly for aufs which mmap(2) diffrent file and wants to print different path
531+ * in /proc/PID/maps.
532+ * Call these functions via macros defined in linux/mm.h.
533+ *
534+ * See Documentation/filesystems/aufs/design/06mmap.txt
535+ *
536+ * Copyright (c) 2014 Junjro R. Okajima
537+ * Copyright (c) 2014 Ian Campbell
538+ */
539+
540+#include <linux/mm.h>
541+#include <linux/file.h>
542+#include <linux/fs.h>
543+
544+/* #define PRFILE_TRACE */
545+static inline void prfile_trace(struct file *f, struct file *pr,
546+ const char func[], int line, const char func2[])
547+{
548+#ifdef PRFILE_TRACE
549+ if (pr)
c2c0f25c 550+ pr_info("%s:%d: %s, %s\n", func, line, func2,
7e9cd9fe 551+ f ? (char *)f->f_path.dentry->d_name.name : "(null)");
076b876e
AM
552+#endif
553+}
554+
076b876e
AM
555+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
556+ int line)
557+{
558+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
559+
560+ prfile_trace(f, pr, func, line, __func__);
561+ file_update_time(f);
562+ if (f && pr)
563+ file_update_time(pr);
564+}
565+
566+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
567+ int line)
568+{
569+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
570+
571+ prfile_trace(f, pr, func, line, __func__);
572+ return (f && pr) ? pr : f;
573+}
574+
575+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
576+{
577+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
578+
579+ prfile_trace(f, pr, func, line, __func__);
580+ get_file(f);
581+ if (f && pr)
582+ get_file(pr);
583+}
584+
585+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
586+{
587+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
588+
589+ prfile_trace(f, pr, func, line, __func__);
590+ fput(f);
591+ if (f && pr)
592+ fput(pr);
593+}
b912730e
AM
594+
595+#ifndef CONFIG_MMU
076b876e
AM
596+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
597+ int line)
598+{
599+ struct file *f = region->vm_file, *pr = region->vm_prfile;
600+
601+ prfile_trace(f, pr, func, line, __func__);
602+ return (f && pr) ? pr : f;
603+}
604+
605+void vmr_do_fput(struct vm_region *region, const char func[], int line)
606+{
607+ struct file *f = region->vm_file, *pr = region->vm_prfile;
608+
609+ prfile_trace(f, pr, func, line, __func__);
610+ fput(f);
611+ if (f && pr)
612+ fput(pr);
613+}
b912730e 614+#endif /* !CONFIG_MMU */
79b8bda9 615aufs4.3 standalone patch
7f207e10 616
c1595e42 617diff --git a/fs/dcache.c b/fs/dcache.c
79b8bda9 618index 8aa7f26..f997345 100644
c1595e42
JR
619--- a/fs/dcache.c
620+++ b/fs/dcache.c
79b8bda9 621@@ -1272,6 +1272,7 @@ rename_retry:
c1595e42
JR
622 seq = 1;
623 goto again;
624 }
625+EXPORT_SYMBOL(d_walk);
626
627 /*
628 * Search for at least 1 mount point in the dentry's subdirs.
79b8bda9
AM
629diff --git a/fs/exec.c b/fs/exec.c
630index b06623a..b9206c5 100644
631--- a/fs/exec.c
632+++ b/fs/exec.c
633@@ -103,6 +103,7 @@ bool path_noexec(const struct path *path)
634 return (path->mnt->mnt_flags & MNT_NOEXEC) ||
635 (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
636 }
637+EXPORT_SYMBOL(path_noexec);
638
639 #ifdef CONFIG_USELIB
640 /*
b912730e 641diff --git a/fs/file_table.c b/fs/file_table.c
79b8bda9 642index ad17e05..df66450 100644
b912730e
AM
643--- a/fs/file_table.c
644+++ b/fs/file_table.c
79b8bda9 645@@ -147,6 +147,7 @@ over:
b912730e
AM
646 }
647 return ERR_PTR(-ENFILE);
648 }
649+EXPORT_SYMBOL(get_empty_filp);
650
651 /**
652 * alloc_file - allocate and initialize a 'struct file'
79b8bda9 653@@ -308,6 +309,7 @@ void put_filp(struct file *file)
b912730e
AM
654 file_free(file);
655 }
656 }
657+EXPORT_SYMBOL(put_filp);
658
79b8bda9 659 void __init files_init(void)
b912730e 660 {
7f207e10 661diff --git a/fs/namespace.c b/fs/namespace.c
79b8bda9 662index 0570729..ec560d8 100644
7f207e10
AM
663--- a/fs/namespace.c
664+++ b/fs/namespace.c
7e9cd9fe 665@@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
666 mnt_dec_writers(real_mount(mnt));
667 preempt_enable();
668 }
669+EXPORT_SYMBOL_GPL(__mnt_drop_write);
670
671 /**
672 * mnt_drop_write - give up write access to a mount
79b8bda9 673@@ -1803,6 +1804,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
674 }
675 return 0;
676 }
677+EXPORT_SYMBOL(iterate_mounts);
678
7eafdf33 679 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
680 {
681diff --git a/fs/notify/group.c b/fs/notify/group.c
c1595e42 682index d16b62c..06ca6bc 100644
7f207e10
AM
683--- a/fs/notify/group.c
684+++ b/fs/notify/group.c
685@@ -22,6 +22,7 @@
686 #include <linux/srcu.h>
687 #include <linux/rculist.h>
688 #include <linux/wait.h>
689+#include <linux/module.h>
690
691 #include <linux/fsnotify_backend.h>
692 #include "fsnotify.h"
fb47a38f 693@@ -72,6 +73,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
1716fcea
AM
694 {
695 atomic_inc(&group->refcnt);
696 }
697+EXPORT_SYMBOL(fsnotify_get_group);
698
699 /*
700 * Drop a reference to a group. Free it if it's through.
fb47a38f 701@@ -81,6 +83,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
7f207e10 702 if (atomic_dec_and_test(&group->refcnt))
1716fcea 703 fsnotify_final_destroy_group(group);
7f207e10
AM
704 }
705+EXPORT_SYMBOL(fsnotify_put_group);
706
707 /*
708 * Create a new fsnotify_group and hold a reference for the group returned.
fb47a38f 709@@ -109,6 +112,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
710
711 return group;
712 }
713+EXPORT_SYMBOL(fsnotify_alloc_group);
1716fcea
AM
714
715 int fsnotify_fasync(int fd, struct file *file, int on)
716 {
7f207e10 717diff --git a/fs/notify/mark.c b/fs/notify/mark.c
79b8bda9 718index fc0df44..325b5c6 100644
7f207e10
AM
719--- a/fs/notify/mark.c
720+++ b/fs/notify/mark.c
392086de 721@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
7f207e10 722 mark->free_mark(mark);
1716fcea 723 }
7f207e10
AM
724 }
725+EXPORT_SYMBOL(fsnotify_put_mark);
726
2000de60
JR
727 /* Calculate mask of events for a list of marks */
728 u32 fsnotify_recalc_mask(struct hlist_head *head)
79b8bda9 729@@ -208,6 +209,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea 730 mutex_unlock(&group->mark_mutex);
79b8bda9 731 fsnotify_free_mark(mark);
7f207e10
AM
732 }
733+EXPORT_SYMBOL(fsnotify_destroy_mark);
734
79b8bda9
AM
735 void fsnotify_destroy_marks(struct hlist_head *head, spinlock_t *lock)
736 {
737@@ -392,6 +394,7 @@ err:
7f207e10
AM
738
739 return ret;
740 }
741+EXPORT_SYMBOL(fsnotify_add_mark);
742
1716fcea
AM
743 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
744 struct inode *inode, struct vfsmount *mnt, int allow_dups)
79b8bda9 745@@ -492,6 +495,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
7f207e10
AM
746 atomic_set(&mark->refcnt, 1);
747 mark->free_mark = free_mark;
748 }
749+EXPORT_SYMBOL(fsnotify_init_mark);
750
751 static int fsnotify_mark_destroy(void *ignored)
752 {
753diff --git a/fs/open.c b/fs/open.c
79b8bda9 754index b6f1e96..4ab0d4e 100644
7f207e10
AM
755--- a/fs/open.c
756+++ b/fs/open.c
c2c0f25c 757@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
7f207e10
AM
758 mutex_unlock(&dentry->d_inode->i_mutex);
759 return ret;
760 }
761+EXPORT_SYMBOL(do_truncate);
762
1716fcea 763 long vfs_truncate(struct path *path, loff_t length)
7f207e10 764 {
c2c0f25c 765@@ -678,6 +679,7 @@ int open_check_o_direct(struct file *f)
b912730e
AM
766 }
767 return 0;
768 }
769+EXPORT_SYMBOL(open_check_o_direct);
770
771 static int do_dentry_open(struct file *f,
c2c0f25c 772 struct inode *inode,
5527c038
JR
773diff --git a/fs/read_write.c b/fs/read_write.c
774index fd0414e..8ace6ec 100644
775--- a/fs/read_write.c
776+++ b/fs/read_write.c
777@@ -504,6 +504,7 @@ vfs_readf_t vfs_readf(struct file *file)
778 return new_sync_read;
779 return ERR_PTR(-ENOSYS);
780 }
781+EXPORT_SYMBOL(vfs_readf);
782
783 vfs_writef_t vfs_writef(struct file *file)
784 {
785@@ -515,6 +516,7 @@ vfs_writef_t vfs_writef(struct file *file)
786 return new_sync_write;
787 return ERR_PTR(-ENOSYS);
788 }
789+EXPORT_SYMBOL(vfs_writef);
790
791 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
792 {
7f207e10 793diff --git a/fs/splice.c b/fs/splice.c
c2c0f25c 794index 5f8385a..f76067e 100644
7f207e10
AM
795--- a/fs/splice.c
796+++ b/fs/splice.c
c2c0f25c 797@@ -1115,6 +1115,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
392086de
AM
798
799 return splice_write(pipe, out, ppos, len, flags);
7f207e10
AM
800 }
801+EXPORT_SYMBOL(do_splice_from);
802
803 /*
804 * Attempt to initiate a splice from a file to a pipe.
c2c0f25c 805@@ -1141,6 +1142,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
806
807 return splice_read(in, ppos, pipe, len, flags);
808 }
809+EXPORT_SYMBOL(do_splice_to);
810
811 /**
812 * splice_direct_to_actor - splices data directly between two non-pipes
c1595e42 813diff --git a/fs/xattr.c b/fs/xattr.c
c2c0f25c 814index 072fee1..a7677af 100644
c1595e42
JR
815--- a/fs/xattr.c
816+++ b/fs/xattr.c
817@@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
818 *xattr_value = value;
819 return error;
820 }
821+EXPORT_SYMBOL(vfs_getxattr_alloc);
822
823 /* Compare an extended attribute value with the given value */
824 int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
7f207e10 825diff --git a/security/commoncap.c b/security/commoncap.c
79b8bda9 826index 1832cf7..987ff5f 100644
7f207e10
AM
827--- a/security/commoncap.c
828+++ b/security/commoncap.c
79b8bda9 829@@ -1053,12 +1053,14 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 830 }
7f207e10
AM
831 return ret;
832 }
0c3ec466
AM
833+EXPORT_SYMBOL(cap_mmap_addr);
834
835 int cap_mmap_file(struct file *file, unsigned long reqprot,
836 unsigned long prot, unsigned long flags)
837 {
838 return 0;
839 }
840+EXPORT_SYMBOL(cap_mmap_file);
c2c0f25c
AM
841
842 #ifdef CONFIG_SECURITY
843
7f207e10 844diff --git a/security/device_cgroup.c b/security/device_cgroup.c
79b8bda9 845index 03c1652..b00aa76 100644
7f207e10
AM
846--- a/security/device_cgroup.c
847+++ b/security/device_cgroup.c
f6c5ef8b
AM
848@@ -7,6 +7,7 @@
849 #include <linux/device_cgroup.h>
850 #include <linux/cgroup.h>
851 #include <linux/ctype.h>
852+#include <linux/export.h>
853 #include <linux/list.h>
854 #include <linux/uaccess.h>
855 #include <linux/seq_file.h>
076b876e 856@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
857 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
858 access);
7f207e10 859 }
2cbb1c4b 860+EXPORT_SYMBOL(__devcgroup_inode_permission);
7f207e10
AM
861
862 int devcgroup_inode_mknod(int mode, dev_t dev)
863 {
864diff --git a/security/security.c b/security/security.c
79b8bda9 865index 46f405c..54488b0 100644
7f207e10
AM
866--- a/security/security.c
867+++ b/security/security.c
79b8bda9 868@@ -433,6 +433,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
7f207e10 869 return 0;
c2c0f25c 870 return call_int_hook(path_rmdir, 0, dir, dentry);
7f207e10
AM
871 }
872+EXPORT_SYMBOL(security_path_rmdir);
873
874 int security_path_unlink(struct path *dir, struct dentry *dentry)
875 {
79b8bda9 876@@ -449,6 +450,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
7f207e10 877 return 0;
c2c0f25c 878 return call_int_hook(path_symlink, 0, dir, dentry, old_name);
7f207e10
AM
879 }
880+EXPORT_SYMBOL(security_path_symlink);
881
882 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
883 struct dentry *new_dentry)
79b8bda9 884@@ -457,6 +459,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
7f207e10 885 return 0;
c2c0f25c 886 return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
7f207e10
AM
887 }
888+EXPORT_SYMBOL(security_path_link);
889
890 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
38d290e6 891 struct path *new_dir, struct dentry *new_dentry,
79b8bda9 892@@ -484,6 +487,7 @@ int security_path_truncate(struct path *path)
7f207e10 893 return 0;
c2c0f25c 894 return call_int_hook(path_truncate, 0, path);
7f207e10
AM
895 }
896+EXPORT_SYMBOL(security_path_truncate);
897
7eafdf33
AM
898 int security_path_chmod(struct path *path, umode_t mode)
899 {
79b8bda9 900@@ -491,6 +495,7 @@ int security_path_chmod(struct path *path, umode_t mode)
7f207e10 901 return 0;
c2c0f25c 902 return call_int_hook(path_chmod, 0, path, mode);
7f207e10
AM
903 }
904+EXPORT_SYMBOL(security_path_chmod);
905
537831f9 906 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 907 {
79b8bda9 908@@ -498,6 +503,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 909 return 0;
c2c0f25c 910 return call_int_hook(path_chown, 0, path, uid, gid);
7f207e10
AM
911 }
912+EXPORT_SYMBOL(security_path_chown);
913
914 int security_path_chroot(struct path *path)
915 {
79b8bda9 916@@ -583,6 +589,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10 917 return 0;
c2c0f25c 918 return call_int_hook(inode_readlink, 0, dentry);
7f207e10
AM
919 }
920+EXPORT_SYMBOL(security_inode_readlink);
921
c2c0f25c
AM
922 int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
923 bool rcu)
79b8bda9 924@@ -598,6 +605,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 925 return 0;
c2c0f25c 926 return call_int_hook(inode_permission, 0, inode, mask);
7f207e10
AM
927 }
928+EXPORT_SYMBOL(security_inode_permission);
929
1e00d052 930 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 931 {
79b8bda9 932@@ -736,6 +744,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
933
934 return fsnotify_perm(file, mask);
935 }
936+EXPORT_SYMBOL(security_file_permission);
937
938 int security_file_alloc(struct file *file)
939 {
79b8bda9 940@@ -795,6 +804,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
941 return ret;
942 return ima_file_mmap(file, prot);
943 }
0c3ec466 944+EXPORT_SYMBOL(security_mmap_file);
7f207e10 945
0c3ec466
AM
946 int security_mmap_addr(unsigned long addr)
947 {
7f207e10
AM
948diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
949--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 950+++ linux/Documentation/ABI/testing/debugfs-aufs 2015-09-24 10:47:58.244719488 +0200
86dc4139 951@@ -0,0 +1,50 @@
7f207e10
AM
952+What: /debug/aufs/si_<id>/
953+Date: March 2009
f6b6e03d 954+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
955+Description:
956+ Under /debug/aufs, a directory named si_<id> is created
957+ per aufs mount, where <id> is a unique id generated
958+ internally.
1facf9fc 959+
86dc4139
AM
960+What: /debug/aufs/si_<id>/plink
961+Date: Apr 2013
f6b6e03d 962+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
963+Description:
964+ It has three lines and shows the information about the
965+ pseudo-link. The first line is a single number
966+ representing a number of buckets. The second line is a
967+ number of pseudo-links per buckets (separated by a
968+ blank). The last line is a single number representing a
969+ total number of psedo-links.
970+ When the aufs mount option 'noplink' is specified, it
971+ will show "1\n0\n0\n".
972+
7f207e10
AM
973+What: /debug/aufs/si_<id>/xib
974+Date: March 2009
f6b6e03d 975+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
976+Description:
977+ It shows the consumed blocks by xib (External Inode Number
978+ Bitmap), its block size and file size.
979+ When the aufs mount option 'noxino' is specified, it
980+ will be empty. About XINO files, see the aufs manual.
981+
982+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
983+Date: March 2009
f6b6e03d 984+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
985+Description:
986+ It shows the consumed blocks by xino (External Inode Number
987+ Translation Table), its link count, block size and file
988+ size.
989+ When the aufs mount option 'noxino' is specified, it
990+ will be empty. About XINO files, see the aufs manual.
991+
992+What: /debug/aufs/si_<id>/xigen
993+Date: March 2009
f6b6e03d 994+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
995+Description:
996+ It shows the consumed blocks by xigen (External Inode
997+ Generation Table), its block size and file size.
998+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
999+ be created.
1000+ When the aufs mount option 'noxino' is specified, it
1001+ will be empty. About XINO files, see the aufs manual.
1002diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
1003--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 1004+++ linux/Documentation/ABI/testing/sysfs-aufs 2015-09-24 10:47:58.244719488 +0200
392086de 1005@@ -0,0 +1,31 @@
7f207e10
AM
1006+What: /sys/fs/aufs/si_<id>/
1007+Date: March 2009
f6b6e03d 1008+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1009+Description:
1010+ Under /sys/fs/aufs, a directory named si_<id> is created
1011+ per aufs mount, where <id> is a unique id generated
1012+ internally.
1013+
1014+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
1015+Date: March 2009
f6b6e03d 1016+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1017+Description:
1018+ It shows the abolute path of a member directory (which
1019+ is called branch) in aufs, and its permission.
1020+
392086de
AM
1021+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
1022+Date: July 2013
f6b6e03d 1023+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
1024+Description:
1025+ It shows the id of a member directory (which is called
1026+ branch) in aufs.
1027+
7f207e10
AM
1028+What: /sys/fs/aufs/si_<id>/xi_path
1029+Date: March 2009
f6b6e03d 1030+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1031+Description:
1032+ It shows the abolute path of XINO (External Inode Number
1033+ Bitmap, Translation Table and Generation Table) file
1034+ even if it is the default path.
1035+ When the aufs mount option 'noxino' is specified, it
1036+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
1037diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
1038--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 1039+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2015-09-24 10:47:58.244719488 +0200
7e9cd9fe 1040@@ -0,0 +1,170 @@
53392da6 1041+
2000de60 1042+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1043+#
1044+# This program is free software; you can redistribute it and/or modify
1045+# it under the terms of the GNU General Public License as published by
1046+# the Free Software Foundation; either version 2 of the License, or
1047+# (at your option) any later version.
1048+#
1049+# This program is distributed in the hope that it will be useful,
1050+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1051+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1052+# GNU General Public License for more details.
1053+#
1054+# You should have received a copy of the GNU General Public License
523b37e3 1055+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1056+
1057+Introduction
1058+----------------------------------------
1059+
1060+aufs [ei ju: ef es] | [a u f s]
1061+1. abbrev. for "advanced multi-layered unification filesystem".
1062+2. abbrev. for "another unionfs".
1063+3. abbrev. for "auf das" in German which means "on the" in English.
1064+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
1065+ But "Filesystem aufs Filesystem" is hard to understand.
1066+
1067+AUFS is a filesystem with features:
1068+- multi layered stackable unification filesystem, the member directory
1069+ is called as a branch.
1070+- branch permission and attribute, 'readonly', 'real-readonly',
7e9cd9fe 1071+ 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their
53392da6
AM
1072+ combination.
1073+- internal "file copy-on-write".
1074+- logical deletion, whiteout.
1075+- dynamic branch manipulation, adding, deleting and changing permission.
1076+- allow bypassing aufs, user's direct branch access.
1077+- external inode number translation table and bitmap which maintains the
1078+ persistent aufs inode number.
1079+- seekable directory, including NFS readdir.
1080+- file mapping, mmap and sharing pages.
1081+- pseudo-link, hardlink over branches.
1082+- loopback mounted filesystem as a branch.
1083+- several policies to select one among multiple writable branches.
1084+- revert a single systemcall when an error occurs in aufs.
1085+- and more...
1086+
1087+
1088+Multi Layered Stackable Unification Filesystem
1089+----------------------------------------------------------------------
1090+Most people already knows what it is.
1091+It is a filesystem which unifies several directories and provides a
1092+merged single directory. When users access a file, the access will be
1093+passed/re-directed/converted (sorry, I am not sure which English word is
1094+correct) to the real file on the member filesystem. The member
1095+filesystem is called 'lower filesystem' or 'branch' and has a mode
1096+'readonly' and 'readwrite.' And the deletion for a file on the lower
1097+readonly branch is handled by creating 'whiteout' on the upper writable
1098+branch.
1099+
1100+On LKML, there have been discussions about UnionMount (Jan Blunck,
1101+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
1102+different approaches to implement the merged-view.
1103+The former tries putting it into VFS, and the latter implements as a
1104+separate filesystem.
1105+(If I misunderstand about these implementations, please let me know and
1106+I shall correct it. Because it is a long time ago when I read their
1107+source files last time).
1108+
1109+UnionMount's approach will be able to small, but may be hard to share
1110+branches between several UnionMount since the whiteout in it is
1111+implemented in the inode on branch filesystem and always
1112+shared. According to Bharata's post, readdir does not seems to be
1113+finished yet.
1114+There are several missing features known in this implementations such as
1115+- for users, the inode number may change silently. eg. copy-up.
1116+- link(2) may break by copy-up.
1117+- read(2) may get an obsoleted filedata (fstat(2) too).
1118+- fcntl(F_SETLK) may be broken by copy-up.
1119+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
1120+ open(O_RDWR).
1121+
7e9cd9fe
AM
1122+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was
1123+merged into mainline. This is another implementation of UnionMount as a
1124+separated filesystem. All the limitations and known problems which
1125+UnionMount are equally inherited to "overlay" filesystem.
1126+
1127+Unionfs has a longer history. When I started implementing a stackable
1128+filesystem (Aug 2005), it already existed. It has virtual super_block,
1129+inode, dentry and file objects and they have an array pointing lower
1130+same kind objects. After contributing many patches for Unionfs, I
1131+re-started my project AUFS (Jun 2006).
53392da6
AM
1132+
1133+In AUFS, the structure of filesystem resembles to Unionfs, but I
1134+implemented my own ideas, approaches and enhancements and it became
1135+totally different one.
1136+
1137+Comparing DM snapshot and fs based implementation
1138+- the number of bytes to be copied between devices is much smaller.
1139+- the type of filesystem must be one and only.
1140+- the fs must be writable, no readonly fs, even for the lower original
1141+ device. so the compression fs will not be usable. but if we use
1142+ loopback mount, we may address this issue.
1143+ for instance,
1144+ mount /cdrom/squashfs.img /sq
1145+ losetup /sq/ext2.img
1146+ losetup /somewhere/cow
1147+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
1148+- it will be difficult (or needs more operations) to extract the
1149+ difference between the original device and COW.
1150+- DM snapshot-merge may help a lot when users try merging. in the
1151+ fs-layer union, users will use rsync(1).
1152+
7e9cd9fe
AM
1153+You may want to read my old paper "Filesystems in LiveCD"
1154+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf).
53392da6 1155+
7e9cd9fe
AM
1156+
1157+Several characters/aspects/persona of aufs
53392da6
AM
1158+----------------------------------------------------------------------
1159+
7e9cd9fe 1160+Aufs has several characters, aspects or persona.
53392da6
AM
1161+1. a filesystem, callee of VFS helper
1162+2. sub-VFS, caller of VFS helper for branches
1163+3. a virtual filesystem which maintains persistent inode number
1164+4. reader/writer of files on branches such like an application
1165+
1166+1. Callee of VFS Helper
1167+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1168+unlink(2) from an application reaches sys_unlink() kernel function and
1169+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1170+calls filesystem specific unlink operation. Actually aufs implements the
1171+unlink operation but it behaves like a redirector.
1172+
1173+2. Caller of VFS Helper for Branches
1174+aufs_unlink() passes the unlink request to the branch filesystem as if
1175+it were called from VFS. So the called unlink operation of the branch
1176+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1177+every necessary pre/post operation for the branch filesystem.
1178+- acquire the lock for the parent dir on a branch
1179+- lookup in a branch
1180+- revalidate dentry on a branch
1181+- mnt_want_write() for a branch
1182+- vfs_unlink() for a branch
1183+- mnt_drop_write() for a branch
1184+- release the lock on a branch
1185+
1186+3. Persistent Inode Number
1187+One of the most important issue for a filesystem is to maintain inode
1188+numbers. This is particularly important to support exporting a
1189+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1190+backend block device for its own. But some storage is necessary to
7e9cd9fe
AM
1191+keep and maintain the inode numbers. It may be a large space and may not
1192+suit to keep in memory. Aufs rents some space from its first writable
1193+branch filesystem (by default) and creates file(s) on it. These files
1194+are created by aufs internally and removed soon (currently) keeping
1195+opened.
53392da6
AM
1196+Note: Because these files are removed, they are totally gone after
1197+ unmounting aufs. It means the inode numbers are not persistent
1198+ across unmount or reboot. I have a plan to make them really
1199+ persistent which will be important for aufs on NFS server.
1200+
1201+4. Read/Write Files Internally (copy-on-write)
1202+Because a branch can be readonly, when you write a file on it, aufs will
1203+"copy-up" it to the upper writable branch internally. And then write the
1204+originally requested thing to the file. Generally kernel doesn't
1205+open/read/write file actively. In aufs, even a single write may cause a
1206+internal "file copy". This behaviour is very similar to cp(1) command.
1207+
1208+Some people may think it is better to pass such work to user space
1209+helper, instead of doing in kernel space. Actually I am still thinking
1210+about it. But currently I have implemented it in kernel space.
1211diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1212--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 1213+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2015-09-24 10:47:58.244719488 +0200
7e9cd9fe 1214@@ -0,0 +1,258 @@
53392da6 1215+
2000de60 1216+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1217+#
1218+# This program is free software; you can redistribute it and/or modify
1219+# it under the terms of the GNU General Public License as published by
1220+# the Free Software Foundation; either version 2 of the License, or
1221+# (at your option) any later version.
1222+#
1223+# This program is distributed in the hope that it will be useful,
1224+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1225+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1226+# GNU General Public License for more details.
1227+#
1228+# You should have received a copy of the GNU General Public License
523b37e3 1229+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1230+
1231+Basic Aufs Internal Structure
1232+
1233+Superblock/Inode/Dentry/File Objects
1234+----------------------------------------------------------------------
1235+As like an ordinary filesystem, aufs has its own
1236+superblock/inode/dentry/file objects. All these objects have a
1237+dynamically allocated array and store the same kind of pointers to the
1238+lower filesystem, branch.
1239+For example, when you build a union with one readwrite branch and one
1240+readonly, mounted /au, /rw and /ro respectively.
1241+- /au = /rw + /ro
1242+- /ro/fileA exists but /rw/fileA
1243+
1244+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1245+pointers are stored in a aufs dentry. The array in aufs dentry will be,
7e9cd9fe 1246+- [0] = NULL (because /rw/fileA doesn't exist)
53392da6
AM
1247+- [1] = /ro/fileA
1248+
1249+This style of an array is essentially same to the aufs
1250+superblock/inode/dentry/file objects.
1251+
1252+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1253+branches dynamically, these objects has its own generation. When
1254+branches are changed, the generation in aufs superblock is
1255+incremented. And a generation in other object are compared when it is
1256+accessed. When a generation in other objects are obsoleted, aufs
1257+refreshes the internal array.
53392da6
AM
1258+
1259+
1260+Superblock
1261+----------------------------------------------------------------------
1262+Additionally aufs superblock has some data for policies to select one
1263+among multiple writable branches, XIB files, pseudo-links and kobject.
1264+See below in detail.
7e9cd9fe
AM
1265+About the policies which supports copy-down a directory, see
1266+wbr_policy.txt too.
53392da6
AM
1267+
1268+
1269+Branch and XINO(External Inode Number Translation Table)
1270+----------------------------------------------------------------------
1271+Every branch has its own xino (external inode number translation table)
1272+file. The xino file is created and unlinked by aufs internally. When two
1273+members of a union exist on the same filesystem, they share the single
1274+xino file.
1275+The struct of a xino file is simple, just a sequence of aufs inode
1276+numbers which is indexed by the lower inode number.
1277+In the above sample, assume the inode number of /ro/fileA is i111 and
1278+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1279+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1280+
1281+When the inode numbers are not contiguous, the xino file will be sparse
1282+which has a hole in it and doesn't consume as much disk space as it
1283+might appear. If your branch filesystem consumes disk space for such
1284+holes, then you should specify 'xino=' option at mounting aufs.
1285+
7e9cd9fe
AM
1286+Aufs has a mount option to free the disk blocks for such holes in XINO
1287+files on tmpfs or ramdisk. But it is not so effective actually. If you
1288+meet a problem of disk shortage due to XINO files, then you should try
1289+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git.
1290+The patch localizes the assignment inumbers per tmpfs-mount and avoid
1291+the holes in XINO files.
1292+
53392da6 1293+Also a writable branch has three kinds of "whiteout bases". All these
7e9cd9fe 1294+are existed when the branch is joined to aufs, and their names are
53392da6
AM
1295+whiteout-ed doubly, so that users will never see their names in aufs
1296+hierarchy.
7e9cd9fe 1297+1. a regular file which will be hardlinked to all whiteouts.
53392da6 1298+2. a directory to store a pseudo-link.
7e9cd9fe 1299+3. a directory to store an "orphan"-ed file temporary.
53392da6
AM
1300+
1301+1. Whiteout Base
1302+ When you remove a file on a readonly branch, aufs handles it as a
1303+ logical deletion and creates a whiteout on the upper writable branch
1304+ as a hardlink of this file in order not to consume inode on the
1305+ writable branch.
1306+2. Pseudo-link Dir
1307+ See below, Pseudo-link.
1308+3. Step-Parent Dir
1309+ When "fileC" exists on the lower readonly branch only and it is
1310+ opened and removed with its parent dir, and then user writes
1311+ something into it, then aufs copies-up fileC to this
1312+ directory. Because there is no other dir to store fileC. After
1313+ creating a file under this dir, the file is unlinked.
1314+
1315+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1316+dynamically, a branch has its own id. When the branch order changes,
1317+aufs finds the new index by searching the branch id.
53392da6
AM
1318+
1319+
1320+Pseudo-link
1321+----------------------------------------------------------------------
1322+Assume "fileA" exists on the lower readonly branch only and it is
1323+hardlinked to "fileB" on the branch. When you write something to fileA,
1324+aufs copies-up it to the upper writable branch. Additionally aufs
1325+creates a hardlink under the Pseudo-link Directory of the writable
1326+branch. The inode of a pseudo-link is kept in aufs super_block as a
1327+simple list. If fileB is read after unlinking fileA, aufs returns
1328+filedata from the pseudo-link instead of the lower readonly
1329+branch. Because the pseudo-link is based upon the inode, to keep the
7e9cd9fe 1330+inode number by xino (see above) is essentially necessary.
53392da6
AM
1331+
1332+All the hardlinks under the Pseudo-link Directory of the writable branch
1333+should be restored in a proper location later. Aufs provides a utility
1334+to do this. The userspace helpers executed at remounting and unmounting
1335+aufs by default.
1336+During this utility is running, it puts aufs into the pseudo-link
1337+maintenance mode. In this mode, only the process which began the
1338+maintenance mode (and its child processes) is allowed to operate in
1339+aufs. Some other processes which are not related to the pseudo-link will
1340+be allowed to run too, but the rest have to return an error or wait
1341+until the maintenance mode ends. If a process already acquires an inode
1342+mutex (in VFS), it has to return an error.
1343+
1344+
1345+XIB(external inode number bitmap)
1346+----------------------------------------------------------------------
1347+Addition to the xino file per a branch, aufs has an external inode number
7e9cd9fe
AM
1348+bitmap in a superblock object. It is also an internal file such like a
1349+xino file.
53392da6
AM
1350+It is a simple bitmap to mark whether the aufs inode number is in-use or
1351+not.
1352+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1353+
7e9cd9fe 1354+As well as XINO files, aufs has a feature to truncate/refresh XIB to
53392da6
AM
1355+reduce the number of consumed disk blocks for these files.
1356+
1357+
1358+Virtual or Vertical Dir, and Readdir in Userspace
1359+----------------------------------------------------------------------
1360+In order to support multiple layers (branches), aufs readdir operation
1361+constructs a virtual dir block on memory. For readdir, aufs calls
1362+vfs_readdir() internally for each dir on branches, merges their entries
1363+with eliminating the whiteout-ed ones, and sets it to file (dir)
1364+object. So the file object has its entry list until it is closed. The
1365+entry list will be updated when the file position is zero and becomes
7e9cd9fe 1366+obsoleted. This decision is made in aufs automatically.
53392da6
AM
1367+
1368+The dynamically allocated memory block for the name of entries has a
1369+unit of 512 bytes (by default) and stores the names contiguously (no
1370+padding). Another block for each entry is handled by kmem_cache too.
1371+During building dir blocks, aufs creates hash list and judging whether
1372+the entry is whiteouted by its upper branch or already listed.
1373+The merged result is cached in the corresponding inode object and
1374+maintained by a customizable life-time option.
1375+
1376+Some people may call it can be a security hole or invite DoS attack
1377+since the opened and once readdir-ed dir (file object) holds its entry
1378+list and becomes a pressure for system memory. But I'd say it is similar
1379+to files under /proc or /sys. The virtual files in them also holds a
1380+memory page (generally) while they are opened. When an idea to reduce
1381+memory for them is introduced, it will be applied to aufs too.
1382+For those who really hate this situation, I've developed readdir(3)
1383+library which operates this merging in userspace. You just need to set
1384+LD_PRELOAD environment variable, and aufs will not consume no memory in
1385+kernel space for readdir(3).
1386+
1387+
1388+Workqueue
1389+----------------------------------------------------------------------
1390+Aufs sometimes requires privilege access to a branch. For instance,
1391+in copy-up/down operation. When a user process is going to make changes
1392+to a file which exists in the lower readonly branch only, and the mode
1393+of one of ancestor directories may not be writable by a user
1394+process. Here aufs copy-up the file with its ancestors and they may
1395+require privilege to set its owner/group/mode/etc.
1396+This is a typical case of a application character of aufs (see
1397+Introduction).
1398+
1399+Aufs uses workqueue synchronously for this case. It creates its own
1400+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1401+passes the request to call mkdir or write (for example), and wait for
1402+its completion. This approach solves a problem of a signal handler
1403+simply.
1404+If aufs didn't adopt the workqueue and changed the privilege of the
7e9cd9fe
AM
1405+process, then the process may receive the unexpected SIGXFSZ or other
1406+signals.
53392da6
AM
1407+
1408+Also aufs uses the system global workqueue ("events" kernel thread) too
1409+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1410+whiteout base and etc. This is unrelated to a privilege.
1411+Most of aufs operation tries acquiring a rw_semaphore for aufs
1412+superblock at the beginning, at the same time waits for the completion
1413+of all queued asynchronous tasks.
1414+
1415+
1416+Whiteout
1417+----------------------------------------------------------------------
1418+The whiteout in aufs is very similar to Unionfs's. That is represented
1419+by its filename. UnionMount takes an approach of a file mode, but I am
1420+afraid several utilities (find(1) or something) will have to support it.
1421+
1422+Basically the whiteout represents "logical deletion" which stops aufs to
1423+lookup further, but also it represents "dir is opaque" which also stop
7e9cd9fe 1424+further lookup.
53392da6
AM
1425+
1426+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1427+In order to make several functions in a single systemcall to be
1428+revertible, aufs adopts an approach to rename a directory to a temporary
1429+unique whiteouted name.
1430+For example, in rename(2) dir where the target dir already existed, aufs
1431+renames the target dir to a temporary unique whiteouted name before the
7e9cd9fe 1432+actual rename on a branch, and then handles other actions (make it opaque,
53392da6
AM
1433+update the attributes, etc). If an error happens in these actions, aufs
1434+simply renames the whiteouted name back and returns an error. If all are
1435+succeeded, aufs registers a function to remove the whiteouted unique
1436+temporary name completely and asynchronously to the system global
1437+workqueue.
1438+
1439+
1440+Copy-up
1441+----------------------------------------------------------------------
1442+It is a well-known feature or concept.
1443+When user modifies a file on a readonly branch, aufs operate "copy-up"
1444+internally and makes change to the new file on the upper writable branch.
1445+When the trigger systemcall does not update the timestamps of the parent
1446+dir, aufs reverts it after copy-up.
c2b27bf2
AM
1447+
1448+
1449+Move-down (aufs3.9 and later)
1450+----------------------------------------------------------------------
1451+"Copy-up" is one of the essential feature in aufs. It copies a file from
1452+the lower readonly branch to the upper writable branch when a user
1453+changes something about the file.
1454+"Move-down" is an opposite action of copy-up. Basically this action is
1455+ran manually instead of automatically and internally.
076b876e
AM
1456+For desgin and implementation, aufs has to consider these issues.
1457+- whiteout for the file may exist on the lower branch.
1458+- ancestor directories may not exist on the lower branch.
1459+- diropq for the ancestor directories may exist on the upper branch.
1460+- free space on the lower branch will reduce.
1461+- another access to the file may happen during moving-down, including
7e9cd9fe 1462+ UDBA (see "Revalidate Dentry and UDBA").
076b876e
AM
1463+- the file should not be hard-linked nor pseudo-linked. they should be
1464+ handled by auplink utility later.
c2b27bf2
AM
1465+
1466+Sometimes users want to move-down a file from the upper writable branch
1467+to the lower readonly or writable branch. For instance,
1468+- the free space of the upper writable branch is going to run out.
1469+- create a new intermediate branch between the upper and lower branch.
1470+- etc.
1471+
1472+For this purpose, use "aumvdown" command in aufs-util.git.
b912730e
AM
1473diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt linux/Documentation/filesystems/aufs/design/03atomic_open.txt
1474--- /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 1475+++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2015-09-24 10:47:58.244719488 +0200
b912730e
AM
1476@@ -0,0 +1,85 @@
1477+
1478+# Copyright (C) 2015 Junjiro R. Okajima
1479+#
1480+# This program is free software; you can redistribute it and/or modify
1481+# it under the terms of the GNU General Public License as published by
1482+# the Free Software Foundation; either version 2 of the License, or
1483+# (at your option) any later version.
1484+#
1485+# This program is distributed in the hope that it will be useful,
1486+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1487+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1488+# GNU General Public License for more details.
1489+#
1490+# You should have received a copy of the GNU General Public License
1491+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1492+
1493+Support for a branch who has its ->atomic_open()
1494+----------------------------------------------------------------------
1495+The filesystems who implement its ->atomic_open() are not majority. For
1496+example NFSv4 does, and aufs should call NFSv4 ->atomic_open,
1497+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than
1498+->atomic_open(), NFSv4 returns an error for this open(2). While I am not
1499+sure whether all filesystems who have ->atomic_open() behave like this,
1500+but NFSv4 surely returns the error.
1501+
1502+In order to support ->atomic_open() for aufs, there are a few
1503+approaches.
1504+
1505+A. Introduce aufs_atomic_open()
1506+ - calls one of VFS:do_last(), lookup_open() or atomic_open() for
1507+ branch fs.
1508+B. Introduce aufs_atomic_open() calling create, open and chmod. this is
1509+ an aufs user Pip Cet's approach
1510+ - calls aufs_create(), VFS finish_open() and notify_change().
1511+ - pass fake-mode to finish_open(), and then correct the mode by
1512+ notify_change().
1513+C. Extend aufs_open() to call branch fs's ->atomic_open()
1514+ - no aufs_atomic_open().
1515+ - aufs_lookup() registers the TID to an aufs internal object.
1516+ - aufs_create() does nothing when the matching TID is registered, but
1517+ registers the mode.
1518+ - aufs_open() calls branch fs's ->atomic_open() when the matching
1519+ TID is registered.
1520+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's
1521+ credential
1522+ - no aufs_atomic_open().
1523+ - aufs_create() registers the TID to an internal object. this info
1524+ represents "this process created this file just now."
1525+ - when aufs gets EACCES from branch fs's ->open(), then confirm the
1526+ registered TID and re-try open() with superuser's credential.
1527+
1528+Pros and cons for each approach.
1529+
1530+A.
1531+ - straightforward but highly depends upon VFS internal.
1532+ - the atomic behavaiour is kept.
1533+ - some of parameters such as nameidata are hard to reproduce for
1534+ branch fs.
1535+ - large overhead.
1536+B.
1537+ - easy to implement.
1538+ - the atomic behavaiour is lost.
1539+C.
1540+ - the atomic behavaiour is kept.
1541+ - dirty and tricky.
1542+ - VFS checks whether the file is created correctly after calling
1543+ ->create(), which means this approach doesn't work.
1544+D.
1545+ - easy to implement.
1546+ - the atomic behavaiour is lost.
1547+ - to open a file with superuser's credential and give it to a user
1548+ process is a bad idea, since the file object keeps the credential
1549+ in it. It may affect LSM or something. This approach doesn't work
1550+ either.
1551+
1552+The approach A is ideal, but it hard to implement. So here is a
1553+variation of A, which is to be implemented.
1554+
1555+A-1. Introduce aufs_atomic_open()
1556+ - calls branch fs ->atomic_open() if exists. otherwise calls
1557+ vfs_create() and finish_open().
1558+ - the demerit is that the several checks after branch fs
1559+ ->atomic_open() are lost. in the ordinary case, the checks are
1560+ done by VFS:do_last(), lookup_open() and atomic_open(). some can
1561+ be implemented in aufs, but not all I am afraid.
53392da6
AM
1562diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1563--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 1564+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2015-09-24 10:47:58.244719488 +0200
7e9cd9fe 1565@@ -0,0 +1,113 @@
53392da6 1566+
2000de60 1567+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1568+#
1569+# This program is free software; you can redistribute it and/or modify
1570+# it under the terms of the GNU General Public License as published by
1571+# the Free Software Foundation; either version 2 of the License, or
1572+# (at your option) any later version.
1573+#
1574+# This program is distributed in the hope that it will be useful,
1575+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1576+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1577+# GNU General Public License for more details.
1578+#
1579+# You should have received a copy of the GNU General Public License
523b37e3 1580+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1581+
1582+Lookup in a Branch
1583+----------------------------------------------------------------------
1584+Since aufs has a character of sub-VFS (see Introduction), it operates
7e9cd9fe
AM
1585+lookup for branches as VFS does. It may be a heavy work. But almost all
1586+lookup operation in aufs is the simplest case, ie. lookup only an entry
1587+directly connected to its parent. Digging down the directory hierarchy
1588+is unnecessary. VFS has a function lookup_one_len() for that use, and
1589+aufs calls it.
1590+
1591+When a branch is a remote filesystem, aufs basically relies upon its
53392da6
AM
1592+->d_revalidate(), also aufs forces the hardest revalidate tests for
1593+them.
1594+For d_revalidate, aufs implements three levels of revalidate tests. See
1595+"Revalidate Dentry and UDBA" in detail.
1596+
1597+
076b876e
AM
1598+Test Only the Highest One for the Directory Permission (dirperm1 option)
1599+----------------------------------------------------------------------
1600+Let's try case study.
1601+- aufs has two branches, upper readwrite and lower readonly.
1602+ /au = /rw + /ro
1603+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1604+- user invoked "chmod a+rx /au/dirA"
1605+- the internal copy-up is activated and "/rw/dirA" is created and its
7e9cd9fe 1606+ permission bits are set to world readable.
076b876e
AM
1607+- then "/au/dirA" becomes world readable?
1608+
1609+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1610+or it may be a natively readonly filesystem. If aufs respects the lower
1611+branch, it should not respond readdir request from other users. But user
1612+allowed it by chmod. Should really aufs rejects showing the entries
1613+under /ro/dirA?
1614+
7e9cd9fe
AM
1615+To be honest, I don't have a good solution for this case. So aufs
1616+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to
1617+users.
076b876e
AM
1618+When dirperm1 is specified, aufs checks only the highest one for the
1619+directory permission, and shows the entries. Otherwise, as usual, checks
1620+every dir existing on all branches and rejects the request.
1621+
1622+As a side effect, dirperm1 option improves the performance of aufs
1623+because the number of permission check is reduced when the number of
1624+branch is many.
1625+
1626+
53392da6
AM
1627+Revalidate Dentry and UDBA (User's Direct Branch Access)
1628+----------------------------------------------------------------------
1629+Generally VFS helpers re-validate a dentry as a part of lookup.
1630+0. digging down the directory hierarchy.
1631+1. lock the parent dir by its i_mutex.
1632+2. lookup the final (child) entry.
1633+3. revalidate it.
1634+4. call the actual operation (create, unlink, etc.)
1635+5. unlock the parent dir
1636+
1637+If the filesystem implements its ->d_revalidate() (step 3), then it is
1638+called. Actually aufs implements it and checks the dentry on a branch is
1639+still valid.
1640+But it is not enough. Because aufs has to release the lock for the
1641+parent dir on a branch at the end of ->lookup() (step 2) and
1642+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1643+held by VFS.
1644+If the file on a branch is changed directly, eg. bypassing aufs, after
1645+aufs released the lock, then the subsequent operation may cause
1646+something unpleasant result.
1647+
1648+This situation is a result of VFS architecture, ->lookup() and
1649+->d_revalidate() is separated. But I never say it is wrong. It is a good
1650+design from VFS's point of view. It is just not suitable for sub-VFS
1651+character in aufs.
1652+
1653+Aufs supports such case by three level of revalidation which is
1654+selectable by user.
1655+1. Simple Revalidate
1656+ Addition to the native flow in VFS's, confirm the child-parent
1657+ relationship on the branch just after locking the parent dir on the
1658+ branch in the "actual operation" (step 4). When this validation
1659+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1660+ checks the validation of the dentry on branches.
1661+2. Monitor Changes Internally by Inotify/Fsnotify
1662+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1663+ the dentry on the branch, and returns EBUSY if it finds different
1664+ dentry.
1665+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1666+ during it is in cache. When the event is notified, aufs registers a
1667+ function to kernel 'events' thread by schedule_work(). And the
1668+ function sets some special status to the cached aufs dentry and inode
1669+ private data. If they are not cached, then aufs has nothing to
1670+ do. When the same file is accessed through aufs (step 0-3) later,
1671+ aufs will detect the status and refresh all necessary data.
1672+ In this mode, aufs has to ignore the event which is fired by aufs
1673+ itself.
1674+3. No Extra Validation
1675+ This is the simplest test and doesn't add any additional revalidation
7e9cd9fe 1676+ test, and skip the revalidation in step 4. It is useful and improves
53392da6
AM
1677+ aufs performance when system surely hide the aufs branches from user,
1678+ by over-mounting something (or another method).
1679diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1680--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 1681+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2015-09-24 10:47:58.244719488 +0200
7e9cd9fe 1682@@ -0,0 +1,74 @@
53392da6 1683+
2000de60 1684+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1685+#
1686+# This program is free software; you can redistribute it and/or modify
1687+# it under the terms of the GNU General Public License as published by
1688+# the Free Software Foundation; either version 2 of the License, or
1689+# (at your option) any later version.
1690+#
1691+# This program is distributed in the hope that it will be useful,
1692+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1693+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1694+# GNU General Public License for more details.
1695+#
1696+# You should have received a copy of the GNU General Public License
523b37e3 1697+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1698+
1699+Branch Manipulation
1700+
1701+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1702+and changing its permission/attribute, there are a lot of works to do.
1703+
1704+
1705+Add a Branch
1706+----------------------------------------------------------------------
1707+o Confirm the adding dir exists outside of aufs, including loopback
7e9cd9fe 1708+ mount, and its various attributes.
53392da6
AM
1709+o Initialize the xino file and whiteout bases if necessary.
1710+ See struct.txt.
1711+
1712+o Check the owner/group/mode of the directory
1713+ When the owner/group/mode of the adding directory differs from the
1714+ existing branch, aufs issues a warning because it may impose a
1715+ security risk.
1716+ For example, when a upper writable branch has a world writable empty
1717+ top directory, a malicious user can create any files on the writable
1718+ branch directly, like copy-up and modify manually. If something like
1719+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1720+ writable branch, and the writable branch is world-writable, then a
1721+ malicious guy may create /etc/passwd on the writable branch directly
1722+ and the infected file will be valid in aufs.
7e9cd9fe 1723+ I am afraid it can be a security issue, but aufs can do nothing except
53392da6
AM
1724+ producing a warning.
1725+
1726+
1727+Delete a Branch
1728+----------------------------------------------------------------------
1729+o Confirm the deleting branch is not busy
1730+ To be general, there is one merit to adopt "remount" interface to
1731+ manipulate branches. It is to discard caches. At deleting a branch,
1732+ aufs checks the still cached (and connected) dentries and inodes. If
1733+ there are any, then they are all in-use. An inode without its
1734+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1735+
1736+ For the cached one, aufs checks whether the same named entry exists on
1737+ other branches.
1738+ If the cached one is a directory, because aufs provides a merged view
1739+ to users, as long as one dir is left on any branch aufs can show the
1740+ dir to users. In this case, the branch can be removed from aufs.
1741+ Otherwise aufs rejects deleting the branch.
1742+
1743+ If any file on the deleting branch is opened by aufs, then aufs
1744+ rejects deleting.
1745+
1746+
1747+Modify the Permission of a Branch
1748+----------------------------------------------------------------------
1749+o Re-initialize or remove the xino file and whiteout bases if necessary.
1750+ See struct.txt.
1751+
1752+o rw --> ro: Confirm the modifying branch is not busy
1753+ Aufs rejects the request if any of these conditions are true.
1754+ - a file on the branch is mmap-ed.
1755+ - a regular file on the branch is opened for write and there is no
1756+ same named entry on the upper branch.
1757diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1758--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 1759+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2015-09-24 10:47:58.244719488 +0200
523b37e3 1760@@ -0,0 +1,64 @@
53392da6 1761+
2000de60 1762+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1763+#
1764+# This program is free software; you can redistribute it and/or modify
1765+# it under the terms of the GNU General Public License as published by
1766+# the Free Software Foundation; either version 2 of the License, or
1767+# (at your option) any later version.
1768+#
1769+# This program is distributed in the hope that it will be useful,
1770+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1771+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1772+# GNU General Public License for more details.
1773+#
1774+# You should have received a copy of the GNU General Public License
523b37e3 1775+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1776+
1777+Policies to Select One among Multiple Writable Branches
1778+----------------------------------------------------------------------
1779+When the number of writable branch is more than one, aufs has to decide
1780+the target branch for file creation or copy-up. By default, the highest
1781+writable branch which has the parent (or ancestor) dir of the target
1782+file is chosen (top-down-parent policy).
1783+By user's request, aufs implements some other policies to select the
7e9cd9fe
AM
1784+writable branch, for file creation several policies, round-robin,
1785+most-free-space, and other policies. For copy-up, top-down-parent,
1786+bottom-up-parent, bottom-up and others.
53392da6
AM
1787+
1788+As expected, the round-robin policy selects the branch in circular. When
1789+you have two writable branches and creates 10 new files, 5 files will be
1790+created for each branch. mkdir(2) systemcall is an exception. When you
1791+create 10 new directories, all will be created on the same branch.
1792+And the most-free-space policy selects the one which has most free
1793+space among the writable branches. The amount of free space will be
1794+checked by aufs internally, and users can specify its time interval.
1795+
1796+The policies for copy-up is more simple,
1797+top-down-parent is equivalent to the same named on in create policy,
1798+bottom-up-parent selects the writable branch where the parent dir
1799+exists and the nearest upper one from the copyup-source,
1800+bottom-up selects the nearest upper writable branch from the
1801+copyup-source, regardless the existence of the parent dir.
1802+
1803+There are some rules or exceptions to apply these policies.
1804+- If there is a readonly branch above the policy-selected branch and
1805+ the parent dir is marked as opaque (a variation of whiteout), or the
1806+ target (creating) file is whiteout-ed on the upper readonly branch,
1807+ then the result of the policy is ignored and the target file will be
1808+ created on the nearest upper writable branch than the readonly branch.
1809+- If there is a writable branch above the policy-selected branch and
1810+ the parent dir is marked as opaque or the target file is whiteouted
1811+ on the branch, then the result of the policy is ignored and the target
1812+ file will be created on the highest one among the upper writable
1813+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1814+ it as usual.
1815+- link(2) and rename(2) systemcalls are exceptions in every policy.
1816+ They try selecting the branch where the source exists as possible
1817+ since copyup a large file will take long time. If it can't be,
1818+ ie. the branch where the source exists is readonly, then they will
1819+ follow the copyup policy.
1820+- There is an exception for rename(2) when the target exists.
1821+ If the rename target exists, aufs compares the index of the branches
1822+ where the source and the target exists and selects the higher
1823+ one. If the selected branch is readonly, then aufs follows the
1824+ copyup policy.
076b876e
AM
1825diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
1826--- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 1827+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2015-09-24 10:47:58.244719488 +0200
076b876e
AM
1828@@ -0,0 +1,120 @@
1829+
2000de60 1830+# Copyright (C) 2011-2015 Junjiro R. Okajima
076b876e
AM
1831+#
1832+# This program is free software; you can redistribute it and/or modify
1833+# it under the terms of the GNU General Public License as published by
1834+# the Free Software Foundation; either version 2 of the License, or
1835+# (at your option) any later version.
1836+#
1837+# This program is distributed in the hope that it will be useful,
1838+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1839+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1840+# GNU General Public License for more details.
1841+#
1842+# You should have received a copy of the GNU General Public License
1843+# along with this program; if not, write to the Free Software
1844+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1845+
1846+
1847+File-based Hierarchical Storage Management (FHSM)
1848+----------------------------------------------------------------------
1849+Hierarchical Storage Management (or HSM) is a well-known feature in the
1850+storage world. Aufs provides this feature as file-based with multiple
7e9cd9fe 1851+writable branches, based upon the principle of "Colder, the Lower".
076b876e 1852+Here the word "colder" means that the less used files, and "lower" means
7e9cd9fe 1853+that the position in the order of the stacked branches vertically.
076b876e
AM
1854+These multiple writable branches are prioritized, ie. the topmost one
1855+should be the fastest drive and be used heavily.
1856+
1857+o Characters in aufs FHSM story
1858+- aufs itself and a new branch attribute.
1859+- a new ioctl interface to move-down and to establish a connection with
1860+ the daemon ("move-down" is a converse of "copy-up").
1861+- userspace tool and daemon.
1862+
1863+The userspace daemon establishes a connection with aufs and waits for
1864+the notification. The notified information is very similar to struct
1865+statfs containing the number of consumed blocks and inodes.
1866+When the consumed blocks/inodes of a branch exceeds the user-specified
1867+upper watermark, the daemon activates its move-down process until the
1868+consumed blocks/inodes reaches the user-specified lower watermark.
1869+
1870+The actual move-down is done by aufs based upon the request from
1871+user-space since we need to maintain the inode number and the internal
1872+pointer arrays in aufs.
1873+
1874+Currently aufs FHSM handles the regular files only. Additionally they
1875+must not be hard-linked nor pseudo-linked.
1876+
1877+
1878+o Cowork of aufs and the user-space daemon
1879+ During the userspace daemon established the connection, aufs sends a
1880+ small notification to it whenever aufs writes something into the
1881+ writable branch. But it may cost high since aufs issues statfs(2)
1882+ internally. So user can specify a new option to cache the
1883+ info. Actually the notification is controlled by these factors.
1884+ + the specified cache time.
1885+ + classified as "force" by aufs internally.
1886+ Until the specified time expires, aufs doesn't send the info
1887+ except the forced cases. When aufs decide forcing, the info is always
1888+ notified to userspace.
1889+ For example, the number of free inodes is generally large enough and
1890+ the shortage of it happens rarely. So aufs doesn't force the
1891+ notification when creating a new file, directory and others. This is
1892+ the typical case which aufs doesn't force.
1893+ When aufs writes the actual filedata and the files consumes any of new
1894+ blocks, the aufs forces notifying.
1895+
1896+
1897+o Interfaces in aufs
1898+- New branch attribute.
1899+ + fhsm
1900+ Specifies that the branch is managed by FHSM feature. In other word,
1901+ participant in the FHSM.
1902+ When nofhsm is set to the branch, it will not be the source/target
1903+ branch of the move-down operation. This attribute is set
1904+ independently from coo and moo attributes, and if you want full
1905+ FHSM, you should specify them as well.
1906+- New mount option.
1907+ + fhsm_sec
1908+ Specifies a second to suppress many less important info to be
1909+ notified.
1910+- New ioctl.
1911+ + AUFS_CTL_FHSM_FD
1912+ create a new file descriptor which userspace can read the notification
1913+ (a subset of struct statfs) from aufs.
1914+- Module parameter 'brs'
1915+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not
1916+ be set.
1917+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
1918+ When there are two or more branches with fhsm attributes,
1919+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
1920+ terminates it. As a result of remounting and branch-manipulation, the
1921+ number of branches with fhsm attribute can be one. In this case,
1922+ /sbin/mount.aufs will terminate the user-space daemon.
1923+
1924+
1925+Finally the operation is done as these steps in kernel-space.
1926+- make sure that,
1927+ + no one else is using the file.
1928+ + the file is not hard-linked.
1929+ + the file is not pseudo-linked.
1930+ + the file is a regular file.
1931+ + the parent dir is not opaqued.
1932+- find the target writable branch.
1933+- make sure the file is not whiteout-ed by the upper (than the target)
1934+ branch.
1935+- make the parent dir on the target branch.
1936+- mutex lock the inode on the branch.
1937+- unlink the whiteout on the target branch (if exists).
1938+- lookup and create the whiteout-ed temporary name on the target branch.
1939+- copy the file as the whiteout-ed temporary name on the target branch.
1940+- rename the whiteout-ed temporary name to the original name.
1941+- unlink the file on the source branch.
1942+- maintain the internal pointer array and the external inode number
1943+ table (XINO).
1944+- maintain the timestamps and other attributes of the parent dir and the
1945+ file.
1946+
1947+And of course, in every step, an error may happen. So the operation
1948+should restore the original file state after an error happens.
53392da6
AM
1949diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1950--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 1951+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2015-09-24 10:47:58.244719488 +0200
b912730e 1952@@ -0,0 +1,72 @@
53392da6 1953+
2000de60 1954+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1955+#
1956+# This program is free software; you can redistribute it and/or modify
1957+# it under the terms of the GNU General Public License as published by
1958+# the Free Software Foundation; either version 2 of the License, or
1959+# (at your option) any later version.
1960+#
1961+# This program is distributed in the hope that it will be useful,
1962+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1963+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1964+# GNU General Public License for more details.
1965+#
1966+# You should have received a copy of the GNU General Public License
523b37e3 1967+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1968+
1969+mmap(2) -- File Memory Mapping
1970+----------------------------------------------------------------------
1971+In aufs, the file-mapped pages are handled by a branch fs directly, no
1972+interaction with aufs. It means aufs_mmap() calls the branch fs's
1973+->mmap().
1974+This approach is simple and good, but there is one problem.
7e9cd9fe 1975+Under /proc, several entries show the mmapped files by its path (with
53392da6
AM
1976+device and inode number), and the printed path will be the path on the
1977+branch fs's instead of virtual aufs's.
1978+This is not a problem in most cases, but some utilities lsof(1) (and its
1979+user) may expect the path on aufs.
1980+
1981+To address this issue, aufs adds a new member called vm_prfile in struct
1982+vm_area_struct (and struct vm_region). The original vm_file points to
1983+the file on the branch fs in order to handle everything correctly as
1984+usual. The new vm_prfile points to a virtual file in aufs, and the
1985+show-functions in procfs refers to vm_prfile if it is set.
1986+Also we need to maintain several other places where touching vm_file
1987+such like
1988+- fork()/clone() copies vma and the reference count of vm_file is
1989+ incremented.
1990+- merging vma maintains the ref count too.
1991+
7e9cd9fe 1992+This is not a good approach. It just fakes the printed path. But it
53392da6
AM
1993+leaves all behaviour around f_mapping unchanged. This is surely an
1994+advantage.
1995+Actually aufs had adopted another complicated approach which calls
1996+generic_file_mmap() and handles struct vm_operations_struct. In this
1997+approach, aufs met a hard problem and I could not solve it without
1998+switching the approach.
b912730e
AM
1999+
2000+There may be one more another approach which is
2001+- bind-mount the branch-root onto the aufs-root internally
2002+- grab the new vfsmount (ie. struct mount)
2003+- lazy-umount the branch-root internally
2004+- in open(2) the aufs-file, open the branch-file with the hidden
2005+ vfsmount (instead of the original branch's vfsmount)
2006+- ideally this "bind-mount and lazy-umount" should be done atomically,
2007+ but it may be possible from userspace by the mount helper.
2008+
2009+Adding the internal hidden vfsmount and using it in opening a file, the
2010+file path under /proc will be printed correctly. This approach looks
2011+smarter, but is not possible I am afraid.
2012+- aufs-root may be bind-mount later. when it happens, another hidden
2013+ vfsmount will be required.
2014+- it is hard to get the chance to bind-mount and lazy-umount
2015+ + in kernel-space, FS can have vfsmount in open(2) via
2016+ file->f_path, and aufs can know its vfsmount. But several locks are
2017+ already acquired, and if aufs tries to bind-mount and lazy-umount
2018+ here, then it may cause a deadlock.
2019+ + in user-space, bind-mount doesn't invoke the mount helper.
2020+- since /proc shows dev and ino, aufs has to give vma these info. it
2021+ means a new member vm_prinode will be necessary. this is essentially
2022+ equivalent to vm_prfile described above.
2023+
2024+I have to give up this "looks-smater" approach.
c1595e42
JR
2025diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
2026--- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 2027+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2015-09-24 10:47:58.244719488 +0200
c1595e42
JR
2028@@ -0,0 +1,96 @@
2029+
2000de60 2030+# Copyright (C) 2014-2015 Junjiro R. Okajima
c1595e42
JR
2031+#
2032+# This program is free software; you can redistribute it and/or modify
2033+# it under the terms of the GNU General Public License as published by
2034+# the Free Software Foundation; either version 2 of the License, or
2035+# (at your option) any later version.
2036+#
2037+# This program is distributed in the hope that it will be useful,
2038+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2039+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2040+# GNU General Public License for more details.
2041+#
2042+# You should have received a copy of the GNU General Public License
2043+# along with this program; if not, write to the Free Software
2044+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2045+
2046+
2047+Listing XATTR/EA and getting the value
2048+----------------------------------------------------------------------
2049+For the inode standard attributes (owner, group, timestamps, etc.), aufs
2050+shows the values from the topmost existing file. This behaviour is good
7e9cd9fe 2051+for the non-dir entries since the bahaviour exactly matches the shown
c1595e42
JR
2052+information. But for the directories, aufs considers all the same named
2053+entries on the lower branches. Which means, if one of the lower entry
2054+rejects readdir call, then aufs returns an error even if the topmost
2055+entry allows it. This behaviour is necessary to respect the branch fs's
2056+security, but can make users confused since the user-visible standard
2057+attributes don't match the behaviour.
2058+To address this issue, aufs has a mount option called dirperm1 which
2059+checks the permission for the topmost entry only, and ignores the lower
2060+entry's permission.
2061+
2062+A similar issue can happen around XATTR.
2063+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
7e9cd9fe
AM
2064+always set. Otherwise these very unpleasant situation would happen.
2065+- listxattr(2) may return the duplicated entries.
c1595e42
JR
2066+- users may not be able to remove or reset the XATTR forever,
2067+
2068+
2069+XATTR/EA support in the internal (copy,move)-(up,down)
2070+----------------------------------------------------------------------
7e9cd9fe 2071+Generally the extended attributes of inode are categorized as these.
c1595e42
JR
2072+- "security" for LSM and capability.
2073+- "system" for posix ACL, 'acl' mount option is required for the branch
2074+ fs generally.
2075+- "trusted" for userspace, CAP_SYS_ADMIN is required.
2076+- "user" for userspace, 'user_xattr' mount option is required for the
2077+ branch fs generally.
2078+
2079+Moreover there are some other categories. Aufs handles these rather
2080+unpopular categories as the ordinary ones, ie. there is no special
2081+condition nor exception.
2082+
2083+In copy-up, the support for XATTR on the dst branch may differ from the
2084+src branch. In this case, the copy-up operation will get an error and
7e9cd9fe
AM
2085+the original user operation which triggered the copy-up will fail. It
2086+can happen that even all copy-up will fail.
c1595e42
JR
2087+When both of src and dst branches support XATTR and if an error occurs
2088+during copying XATTR, then the copy-up should fail obviously. That is a
2089+good reason and aufs should return an error to userspace. But when only
7e9cd9fe 2090+the src branch support that XATTR, aufs should not return an error.
c1595e42
JR
2091+For example, the src branch supports ACL but the dst branch doesn't
2092+because the dst branch may natively un-support it or temporary
2093+un-support it due to "noacl" mount option. Of course, the dst branch fs
2094+may NOT return an error even if the XATTR is not supported. It is
2095+totally up to the branch fs.
2096+
2097+Anyway when the aufs internal copy-up gets an error from the dst branch
2098+fs, then aufs tries removing the just copied entry and returns the error
2099+to the userspace. The worst case of this situation will be all copy-up
2100+will fail.
2101+
2102+For the copy-up operation, there two basic approaches.
2103+- copy the specified XATTR only (by category above), and return the
7e9cd9fe 2104+ error unconditionally if it happens.
c1595e42
JR
2105+- copy all XATTR, and ignore the error on the specified category only.
2106+
2107+In order to support XATTR and to implement the correct behaviour, aufs
7e9cd9fe
AM
2108+chooses the latter approach and introduces some new branch attributes,
2109+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
c1595e42 2110+They correspond to the XATTR namespaces (see above). Additionally, to be
7e9cd9fe
AM
2111+convenient, "icex" is also provided which means all "icex*" attributes
2112+are set (here the word "icex" stands for "ignore copy-error on XATTR").
c1595e42
JR
2113+
2114+The meaning of these attributes is to ignore the error from setting
2115+XATTR on that branch.
2116+Note that aufs tries copying all XATTR unconditionally, and ignores the
2117+error from the dst branch according to the specified attributes.
2118+
2119+Some XATTR may have its default value. The default value may come from
2120+the parent dir or the environment. If the default value is set at the
2121+file creating-time, it will be overwritten by copy-up.
2122+Some contradiction may happen I am afraid.
2123+Do we need another attribute to stop copying XATTR? I am unsure. For
2124+now, aufs implements the branch attributes to ignore the error.
53392da6
AM
2125diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
2126--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 2127+++ linux/Documentation/filesystems/aufs/design/07export.txt 2015-09-24 10:47:58.248052907 +0200
523b37e3 2128@@ -0,0 +1,58 @@
53392da6 2129+
2000de60 2130+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
2131+#
2132+# This program is free software; you can redistribute it and/or modify
2133+# it under the terms of the GNU General Public License as published by
2134+# the Free Software Foundation; either version 2 of the License, or
2135+# (at your option) any later version.
2136+#
2137+# This program is distributed in the hope that it will be useful,
2138+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2139+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2140+# GNU General Public License for more details.
2141+#
2142+# You should have received a copy of the GNU General Public License
523b37e3 2143+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2144+
2145+Export Aufs via NFS
2146+----------------------------------------------------------------------
2147+Here is an approach.
2148+- like xino/xib, add a new file 'xigen' which stores aufs inode
2149+ generation.
2150+- iget_locked(): initialize aufs inode generation for a new inode, and
2151+ store it in xigen file.
2152+- destroy_inode(): increment aufs inode generation and store it in xigen
2153+ file. it is necessary even if it is not unlinked, because any data of
2154+ inode may be changed by UDBA.
2155+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
2156+ build file handle by
2157+ + branch id (4 bytes)
2158+ + superblock generation (4 bytes)
2159+ + inode number (4 or 8 bytes)
2160+ + parent dir inode number (4 or 8 bytes)
2161+ + inode generation (4 bytes))
2162+ + return value of exportfs_encode_fh() for the parent on a branch (4
2163+ bytes)
2164+ + file handle for a branch (by exportfs_encode_fh())
2165+- fh_to_dentry():
2166+ + find the index of a branch from its id in handle, and check it is
2167+ still exist in aufs.
2168+ + 1st level: get the inode number from handle and search it in cache.
7e9cd9fe
AM
2169+ + 2nd level: if not found in cache, get the parent inode number from
2170+ the handle and search it in cache. and then open the found parent
2171+ dir, find the matching inode number by vfs_readdir() and get its
2172+ name, and call lookup_one_len() for the target dentry.
53392da6
AM
2173+ + 3rd level: if the parent dir is not cached, call
2174+ exportfs_decode_fh() for a branch and get the parent on a branch,
2175+ build a pathname of it, convert it a pathname in aufs, call
2176+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
2177+ the 2nd level.
2178+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
2179+ for every branch, but not itself. to get this, (currently) aufs
2180+ searches in current->nsproxy->mnt_ns list. it may not be a good
2181+ idea, but I didn't get other approach.
2182+ + test the generation of the gotten inode.
2183+- every inode operation: they may get EBUSY due to UDBA. in this case,
2184+ convert it into ESTALE for NFSD.
2185+- readdir(): call lockdep_on/off() because filldir in NFSD calls
2186+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
2187diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
2188--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 2189+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2015-09-24 10:47:58.248052907 +0200
523b37e3 2190@@ -0,0 +1,52 @@
53392da6 2191+
2000de60 2192+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
2193+#
2194+# This program is free software; you can redistribute it and/or modify
2195+# it under the terms of the GNU General Public License as published by
2196+# the Free Software Foundation; either version 2 of the License, or
2197+# (at your option) any later version.
2198+#
2199+# This program is distributed in the hope that it will be useful,
2200+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2201+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2202+# GNU General Public License for more details.
2203+#
2204+# You should have received a copy of the GNU General Public License
523b37e3 2205+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2206+
2207+Show Whiteout Mode (shwh)
2208+----------------------------------------------------------------------
2209+Generally aufs hides the name of whiteouts. But in some cases, to show
2210+them is very useful for users. For instance, creating a new middle layer
2211+(branch) by merging existing layers.
2212+
2213+(borrowing aufs1 HOW-TO from a user, Michael Towers)
2214+When you have three branches,
2215+- Bottom: 'system', squashfs (underlying base system), read-only
2216+- Middle: 'mods', squashfs, read-only
2217+- Top: 'overlay', ram (tmpfs), read-write
2218+
2219+The top layer is loaded at boot time and saved at shutdown, to preserve
2220+the changes made to the system during the session.
2221+When larger changes have been made, or smaller changes have accumulated,
2222+the size of the saved top layer data grows. At this point, it would be
2223+nice to be able to merge the two overlay branches ('mods' and 'overlay')
2224+and rewrite the 'mods' squashfs, clearing the top layer and thus
2225+restoring save and load speed.
2226+
2227+This merging is simplified by the use of another aufs mount, of just the
2228+two overlay branches using the 'shwh' option.
2229+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
2230+ aufs /livesys/merge_union
2231+
2232+A merged view of these two branches is then available at
2233+/livesys/merge_union, and the new feature is that the whiteouts are
2234+visible!
2235+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
2236+writing to all branches. Also the default mode for all branches is 'ro'.
2237+It is now possible to save the combined contents of the two overlay
2238+branches to a new squashfs, e.g.:
2239+# mksquashfs /livesys/merge_union /path/to/newmods.squash
2240+
2241+This new squashfs archive can be stored on the boot device and the
2242+initramfs will use it to replace the old one at the next boot.
2243diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
2244--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 2245+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2015-09-24 10:47:58.248052907 +0200
7e9cd9fe 2246@@ -0,0 +1,47 @@
53392da6 2247+
2000de60 2248+# Copyright (C) 2010-2015 Junjiro R. Okajima
53392da6
AM
2249+#
2250+# This program is free software; you can redistribute it and/or modify
2251+# it under the terms of the GNU General Public License as published by
2252+# the Free Software Foundation; either version 2 of the License, or
2253+# (at your option) any later version.
2254+#
2255+# This program is distributed in the hope that it will be useful,
2256+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2257+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2258+# GNU General Public License for more details.
2259+#
2260+# You should have received a copy of the GNU General Public License
523b37e3 2261+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2262+
2263+Dynamically customizable FS operations
2264+----------------------------------------------------------------------
2265+Generally FS operations (struct inode_operations, struct
2266+address_space_operations, struct file_operations, etc.) are defined as
2267+"static const", but it never means that FS have only one set of
2268+operation. Some FS have multiple sets of them. For instance, ext2 has
2269+three sets, one for XIP, for NOBH, and for normal.
2270+Since aufs overrides and redirects these operations, sometimes aufs has
7e9cd9fe 2271+to change its behaviour according to the branch FS type. More importantly
53392da6
AM
2272+VFS acts differently if a function (member in the struct) is set or
2273+not. It means aufs should have several sets of operations and select one
2274+among them according to the branch FS definition.
2275+
7e9cd9fe 2276+In order to solve this problem and not to affect the behaviour of VFS,
53392da6 2277+aufs defines these operations dynamically. For instance, aufs defines
7e9cd9fe
AM
2278+dummy direct_IO function for struct address_space_operations, but it may
2279+not be set to the address_space_operations actually. When the branch FS
2280+doesn't have it, aufs doesn't set it to its address_space_operations
2281+while the function definition itself is still alive. So the behaviour
2282+itself will not change, and it will return an error when direct_IO is
2283+not set.
53392da6
AM
2284+
2285+The lifetime of these dynamically generated operation object is
2286+maintained by aufs branch object. When the branch is removed from aufs,
2287+the reference counter of the object is decremented. When it reaches
2288+zero, the dynamically generated operation object will be freed.
2289+
7e9cd9fe
AM
2290+This approach is designed to support AIO (io_submit), Direct I/O and
2291+XIP (DAX) mainly.
2292+Currently this approach is applied to address_space_operations for
2293+regular files only.
53392da6
AM
2294diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
2295--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 2296+++ linux/Documentation/filesystems/aufs/README 2015-09-24 10:47:58.244719488 +0200
5527c038 2297@@ -0,0 +1,383 @@
53392da6 2298+
5527c038 2299+Aufs4 -- advanced multi layered unification filesystem version 4.x
53392da6
AM
2300+http://aufs.sf.net
2301+Junjiro R. Okajima
2302+
2303+
2304+0. Introduction
2305+----------------------------------------
2306+In the early days, aufs was entirely re-designed and re-implemented
7e9cd9fe 2307+Unionfs Version 1.x series. Adding many original ideas, approaches,
53392da6
AM
2308+improvements and implementations, it becomes totally different from
2309+Unionfs while keeping the basic features.
2310+Recently, Unionfs Version 2.x series begin taking some of the same
2311+approaches to aufs1's.
2312+Unionfs is being developed by Professor Erez Zadok at Stony Brook
2313+University and his team.
2314+
5527c038 2315+Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3.
53392da6
AM
2316+If you want older kernel version support, try aufs2-2.6.git or
2317+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
2318+
2319+Note: it becomes clear that "Aufs was rejected. Let's give it up."
38d290e6
JR
2320+ According to Christoph Hellwig, linux rejects all union-type
2321+ filesystems but UnionMount.
53392da6
AM
2322+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
2323+
38d290e6
JR
2324+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
2325+ UnionMount, and he pointed out an issue around a directory mutex
2326+ lock and aufs addressed it. But it is still unsure whether aufs will
2327+ be merged (or any other union solution).
076b876e 2328+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
38d290e6 2329+
53392da6
AM
2330+
2331+1. Features
2332+----------------------------------------
2333+- unite several directories into a single virtual filesystem. The member
2334+ directory is called as a branch.
2335+- you can specify the permission flags to the branch, which are 'readonly',
2336+ 'readwrite' and 'whiteout-able.'
2337+- by upper writable branch, internal copyup and whiteout, files/dirs on
2338+ readonly branch are modifiable logically.
2339+- dynamic branch manipulation, add, del.
2340+- etc...
2341+
7e9cd9fe
AM
2342+Also there are many enhancements in aufs, such as:
2343+- test only the highest one for the directory permission (dirperm1)
2344+- copyup on open (coo=)
2345+- 'move' policy for copy-up between two writable branches, after
2346+ checking free space.
2347+- xattr, acl
53392da6
AM
2348+- readdir(3) in userspace.
2349+- keep inode number by external inode number table
2350+- keep the timestamps of file/dir in internal copyup operation
2351+- seekable directory, supporting NFS readdir.
2352+- whiteout is hardlinked in order to reduce the consumption of inodes
2353+ on branch
2354+- do not copyup, nor create a whiteout when it is unnecessary
2355+- revert a single systemcall when an error occurs in aufs
2356+- remount interface instead of ioctl
2357+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
2358+- loopback mounted filesystem as a branch
2359+- kernel thread for removing the dir who has a plenty of whiteouts
2360+- support copyup sparse file (a file which has a 'hole' in it)
2361+- default permission flags for branches
2362+- selectable permission flags for ro branch, whether whiteout can
2363+ exist or not
2364+- export via NFS.
2365+- support <sysfs>/fs/aufs and <debugfs>/aufs.
2366+- support multiple writable branches, some policies to select one
2367+ among multiple writable branches.
2368+- a new semantics for link(2) and rename(2) to support multiple
2369+ writable branches.
2370+- no glibc changes are required.
2371+- pseudo hardlink (hardlink over branches)
2372+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
2373+ including NFS or remote filesystem branch.
2374+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
2375+- and more...
2376+
5527c038 2377+Currently these features are dropped temporary from aufs4.
53392da6 2378+See design/08plan.txt in detail.
53392da6
AM
2379+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
2380+ (robr)
2381+- statistics of aufs thread (/sys/fs/aufs/stat)
53392da6
AM
2382+
2383+Features or just an idea in the future (see also design/*.txt),
2384+- reorder the branch index without del/re-add.
2385+- permanent xino files for NFSD
2386+- an option for refreshing the opened files after add/del branches
53392da6
AM
2387+- light version, without branch manipulation. (unnecessary?)
2388+- copyup in userspace
2389+- inotify in userspace
2390+- readv/writev
53392da6
AM
2391+
2392+
2393+2. Download
2394+----------------------------------------
5527c038
JR
2395+There are three GIT trees for aufs4, aufs4-linux.git,
2396+aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in
1e00d052 2397+"aufs-util.git."
5527c038
JR
2398+While the aufs-util is always necessary, you need either of aufs4-linux
2399+or aufs4-standalone.
1e00d052 2400+
5527c038 2401+The aufs4-linux tree includes the whole linux mainline GIT tree,
1e00d052
AM
2402+git://git.kernel.org/.../torvalds/linux.git.
2403+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
5527c038 2404+build aufs4 as an external kernel module.
2000de60 2405+Several extra patches are not included in this tree. Only
5527c038 2406+aufs4-standalone tree contains them. They are describe in the later
2000de60 2407+section "Configuration and Compilation."
1e00d052 2408+
5527c038 2409+On the other hand, the aufs4-standalone tree has only aufs source files
53392da6 2410+and necessary patches, and you can select CONFIG_AUFS_FS=m.
2000de60 2411+But you need to apply all aufs patches manually.
53392da6 2412+
5527c038
JR
2413+You will find GIT branches whose name is in form of "aufs4.x" where "x"
2414+represents the linux kernel version, "linux-4.x". For instance,
2415+"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use
2416+"aufs4.x-rcN" branch.
1e00d052 2417+
5527c038 2418+o aufs4-linux tree
1e00d052 2419+$ git clone --reference /your/linux/git/tree \
5527c038 2420+ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git
1e00d052 2421+- if you don't have linux GIT tree, then remove "--reference ..."
5527c038
JR
2422+$ cd aufs4-linux.git
2423+$ git checkout origin/aufs4.0
53392da6 2424+
2000de60
JR
2425+Or You may want to directly git-pull aufs into your linux GIT tree, and
2426+leave the patch-work to GIT.
2427+$ cd /your/linux/git/tree
5527c038
JR
2428+$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git
2429+$ git fetch aufs4
2430+$ git checkout -b my4.0 v4.0
2431+$ (add your local change...)
2432+$ git pull aufs4 aufs4.0
2433+- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch.
2000de60 2434+- you may need to solve some conflicts between your_changes and
5527c038
JR
2435+ aufs4.0. in this case, git-rerere is recommended so that you can
2436+ solve the similar conflicts automatically when you upgrade to 4.1 or
2000de60
JR
2437+ later in the future.
2438+
5527c038
JR
2439+o aufs4-standalone tree
2440+$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git
2441+$ cd aufs4-standalone.git
2442+$ git checkout origin/aufs4.0
53392da6
AM
2443+
2444+o aufs-util tree
5527c038
JR
2445+$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git
2446+- note that the public aufs-util.git is on SourceForge instead of
2447+ GitHUB.
53392da6 2448+$ cd aufs-util.git
5527c038 2449+$ git checkout origin/aufs4.0
53392da6 2450+
5527c038
JR
2451+Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY.
2452+The minor version number, 'x' in '4.x', of aufs may not always
9dbd164d
AM
2453+follow the minor version number of the kernel.
2454+Because changes in the kernel that cause the use of a new
2455+minor version number do not always require changes to aufs-util.
2456+
2457+Since aufs-util has its own minor version number, you may not be
2458+able to find a GIT branch in aufs-util for your kernel's
2459+exact minor version number.
2460+In this case, you should git-checkout the branch for the
53392da6 2461+nearest lower number.
9dbd164d
AM
2462+
2463+For (an unreleased) example:
5527c038
JR
2464+If you are using "linux-4.10" and the "aufs4.10" branch
2465+does not exist in aufs-util repository, then "aufs4.9", "aufs4.8"
9dbd164d
AM
2466+or something numerically smaller is the branch for your kernel.
2467+
53392da6
AM
2468+Also you can view all branches by
2469+ $ git branch -a
2470+
2471+
2472+3. Configuration and Compilation
2473+----------------------------------------
2474+Make sure you have git-checkout'ed the correct branch.
2475+
5527c038 2476+For aufs4-linux tree,
c06a8ce3 2477+- enable CONFIG_AUFS_FS.
1e00d052
AM
2478+- set other aufs configurations if necessary.
2479+
5527c038 2480+For aufs4-standalone tree,
53392da6
AM
2481+There are several ways to build.
2482+
2483+1.
5527c038
JR
2484+- apply ./aufs4-kbuild.patch to your kernel source files.
2485+- apply ./aufs4-base.patch too.
2486+- apply ./aufs4-mmap.patch too.
2487+- apply ./aufs4-standalone.patch too, if you have a plan to set
2488+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch.
537831f9
AM
2489+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2490+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 2491+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
2492+ =m or =y.
2493+- and build your kernel as usual.
2494+- install the built kernel.
c06a8ce3
AM
2495+ Note: Since linux-3.9, every filesystem module requires an alias
2496+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2497+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
2498+- install the header files too by "make headers_install" to the
2499+ directory where you specify. By default, it is $PWD/usr.
b4510431 2500+ "make help" shows a brief note for headers_install.
53392da6
AM
2501+- and reboot your system.
2502+
2503+2.
2504+- module only (CONFIG_AUFS_FS=m).
5527c038
JR
2505+- apply ./aufs4-base.patch to your kernel source files.
2506+- apply ./aufs4-mmap.patch too.
2507+- apply ./aufs4-standalone.patch too.
53392da6
AM
2508+- build your kernel, don't forget "make headers_install", and reboot.
2509+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 2510+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
2511+ every aufs configurations.
2512+- build the module by simple "make".
c06a8ce3
AM
2513+ Note: Since linux-3.9, every filesystem module requires an alias
2514+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2515+ modules.aliases file.
53392da6
AM
2516+- you can specify ${KDIR} make variable which points to your kernel
2517+ source tree.
2518+- install the files
2519+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
2520+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2521+ + run "make install_headers" (instead of headers_install) to install
2522+ the modified aufs header file (you can specify DESTDIR which is
2523+ available in aufs standalone version's Makefile only), or copy
2524+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2525+ you like manually. By default, the target directory is $PWD/usr.
5527c038 2526+- no need to apply aufs4-kbuild.patch, nor copying source files to your
53392da6
AM
2527+ kernel source tree.
2528+
b4510431 2529+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
2530+ as well as "make headers_install" in the kernel source tree.
2531+ headers_install is subject to be forgotten, but it is essentially
2532+ necessary, not only for building aufs-util.
2533+ You may not meet problems without headers_install in some older
2534+ version though.
2535+
2536+And then,
2537+- read README in aufs-util, build and install it
9dbd164d
AM
2538+- note that your distribution may contain an obsoleted version of
2539+ aufs_type.h in /usr/include/linux or something. When you build aufs
2540+ utilities, make sure that your compiler refers the correct aufs header
2541+ file which is built by "make headers_install."
53392da6
AM
2542+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2543+ then run "make install_ulib" too. And refer to the aufs manual in
2544+ detail.
2545+
5527c038 2546+There several other patches in aufs4-standalone.git. They are all
38d290e6 2547+optional. When you meet some problems, they will help you.
5527c038 2548+- aufs4-loopback.patch
38d290e6
JR
2549+ Supports a nested loopback mount in a branch-fs. This patch is
2550+ unnecessary until aufs produces a message like "you may want to try
2551+ another patch for loopback file".
2552+- vfs-ino.patch
2553+ Modifies a system global kernel internal function get_next_ino() in
2554+ order to stop assigning 0 for an inode-number. Not directly related to
2555+ aufs, but recommended generally.
2556+- tmpfs-idr.patch
2557+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
2558+ the size of aufs XINO files for tmpfs branch. Also it prevents the
2559+ duplication of inode number, which is important for backup tools and
2560+ other utilities. When you find aufs XINO files for tmpfs branch
2561+ growing too much, try this patch.
2562+
53392da6
AM
2563+
2564+4. Usage
2565+----------------------------------------
2566+At first, make sure aufs-util are installed, and please read the aufs
2567+manual, aufs.5 in aufs-util.git tree.
2568+$ man -l aufs.5
2569+
2570+And then,
2571+$ mkdir /tmp/rw /tmp/aufs
2572+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2573+
2574+Here is another example. The result is equivalent.
2575+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2576+ Or
2577+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2578+# mount -o remount,append:${HOME} /tmp/aufs
2579+
2580+Then, you can see whole tree of your home dir through /tmp/aufs. If
2581+you modify a file under /tmp/aufs, the one on your home directory is
2582+not affected, instead the same named file will be newly created under
2583+/tmp/rw. And all of your modification to a file will be applied to
2584+the one under /tmp/rw. This is called the file based Copy on Write
2585+(COW) method.
2586+Aufs mount options are described in aufs.5.
2587+If you run chroot or something and make your aufs as a root directory,
2588+then you need to customize the shutdown script. See the aufs manual in
2589+detail.
2590+
2591+Additionally, there are some sample usages of aufs which are a
2592+diskless system with network booting, and LiveCD over NFS.
2593+See sample dir in CVS tree on SourceForge.
2594+
2595+
2596+5. Contact
2597+----------------------------------------
2598+When you have any problems or strange behaviour in aufs, please let me
2599+know with:
2600+- /proc/mounts (instead of the output of mount(8))
2601+- /sys/module/aufs/*
2602+- /sys/fs/aufs/* (if you have them)
2603+- /debug/aufs/* (if you have them)
2604+- linux kernel version
2605+ if your kernel is not plain, for example modified by distributor,
2606+ the url where i can download its source is necessary too.
2607+- aufs version which was printed at loading the module or booting the
2608+ system, instead of the date you downloaded.
2609+- configuration (define/undefine CONFIG_AUFS_xxx)
2610+- kernel configuration or /proc/config.gz (if you have it)
2611+- behaviour which you think to be incorrect
2612+- actual operation, reproducible one is better
2613+- mailto: aufs-users at lists.sourceforge.net
2614+
2615+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2616+and Feature Requests) on SourceForge. Please join and write to
2617+aufs-users ML.
2618+
2619+
2620+6. Acknowledgements
2621+----------------------------------------
2622+Thanks to everyone who have tried and are using aufs, whoever
2623+have reported a bug or any feedback.
2624+
2625+Especially donators:
2626+Tomas Matejicek(slax.org) made a donation (much more than once).
2627+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2628+ scripts) is making "doubling" donations.
2629+ Unfortunately I cannot list all of the donators, but I really
b4510431 2630+ appreciate.
53392da6
AM
2631+ It ends Aug 2010, but the ordinary donation URL is still available.
2632+ <http://sourceforge.net/donate/index.php?group_id=167503>
2633+Dai Itasaka made a donation (2007/8).
2634+Chuck Smith made a donation (2008/4, 10 and 12).
2635+Henk Schoneveld made a donation (2008/9).
2636+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
2637+Francois Dupoux made a donation (2008/11).
2638+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
2639+ aufs2 GIT tree (2009/2).
2640+William Grant made a donation (2009/3).
2641+Patrick Lane made a donation (2009/4).
2642+The Mail Archive (mail-archive.com) made donations (2009/5).
2643+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
2644+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
2645+Pavel Pronskiy made a donation (2011/2).
2646+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
2647+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
2648+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
2649+11).
1e00d052 2650+Sam Liddicott made a donation (2011/9).
86dc4139
AM
2651+Era Scarecrow made a donation (2013/4).
2652+Bor Ratajc made a donation (2013/4).
2653+Alessandro Gorreta made a donation (2013/4).
2654+POIRETTE Marc made a donation (2013/4).
2655+Alessandro Gorreta made a donation (2013/4).
2656+lauri kasvandik made a donation (2013/5).
392086de 2657+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
2658+The Parted Magic Project made a donation (2013/9 and 11).
2659+Pavel Barta made a donation (2013/10).
38d290e6 2660+Nikolay Pertsev made a donation (2014/5).
c2c0f25c 2661+James B made a donation (2014/7 and 2015/7).
076b876e 2662+Stefano Di Biase made a donation (2014/8).
2000de60 2663+Daniel Epellei made a donation (2015/1).
53392da6
AM
2664+
2665+Thank you very much.
2666+Donations are always, including future donations, very important and
2667+helpful for me to keep on developing aufs.
2668+
2669+
2670+7.
2671+----------------------------------------
2672+If you are an experienced user, no explanation is needed. Aufs is
2673+just a linux filesystem.
2674+
2675+
2676+Enjoy!
2677+
2678+# Local variables: ;
2679+# mode: text;
2680+# End: ;
7f207e10
AM
2681diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
2682--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 2683+++ linux/fs/aufs/aufs.h 2015-09-24 10:47:58.248052907 +0200
523b37e3 2684@@ -0,0 +1,59 @@
7f207e10 2685+/*
2000de60 2686+ * Copyright (C) 2005-2015 Junjiro R. Okajima
7f207e10
AM
2687+ *
2688+ * This program, aufs is free software; you can redistribute it and/or modify
2689+ * it under the terms of the GNU General Public License as published by
2690+ * the Free Software Foundation; either version 2 of the License, or
2691+ * (at your option) any later version.
2692+ *
2693+ * This program is distributed in the hope that it will be useful,
2694+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2695+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2696+ * GNU General Public License for more details.
2697+ *
2698+ * You should have received a copy of the GNU General Public License
523b37e3 2699+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2700+ */
2701+
2702+/*
2703+ * all header files
2704+ */
2705+
2706+#ifndef __AUFS_H__
2707+#define __AUFS_H__
2708+
2709+#ifdef __KERNEL__
2710+
2711+#define AuStub(type, name, body, ...) \
2712+ static inline type name(__VA_ARGS__) { body; }
2713+
2714+#define AuStubVoid(name, ...) \
2715+ AuStub(void, name, , __VA_ARGS__)
2716+#define AuStubInt0(name, ...) \
2717+ AuStub(int, name, return 0, __VA_ARGS__)
2718+
2719+#include "debug.h"
2720+
2721+#include "branch.h"
2722+#include "cpup.h"
2723+#include "dcsub.h"
2724+#include "dbgaufs.h"
2725+#include "dentry.h"
2726+#include "dir.h"
2727+#include "dynop.h"
2728+#include "file.h"
2729+#include "fstype.h"
2730+#include "inode.h"
2731+#include "loop.h"
2732+#include "module.h"
7f207e10
AM
2733+#include "opts.h"
2734+#include "rwsem.h"
2735+#include "spl.h"
2736+#include "super.h"
2737+#include "sysaufs.h"
2738+#include "vfsub.h"
2739+#include "whout.h"
2740+#include "wkq.h"
2741+
2742+#endif /* __KERNEL__ */
2743+#endif /* __AUFS_H__ */
2744diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
2745--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
2746+++ linux/fs/aufs/branch.c 2015-11-11 17:21:46.915530388 +0100
2747@@ -0,0 +1,1413 @@
7f207e10 2748+/*
2000de60 2749+ * Copyright (C) 2005-2015 Junjiro R. Okajima
7f207e10
AM
2750+ *
2751+ * This program, aufs is free software; you can redistribute it and/or modify
2752+ * it under the terms of the GNU General Public License as published by
2753+ * the Free Software Foundation; either version 2 of the License, or
2754+ * (at your option) any later version.
2755+ *
2756+ * This program is distributed in the hope that it will be useful,
2757+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2758+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2759+ * GNU General Public License for more details.
2760+ *
2761+ * You should have received a copy of the GNU General Public License
523b37e3 2762+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2763+ */
2764+
2765+/*
2766+ * branch management
2767+ */
2768+
027c5e7a 2769+#include <linux/compat.h>
7f207e10
AM
2770+#include <linux/statfs.h>
2771+#include "aufs.h"
2772+
2773+/*
2774+ * free a single branch
1facf9fc 2775+ */
2776+static void au_br_do_free(struct au_branch *br)
2777+{
2778+ int i;
2779+ struct au_wbr *wbr;
4a4d8108 2780+ struct au_dykey **key;
1facf9fc 2781+
027c5e7a
AM
2782+ au_hnotify_fin_br(br);
2783+
1facf9fc 2784+ if (br->br_xino.xi_file)
2785+ fput(br->br_xino.xi_file);
2786+ mutex_destroy(&br->br_xino.xi_nondir_mtx);
2787+
2788+ AuDebugOn(atomic_read(&br->br_count));
2789+
2790+ wbr = br->br_wbr;
2791+ if (wbr) {
2792+ for (i = 0; i < AuBrWh_Last; i++)
2793+ dput(wbr->wbr_wh[i]);
2794+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 2795+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 2796+ }
2797+
076b876e
AM
2798+ if (br->br_fhsm) {
2799+ au_br_fhsm_fin(br->br_fhsm);
2800+ kfree(br->br_fhsm);
2801+ }
2802+
4a4d8108
AM
2803+ key = br->br_dykey;
2804+ for (i = 0; i < AuBrDynOp; i++, key++)
2805+ if (*key)
2806+ au_dy_put(*key);
2807+ else
2808+ break;
2809+
537831f9
AM
2810+ /* recursive lock, s_umount of branch's */
2811+ lockdep_off();
86dc4139 2812+ path_put(&br->br_path);
537831f9 2813+ lockdep_on();
1facf9fc 2814+ kfree(wbr);
2815+ kfree(br);
2816+}
2817+
2818+/*
2819+ * frees all branches
2820+ */
2821+void au_br_free(struct au_sbinfo *sbinfo)
2822+{
2823+ aufs_bindex_t bmax;
2824+ struct au_branch **br;
2825+
dece6358
AM
2826+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2827+
1facf9fc 2828+ bmax = sbinfo->si_bend + 1;
2829+ br = sbinfo->si_branch;
2830+ while (bmax--)
2831+ au_br_do_free(*br++);
2832+}
2833+
2834+/*
2835+ * find the index of a branch which is specified by @br_id.
2836+ */
2837+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2838+{
2839+ aufs_bindex_t bindex, bend;
2840+
2841+ bend = au_sbend(sb);
2842+ for (bindex = 0; bindex <= bend; bindex++)
2843+ if (au_sbr_id(sb, bindex) == br_id)
2844+ return bindex;
2845+ return -1;
2846+}
2847+
2848+/* ---------------------------------------------------------------------- */
2849+
2850+/*
2851+ * add a branch
2852+ */
2853+
b752ccd1
AM
2854+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2855+ struct dentry *h_root)
1facf9fc 2856+{
b752ccd1
AM
2857+ if (unlikely(h_adding == h_root
2858+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 2859+ return 1;
b752ccd1
AM
2860+ if (h_adding->d_sb != h_root->d_sb)
2861+ return 0;
2862+ return au_test_subdir(h_adding, h_root)
2863+ || au_test_subdir(h_root, h_adding);
1facf9fc 2864+}
2865+
2866+/*
2867+ * returns a newly allocated branch. @new_nbranch is a number of branches
2868+ * after adding a branch.
2869+ */
2870+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
2871+ int perm)
2872+{
2873+ struct au_branch *add_branch;
2874+ struct dentry *root;
5527c038 2875+ struct inode *inode;
4a4d8108 2876+ int err;
1facf9fc 2877+
4a4d8108 2878+ err = -ENOMEM;
1facf9fc 2879+ root = sb->s_root;
2880+ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2881+ if (unlikely(!add_branch))
2882+ goto out;
2883+
027c5e7a
AM
2884+ err = au_hnotify_init_br(add_branch, perm);
2885+ if (unlikely(err))
2886+ goto out_br;
2887+
1facf9fc 2888+ add_branch->br_wbr = NULL;
2889+ if (au_br_writable(perm)) {
2890+ /* may be freed separately at changing the branch permission */
2891+ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
2892+ GFP_NOFS);
2893+ if (unlikely(!add_branch->br_wbr))
027c5e7a 2894+ goto out_hnotify;
1facf9fc 2895+ }
2896+
076b876e
AM
2897+ add_branch->br_fhsm = NULL;
2898+ if (au_br_fhsm(perm)) {
2899+ err = au_fhsm_br_alloc(add_branch);
2900+ if (unlikely(err))
2901+ goto out_wbr;
2902+ }
2903+
4a4d8108
AM
2904+ err = au_sbr_realloc(au_sbi(sb), new_nbranch);
2905+ if (!err)
2906+ err = au_di_realloc(au_di(root), new_nbranch);
5527c038
JR
2907+ if (!err) {
2908+ inode = d_inode(root);
2909+ err = au_ii_realloc(au_ii(inode), new_nbranch);
2910+ }
4a4d8108
AM
2911+ if (!err)
2912+ return add_branch; /* success */
1facf9fc 2913+
076b876e 2914+out_wbr:
1facf9fc 2915+ kfree(add_branch->br_wbr);
027c5e7a
AM
2916+out_hnotify:
2917+ au_hnotify_fin_br(add_branch);
4f0767ce 2918+out_br:
1facf9fc 2919+ kfree(add_branch);
4f0767ce 2920+out:
4a4d8108 2921+ return ERR_PTR(err);
1facf9fc 2922+}
2923+
2924+/*
2925+ * test if the branch permission is legal or not.
2926+ */
2927+static int test_br(struct inode *inode, int brperm, char *path)
2928+{
2929+ int err;
2930+
4a4d8108
AM
2931+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
2932+ if (!err)
2933+ goto out;
1facf9fc 2934+
4a4d8108
AM
2935+ err = -EINVAL;
2936+ pr_err("write permission for readonly mount or inode, %s\n", path);
2937+
4f0767ce 2938+out:
1facf9fc 2939+ return err;
2940+}
2941+
2942+/*
2943+ * returns:
2944+ * 0: success, the caller will add it
2945+ * plus: success, it is already unified, the caller should ignore it
2946+ * minus: error
2947+ */
2948+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2949+{
2950+ int err;
2951+ aufs_bindex_t bend, bindex;
5527c038 2952+ struct dentry *root, *h_dentry;
1facf9fc 2953+ struct inode *inode, *h_inode;
2954+
2955+ root = sb->s_root;
2956+ bend = au_sbend(sb);
2957+ if (unlikely(bend >= 0
2958+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
2959+ err = 1;
2960+ if (!remount) {
2961+ err = -EINVAL;
4a4d8108 2962+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 2963+ }
2964+ goto out;
2965+ }
2966+
2967+ err = -ENOSPC; /* -E2BIG; */
2968+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2969+ || AUFS_BRANCH_MAX - 1 <= bend)) {
4a4d8108 2970+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 2971+ goto out;
2972+ }
2973+
2974+ err = -EDOM;
2975+ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
4a4d8108 2976+ pr_err("bad index %d\n", add->bindex);
1facf9fc 2977+ goto out;
2978+ }
2979+
5527c038 2980+ inode = d_inode(add->path.dentry);
1facf9fc 2981+ err = -ENOENT;
2982+ if (unlikely(!inode->i_nlink)) {
4a4d8108 2983+ pr_err("no existence %s\n", add->pathname);
1facf9fc 2984+ goto out;
2985+ }
2986+
2987+ err = -EINVAL;
2988+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 2989+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 2990+ goto out;
2991+ }
2992+
2993+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
2994+ pr_err("unsupported filesystem, %s (%s)\n",
2995+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 2996+ goto out;
2997+ }
2998+
c1595e42
JR
2999+ if (unlikely(inode->i_sb->s_stack_depth)) {
3000+ pr_err("already stacked, %s (%s)\n",
3001+ add->pathname, au_sbtype(inode->i_sb));
3002+ goto out;
3003+ }
3004+
5527c038 3005+ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname);
1facf9fc 3006+ if (unlikely(err))
3007+ goto out;
3008+
3009+ if (bend < 0)
3010+ return 0; /* success */
3011+
3012+ err = -EINVAL;
3013+ for (bindex = 0; bindex <= bend; bindex++)
3014+ if (unlikely(test_overlap(sb, add->path.dentry,
3015+ au_h_dptr(root, bindex)))) {
4a4d8108 3016+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 3017+ goto out;
3018+ }
3019+
3020+ err = 0;
3021+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
5527c038
JR
3022+ h_dentry = au_h_dptr(root, 0);
3023+ h_inode = d_inode(h_dentry);
1facf9fc 3024+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
3025+ || !uid_eq(h_inode->i_uid, inode->i_uid)
3026+ || !gid_eq(h_inode->i_gid, inode->i_gid))
3027+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
3028+ add->pathname,
3029+ i_uid_read(inode), i_gid_read(inode),
3030+ (inode->i_mode & S_IALLUGO),
3031+ i_uid_read(h_inode), i_gid_read(h_inode),
3032+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 3033+ }
3034+
4f0767ce 3035+out:
1facf9fc 3036+ return err;
3037+}
3038+
3039+/*
3040+ * initialize or clean the whiteouts for an adding branch
3041+ */
3042+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 3043+ int new_perm)
1facf9fc 3044+{
3045+ int err, old_perm;
3046+ aufs_bindex_t bindex;
3047+ struct mutex *h_mtx;
3048+ struct au_wbr *wbr;
3049+ struct au_hinode *hdir;
5527c038 3050+ struct dentry *h_dentry;
1facf9fc 3051+
86dc4139
AM
3052+ err = vfsub_mnt_want_write(au_br_mnt(br));
3053+ if (unlikely(err))
3054+ goto out;
3055+
1facf9fc 3056+ wbr = br->br_wbr;
3057+ old_perm = br->br_perm;
3058+ br->br_perm = new_perm;
3059+ hdir = NULL;
3060+ h_mtx = NULL;
3061+ bindex = au_br_index(sb, br->br_id);
3062+ if (0 <= bindex) {
5527c038 3063+ hdir = au_hi(d_inode(sb->s_root), bindex);
4a4d8108 3064+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 3065+ } else {
5527c038
JR
3066+ h_dentry = au_br_dentry(br);
3067+ h_mtx = &d_inode(h_dentry)->i_mutex;
1facf9fc 3068+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
3069+ }
3070+ if (!wbr)
86dc4139 3071+ err = au_wh_init(br, sb);
1facf9fc 3072+ else {
3073+ wbr_wh_write_lock(wbr);
86dc4139 3074+ err = au_wh_init(br, sb);
1facf9fc 3075+ wbr_wh_write_unlock(wbr);
3076+ }
3077+ if (hdir)
4a4d8108 3078+ au_hn_imtx_unlock(hdir);
1facf9fc 3079+ else
3080+ mutex_unlock(h_mtx);
86dc4139 3081+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 3082+ br->br_perm = old_perm;
3083+
3084+ if (!err && wbr && !au_br_writable(new_perm)) {
3085+ kfree(wbr);
3086+ br->br_wbr = NULL;
3087+ }
3088+
86dc4139 3089+out:
1facf9fc 3090+ return err;
3091+}
3092+
3093+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 3094+ int perm)
1facf9fc 3095+{
3096+ int err;
4a4d8108 3097+ struct kstatfs kst;
1facf9fc 3098+ struct au_wbr *wbr;
3099+
3100+ wbr = br->br_wbr;
dece6358 3101+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 3102+ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
3103+ atomic_set(&wbr->wbr_wh_running, 0);
3104+ wbr->wbr_bytes = 0;
3105+
4a4d8108
AM
3106+ /*
3107+ * a limit for rmdir/rename a dir
523b37e3 3108+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 3109+ */
86dc4139 3110+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
3111+ if (unlikely(err))
3112+ goto out;
3113+ err = -EINVAL;
3114+ if (kst.f_namelen >= NAME_MAX)
86dc4139 3115+ err = au_br_init_wh(sb, br, perm);
4a4d8108 3116+ else
523b37e3
AM
3117+ pr_err("%pd(%s), unsupported namelen %ld\n",
3118+ au_br_dentry(br),
86dc4139 3119+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 3120+
4f0767ce 3121+out:
1facf9fc 3122+ return err;
3123+}
3124+
c1595e42 3125+/* initialize a new branch */
1facf9fc 3126+static int au_br_init(struct au_branch *br, struct super_block *sb,
3127+ struct au_opt_add *add)
3128+{
3129+ int err;
5527c038 3130+ struct inode *h_inode;
1facf9fc 3131+
3132+ err = 0;
3133+ memset(&br->br_xino, 0, sizeof(br->br_xino));
3134+ mutex_init(&br->br_xino.xi_nondir_mtx);
3135+ br->br_perm = add->perm;
86dc4139 3136+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108
AM
3137+ spin_lock_init(&br->br_dykey_lock);
3138+ memset(br->br_dykey, 0, sizeof(br->br_dykey));
1facf9fc 3139+ atomic_set(&br->br_count, 0);
1facf9fc 3140+ atomic_set(&br->br_xino_running, 0);
3141+ br->br_id = au_new_br_id(sb);
7f207e10 3142+ AuDebugOn(br->br_id < 0);
1facf9fc 3143+
3144+ if (au_br_writable(add->perm)) {
86dc4139 3145+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 3146+ if (unlikely(err))
b752ccd1 3147+ goto out_err;
1facf9fc 3148+ }
3149+
3150+ if (au_opt_test(au_mntflags(sb), XINO)) {
5527c038
JR
3151+ h_inode = d_inode(add->path.dentry);
3152+ err = au_xino_br(sb, br, h_inode->i_ino,
1facf9fc 3153+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
3154+ if (unlikely(err)) {
3155+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 3156+ goto out_err;
1facf9fc 3157+ }
3158+ }
3159+
3160+ sysaufs_br_init(br);
86dc4139 3161+ path_get(&br->br_path);
b752ccd1 3162+ goto out; /* success */
1facf9fc 3163+
4f0767ce 3164+out_err:
86dc4139 3165+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 3166+out:
1facf9fc 3167+ return err;
3168+}
3169+
3170+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
3171+ struct au_branch *br, aufs_bindex_t bend,
3172+ aufs_bindex_t amount)
3173+{
3174+ struct au_branch **brp;
3175+
dece6358
AM
3176+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3177+
1facf9fc 3178+ brp = sbinfo->si_branch + bindex;
3179+ memmove(brp + 1, brp, sizeof(*brp) * amount);
3180+ *brp = br;
3181+ sbinfo->si_bend++;
3182+ if (unlikely(bend < 0))
3183+ sbinfo->si_bend = 0;
3184+}
3185+
3186+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
3187+ aufs_bindex_t bend, aufs_bindex_t amount)
3188+{
3189+ struct au_hdentry *hdp;
3190+
1308ab2a 3191+ AuRwMustWriteLock(&dinfo->di_rwsem);
3192+
1facf9fc 3193+ hdp = dinfo->di_hdentry + bindex;
3194+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
3195+ au_h_dentry_init(hdp);
3196+ dinfo->di_bend++;
3197+ if (unlikely(bend < 0))
3198+ dinfo->di_bstart = 0;
3199+}
3200+
3201+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
3202+ aufs_bindex_t bend, aufs_bindex_t amount)
3203+{
3204+ struct au_hinode *hip;
3205+
1308ab2a 3206+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3207+
1facf9fc 3208+ hip = iinfo->ii_hinode + bindex;
3209+ memmove(hip + 1, hip, sizeof(*hip) * amount);
3210+ hip->hi_inode = NULL;
4a4d8108 3211+ au_hn_init(hip);
1facf9fc 3212+ iinfo->ii_bend++;
3213+ if (unlikely(bend < 0))
3214+ iinfo->ii_bstart = 0;
3215+}
3216+
86dc4139
AM
3217+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
3218+ aufs_bindex_t bindex)
1facf9fc 3219+{
86dc4139 3220+ struct dentry *root, *h_dentry;
5527c038 3221+ struct inode *root_inode, *h_inode;
1facf9fc 3222+ aufs_bindex_t bend, amount;
3223+
3224+ root = sb->s_root;
5527c038 3225+ root_inode = d_inode(root);
1facf9fc 3226+ bend = au_sbend(sb);
3227+ amount = bend + 1 - bindex;
86dc4139 3228+ h_dentry = au_br_dentry(br);
53392da6 3229+ au_sbilist_lock();
1facf9fc 3230+ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
3231+ au_br_do_add_hdp(au_di(root), bindex, bend, amount);
3232+ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
3233+ au_set_h_dptr(root, bindex, dget(h_dentry));
5527c038
JR
3234+ h_inode = d_inode(h_dentry);
3235+ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0);
53392da6 3236+ au_sbilist_unlock();
1facf9fc 3237+}
3238+
3239+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
3240+{
3241+ int err;
1facf9fc 3242+ aufs_bindex_t bend, add_bindex;
3243+ struct dentry *root, *h_dentry;
3244+ struct inode *root_inode;
3245+ struct au_branch *add_branch;
3246+
3247+ root = sb->s_root;
5527c038 3248+ root_inode = d_inode(root);
1facf9fc 3249+ IMustLock(root_inode);
3250+ err = test_add(sb, add, remount);
3251+ if (unlikely(err < 0))
3252+ goto out;
3253+ if (err) {
3254+ err = 0;
3255+ goto out; /* success */
3256+ }
3257+
3258+ bend = au_sbend(sb);
3259+ add_branch = au_br_alloc(sb, bend + 2, add->perm);
3260+ err = PTR_ERR(add_branch);
3261+ if (IS_ERR(add_branch))
3262+ goto out;
3263+
3264+ err = au_br_init(add_branch, sb, add);
3265+ if (unlikely(err)) {
3266+ au_br_do_free(add_branch);
3267+ goto out;
3268+ }
3269+
3270+ add_bindex = add->bindex;
1facf9fc 3271+ if (!remount)
86dc4139 3272+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3273+ else {
3274+ sysaufs_brs_del(sb, add_bindex);
86dc4139 3275+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3276+ sysaufs_brs_add(sb, add_bindex);
3277+ }
3278+
86dc4139 3279+ h_dentry = add->path.dentry;
1308ab2a 3280+ if (!add_bindex) {
1facf9fc 3281+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 3282+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
3283+ } else
5527c038 3284+ au_add_nlink(root_inode, d_inode(h_dentry));
1facf9fc 3285+
3286+ /*
4a4d8108 3287+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 3288+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 3289+ * once detached from aufs.
3290+ */
3291+ if (au_xino_brid(sb) < 0
3292+ && au_br_writable(add_branch->br_perm)
3293+ && !au_test_fs_bad_xino(h_dentry->d_sb)
3294+ && add_branch->br_xino.xi_file
2000de60 3295+ && add_branch->br_xino.xi_file->f_path.dentry->d_parent == h_dentry)
1facf9fc 3296+ au_xino_brid_set(sb, add_branch->br_id);
3297+
4f0767ce 3298+out:
1facf9fc 3299+ return err;
3300+}
3301+
3302+/* ---------------------------------------------------------------------- */
3303+
79b8bda9 3304+static unsigned long long au_farray_cb(struct super_block *sb, void *a,
076b876e
AM
3305+ unsigned long long max __maybe_unused,
3306+ void *arg)
3307+{
3308+ unsigned long long n;
3309+ struct file **p, *f;
3310+ struct au_sphlhead *files;
3311+ struct au_finfo *finfo;
076b876e
AM
3312+
3313+ n = 0;
3314+ p = a;
3315+ files = &au_sbi(sb)->si_files;
3316+ spin_lock(&files->spin);
3317+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
3318+ f = finfo->fi_file;
3319+ if (file_count(f)
3320+ && !special_file(file_inode(f)->i_mode)) {
3321+ get_file(f);
3322+ *p++ = f;
3323+ n++;
3324+ AuDebugOn(n > max);
3325+ }
3326+ }
3327+ spin_unlock(&files->spin);
3328+
3329+ return n;
3330+}
3331+
3332+static struct file **au_farray_alloc(struct super_block *sb,
3333+ unsigned long long *max)
3334+{
3335+ *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
79b8bda9 3336+ return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL);
076b876e
AM
3337+}
3338+
3339+static void au_farray_free(struct file **a, unsigned long long max)
3340+{
3341+ unsigned long long ull;
3342+
3343+ for (ull = 0; ull < max; ull++)
3344+ if (a[ull])
3345+ fput(a[ull]);
3346+ au_array_free(a);
3347+}
3348+
3349+/* ---------------------------------------------------------------------- */
3350+
1facf9fc 3351+/*
3352+ * delete a branch
3353+ */
3354+
3355+/* to show the line number, do not make it inlined function */
4a4d8108 3356+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 3357+ if (do_info) \
4a4d8108 3358+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 3359+} while (0)
3360+
027c5e7a
AM
3361+static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
3362+ aufs_bindex_t bend)
3363+{
3364+ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
3365+}
3366+
3367+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
3368+ aufs_bindex_t bend)
3369+{
5527c038 3370+ return au_test_ibusy(d_inode(dentry), bstart, bend);
027c5e7a
AM
3371+}
3372+
1facf9fc 3373+/*
3374+ * test if the branch is deletable or not.
3375+ */
3376+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 3377+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3378+{
3379+ int err, i, j, ndentry;
3380+ aufs_bindex_t bstart, bend;
1facf9fc 3381+ struct au_dcsub_pages dpages;
3382+ struct au_dpage *dpage;
3383+ struct dentry *d;
1facf9fc 3384+
3385+ err = au_dpages_init(&dpages, GFP_NOFS);
3386+ if (unlikely(err))
3387+ goto out;
3388+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
3389+ if (unlikely(err))
3390+ goto out_dpages;
3391+
1facf9fc 3392+ for (i = 0; !err && i < dpages.ndpage; i++) {
3393+ dpage = dpages.dpages + i;
3394+ ndentry = dpage->ndentry;
3395+ for (j = 0; !err && j < ndentry; j++) {
3396+ d = dpage->dentries[j];
c1595e42 3397+ AuDebugOn(au_dcount(d) <= 0);
027c5e7a 3398+ if (!au_digen_test(d, sigen)) {
1facf9fc 3399+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
3400+ if (unlikely(au_dbrange_test(d))) {
3401+ di_read_unlock(d, AuLock_IR);
3402+ continue;
3403+ }
3404+ } else {
1facf9fc 3405+ di_write_lock_child(d);
027c5e7a
AM
3406+ if (unlikely(au_dbrange_test(d))) {
3407+ di_write_unlock(d);
3408+ continue;
3409+ }
1facf9fc 3410+ err = au_reval_dpath(d, sigen);
3411+ if (!err)
3412+ di_downgrade_lock(d, AuLock_IR);
3413+ else {
3414+ di_write_unlock(d);
3415+ break;
3416+ }
3417+ }
3418+
027c5e7a 3419+ /* AuDbgDentry(d); */
1facf9fc 3420+ bstart = au_dbstart(d);
3421+ bend = au_dbend(d);
3422+ if (bstart <= bindex
3423+ && bindex <= bend
3424+ && au_h_dptr(d, bindex)
027c5e7a 3425+ && au_test_dbusy(d, bstart, bend)) {
1facf9fc 3426+ err = -EBUSY;
523b37e3 3427+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 3428+ AuDbgDentry(d);
1facf9fc 3429+ }
3430+ di_read_unlock(d, AuLock_IR);
3431+ }
3432+ }
3433+
4f0767ce 3434+out_dpages:
1facf9fc 3435+ au_dpages_free(&dpages);
4f0767ce 3436+out:
1facf9fc 3437+ return err;
3438+}
3439+
3440+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 3441+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3442+{
3443+ int err;
7f207e10
AM
3444+ unsigned long long max, ull;
3445+ struct inode *i, **array;
1facf9fc 3446+ aufs_bindex_t bstart, bend;
1facf9fc 3447+
7f207e10
AM
3448+ array = au_iarray_alloc(sb, &max);
3449+ err = PTR_ERR(array);
3450+ if (IS_ERR(array))
3451+ goto out;
3452+
1facf9fc 3453+ err = 0;
7f207e10
AM
3454+ AuDbg("b%d\n", bindex);
3455+ for (ull = 0; !err && ull < max; ull++) {
3456+ i = array[ull];
076b876e
AM
3457+ if (unlikely(!i))
3458+ break;
7f207e10 3459+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 3460+ continue;
3461+
7f207e10 3462+ /* AuDbgInode(i); */
537831f9 3463+ if (au_iigen(i, NULL) == sigen)
1facf9fc 3464+ ii_read_lock_child(i);
3465+ else {
3466+ ii_write_lock_child(i);
027c5e7a
AM
3467+ err = au_refresh_hinode_self(i);
3468+ au_iigen_dec(i);
1facf9fc 3469+ if (!err)
3470+ ii_downgrade_lock(i);
3471+ else {
3472+ ii_write_unlock(i);
3473+ break;
3474+ }
3475+ }
3476+
3477+ bstart = au_ibstart(i);
3478+ bend = au_ibend(i);
3479+ if (bstart <= bindex
3480+ && bindex <= bend
3481+ && au_h_iptr(i, bindex)
027c5e7a 3482+ && au_test_ibusy(i, bstart, bend)) {
1facf9fc 3483+ err = -EBUSY;
3484+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 3485+ AuDbgInode(i);
1facf9fc 3486+ }
3487+ ii_read_unlock(i);
3488+ }
7f207e10 3489+ au_iarray_free(array, max);
1facf9fc 3490+
7f207e10 3491+out:
1facf9fc 3492+ return err;
3493+}
3494+
b752ccd1
AM
3495+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
3496+ const unsigned int verbose)
1facf9fc 3497+{
3498+ int err;
3499+ unsigned int sigen;
3500+
3501+ sigen = au_sigen(root->d_sb);
3502+ DiMustNoWaiters(root);
5527c038 3503+ IiMustNoWaiters(d_inode(root));
1facf9fc 3504+ di_write_unlock(root);
b752ccd1 3505+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 3506+ if (!err)
b752ccd1 3507+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 3508+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3509+
3510+ return err;
3511+}
3512+
076b876e
AM
3513+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
3514+ struct file **to_free, int *idx)
3515+{
3516+ int err;
c1595e42 3517+ unsigned char matched, root;
076b876e
AM
3518+ aufs_bindex_t bindex, bend;
3519+ struct au_fidir *fidir;
3520+ struct au_hfile *hfile;
3521+
3522+ err = 0;
2000de60 3523+ root = IS_ROOT(file->f_path.dentry);
c1595e42
JR
3524+ if (root) {
3525+ get_file(file);
3526+ to_free[*idx] = file;
3527+ (*idx)++;
3528+ goto out;
3529+ }
3530+
076b876e 3531+ matched = 0;
076b876e
AM
3532+ fidir = au_fi(file)->fi_hdir;
3533+ AuDebugOn(!fidir);
3534+ bend = au_fbend_dir(file);
3535+ for (bindex = au_fbstart(file); bindex <= bend; bindex++) {
3536+ hfile = fidir->fd_hfile + bindex;
3537+ if (!hfile->hf_file)
3538+ continue;
3539+
c1595e42 3540+ if (hfile->hf_br->br_id == br_id) {
076b876e 3541+ matched = 1;
076b876e 3542+ break;
c1595e42 3543+ }
076b876e 3544+ }
c1595e42 3545+ if (matched)
076b876e
AM
3546+ err = -EBUSY;
3547+
3548+out:
3549+ return err;
3550+}
3551+
3552+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
3553+ struct file **to_free, int opened)
3554+{
3555+ int err, idx;
3556+ unsigned long long ull, max;
3557+ aufs_bindex_t bstart;
3558+ struct file *file, **array;
076b876e
AM
3559+ struct dentry *root;
3560+ struct au_hfile *hfile;
3561+
3562+ array = au_farray_alloc(sb, &max);
3563+ err = PTR_ERR(array);
3564+ if (IS_ERR(array))
3565+ goto out;
3566+
3567+ err = 0;
3568+ idx = 0;
3569+ root = sb->s_root;
3570+ di_write_unlock(root);
3571+ for (ull = 0; ull < max; ull++) {
3572+ file = array[ull];
3573+ if (unlikely(!file))
3574+ break;
3575+
3576+ /* AuDbg("%pD\n", file); */
3577+ fi_read_lock(file);
3578+ bstart = au_fbstart(file);
2000de60 3579+ if (!d_is_dir(file->f_path.dentry)) {
076b876e
AM
3580+ hfile = &au_fi(file)->fi_htop;
3581+ if (hfile->hf_br->br_id == br_id)
3582+ err = -EBUSY;
3583+ } else
3584+ err = test_dir_busy(file, br_id, to_free, &idx);
3585+ fi_read_unlock(file);
3586+ if (unlikely(err))
3587+ break;
3588+ }
3589+ di_write_lock_child(root);
3590+ au_farray_free(array, max);
3591+ AuDebugOn(idx > opened);
3592+
3593+out:
3594+ return err;
3595+}
3596+
3597+static void br_del_file(struct file **to_free, unsigned long long opened,
3598+ aufs_bindex_t br_id)
3599+{
3600+ unsigned long long ull;
3601+ aufs_bindex_t bindex, bstart, bend, bfound;
3602+ struct file *file;
3603+ struct au_fidir *fidir;
3604+ struct au_hfile *hfile;
3605+
3606+ for (ull = 0; ull < opened; ull++) {
3607+ file = to_free[ull];
3608+ if (unlikely(!file))
3609+ break;
3610+
3611+ /* AuDbg("%pD\n", file); */
2000de60 3612+ AuDebugOn(!d_is_dir(file->f_path.dentry));
076b876e
AM
3613+ bfound = -1;
3614+ fidir = au_fi(file)->fi_hdir;
3615+ AuDebugOn(!fidir);
3616+ fi_write_lock(file);
3617+ bstart = au_fbstart(file);
3618+ bend = au_fbend_dir(file);
3619+ for (bindex = bstart; bindex <= bend; bindex++) {
3620+ hfile = fidir->fd_hfile + bindex;
3621+ if (!hfile->hf_file)
3622+ continue;
3623+
3624+ if (hfile->hf_br->br_id == br_id) {
3625+ bfound = bindex;
3626+ break;
3627+ }
3628+ }
3629+ AuDebugOn(bfound < 0);
3630+ au_set_h_fptr(file, bfound, NULL);
3631+ if (bfound == bstart) {
3632+ for (bstart++; bstart <= bend; bstart++)
3633+ if (au_hf_dir(file, bstart)) {
3634+ au_set_fbstart(file, bstart);
3635+ break;
3636+ }
3637+ }
3638+ fi_write_unlock(file);
3639+ }
3640+}
3641+
1facf9fc 3642+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
3643+ const aufs_bindex_t bindex,
3644+ const aufs_bindex_t bend)
3645+{
3646+ struct au_branch **brp, **p;
3647+
dece6358
AM
3648+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3649+
1facf9fc 3650+ brp = sbinfo->si_branch + bindex;
3651+ if (bindex < bend)
3652+ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
3653+ sbinfo->si_branch[0 + bend] = NULL;
3654+ sbinfo->si_bend--;
3655+
53392da6 3656+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3657+ if (p)
3658+ sbinfo->si_branch = p;
4a4d8108 3659+ /* harmless error */
1facf9fc 3660+}
3661+
3662+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
3663+ const aufs_bindex_t bend)
3664+{
3665+ struct au_hdentry *hdp, *p;
3666+
1308ab2a 3667+ AuRwMustWriteLock(&dinfo->di_rwsem);
3668+
4a4d8108 3669+ hdp = dinfo->di_hdentry;
1facf9fc 3670+ if (bindex < bend)
4a4d8108
AM
3671+ memmove(hdp + bindex, hdp + bindex + 1,
3672+ sizeof(*hdp) * (bend - bindex));
3673+ hdp[0 + bend].hd_dentry = NULL;
1facf9fc 3674+ dinfo->di_bend--;
3675+
53392da6 3676+ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3677+ if (p)
3678+ dinfo->di_hdentry = p;
4a4d8108 3679+ /* harmless error */
1facf9fc 3680+}
3681+
3682+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
3683+ const aufs_bindex_t bend)
3684+{
3685+ struct au_hinode *hip, *p;
3686+
1308ab2a 3687+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3688+
1facf9fc 3689+ hip = iinfo->ii_hinode + bindex;
3690+ if (bindex < bend)
3691+ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
3692+ iinfo->ii_hinode[0 + bend].hi_inode = NULL;
4a4d8108 3693+ au_hn_init(iinfo->ii_hinode + bend);
1facf9fc 3694+ iinfo->ii_bend--;
3695+
53392da6 3696+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3697+ if (p)
3698+ iinfo->ii_hinode = p;
4a4d8108 3699+ /* harmless error */
1facf9fc 3700+}
3701+
3702+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
3703+ struct au_branch *br)
3704+{
3705+ aufs_bindex_t bend;
3706+ struct au_sbinfo *sbinfo;
53392da6
AM
3707+ struct dentry *root, *h_root;
3708+ struct inode *inode, *h_inode;
3709+ struct au_hinode *hinode;
1facf9fc 3710+
dece6358
AM
3711+ SiMustWriteLock(sb);
3712+
1facf9fc 3713+ root = sb->s_root;
5527c038 3714+ inode = d_inode(root);
1facf9fc 3715+ sbinfo = au_sbi(sb);
3716+ bend = sbinfo->si_bend;
3717+
53392da6
AM
3718+ h_root = au_h_dptr(root, bindex);
3719+ hinode = au_hi(inode, bindex);
3720+ h_inode = au_igrab(hinode->hi_inode);
3721+ au_hiput(hinode);
1facf9fc 3722+
53392da6 3723+ au_sbilist_lock();
1facf9fc 3724+ au_br_do_del_brp(sbinfo, bindex, bend);
3725+ au_br_do_del_hdp(au_di(root), bindex, bend);
3726+ au_br_do_del_hip(au_ii(inode), bindex, bend);
53392da6
AM
3727+ au_sbilist_unlock();
3728+
3729+ dput(h_root);
3730+ iput(h_inode);
3731+ au_br_do_free(br);
1facf9fc 3732+}
3733+
79b8bda9
AM
3734+static unsigned long long empty_cb(struct super_block *sb, void *array,
3735+ unsigned long long max, void *arg)
076b876e
AM
3736+{
3737+ return max;
3738+}
3739+
1facf9fc 3740+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
3741+{
3742+ int err, rerr, i;
076b876e 3743+ unsigned long long opened;
1facf9fc 3744+ unsigned int mnt_flags;
3745+ aufs_bindex_t bindex, bend, br_id;
3746+ unsigned char do_wh, verbose;
3747+ struct au_branch *br;
3748+ struct au_wbr *wbr;
076b876e
AM
3749+ struct dentry *root;
3750+ struct file **to_free;
1facf9fc 3751+
3752+ err = 0;
076b876e
AM
3753+ opened = 0;
3754+ to_free = NULL;
3755+ root = sb->s_root;
3756+ bindex = au_find_dbindex(root, del->h_path.dentry);
1facf9fc 3757+ if (bindex < 0) {
3758+ if (remount)
3759+ goto out; /* success */
3760+ err = -ENOENT;
4a4d8108 3761+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 3762+ goto out;
3763+ }
3764+ AuDbg("bindex b%d\n", bindex);
3765+
3766+ err = -EBUSY;
3767+ mnt_flags = au_mntflags(sb);
3768+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3769+ bend = au_sbend(sb);
3770+ if (unlikely(!bend)) {
3771+ AuVerbose(verbose, "no more branches left\n");
3772+ goto out;
3773+ }
3774+ br = au_sbr(sb, bindex);
86dc4139 3775+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
076b876e
AM
3776+
3777+ br_id = br->br_id;
3778+ opened = atomic_read(&br->br_count);
3779+ if (unlikely(opened)) {
79b8bda9 3780+ to_free = au_array_alloc(&opened, empty_cb, sb, NULL);
076b876e
AM
3781+ err = PTR_ERR(to_free);
3782+ if (IS_ERR(to_free))
3783+ goto out;
3784+
3785+ err = test_file_busy(sb, br_id, to_free, opened);
3786+ if (unlikely(err)) {
3787+ AuVerbose(verbose, "%llu file(s) opened\n", opened);
3788+ goto out;
3789+ }
1facf9fc 3790+ }
3791+
3792+ wbr = br->br_wbr;
3793+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
3794+ if (do_wh) {
1308ab2a 3795+ /* instead of WbrWhMustWriteLock(wbr) */
3796+ SiMustWriteLock(sb);
1facf9fc 3797+ for (i = 0; i < AuBrWh_Last; i++) {
3798+ dput(wbr->wbr_wh[i]);
3799+ wbr->wbr_wh[i] = NULL;
3800+ }
3801+ }
3802+
076b876e 3803+ err = test_children_busy(root, bindex, verbose);
1facf9fc 3804+ if (unlikely(err)) {
3805+ if (do_wh)
3806+ goto out_wh;
3807+ goto out;
3808+ }
3809+
3810+ err = 0;
076b876e
AM
3811+ if (to_free) {
3812+ /*
3813+ * now we confirmed the branch is deletable.
3814+ * let's free the remaining opened dirs on the branch.
3815+ */
3816+ di_write_unlock(root);
3817+ br_del_file(to_free, opened, br_id);
3818+ di_write_lock_child(root);
3819+ }
3820+
1facf9fc 3821+ if (!remount)
3822+ au_br_do_del(sb, bindex, br);
3823+ else {
3824+ sysaufs_brs_del(sb, bindex);
3825+ au_br_do_del(sb, bindex, br);
3826+ sysaufs_brs_add(sb, bindex);
3827+ }
3828+
1308ab2a 3829+ if (!bindex) {
5527c038 3830+ au_cpup_attr_all(d_inode(root), /*force*/1);
1308ab2a 3831+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
3832+ } else
5527c038 3833+ au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry));
1facf9fc 3834+ if (au_opt_test(mnt_flags, PLINK))
3835+ au_plink_half_refresh(sb, br_id);
3836+
b752ccd1 3837+ if (au_xino_brid(sb) == br_id)
1facf9fc 3838+ au_xino_brid_set(sb, -1);
3839+ goto out; /* success */
3840+
4f0767ce 3841+out_wh:
1facf9fc 3842+ /* revert */
86dc4139 3843+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 3844+ if (rerr)
0c3ec466
AM
3845+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
3846+ del->pathname, rerr);
4f0767ce 3847+out:
076b876e
AM
3848+ if (to_free)
3849+ au_farray_free(to_free, opened);
1facf9fc 3850+ return err;
3851+}
3852+
3853+/* ---------------------------------------------------------------------- */
3854+
027c5e7a
AM
3855+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
3856+{
3857+ int err;
3858+ aufs_bindex_t bstart, bend;
3859+ struct aufs_ibusy ibusy;
3860+ struct inode *inode, *h_inode;
3861+
3862+ err = -EPERM;
3863+ if (unlikely(!capable(CAP_SYS_ADMIN)))
3864+ goto out;
3865+
3866+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
3867+ if (!err)
3868+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
3869+ if (unlikely(err)) {
3870+ err = -EFAULT;
3871+ AuTraceErr(err);
3872+ goto out;
3873+ }
3874+
3875+ err = -EINVAL;
3876+ si_read_lock(sb, AuLock_FLUSH);
3877+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
3878+ goto out_unlock;
3879+
3880+ err = 0;
3881+ ibusy.h_ino = 0; /* invalid */
3882+ inode = ilookup(sb, ibusy.ino);
3883+ if (!inode
3884+ || inode->i_ino == AUFS_ROOT_INO
3885+ || is_bad_inode(inode))
3886+ goto out_unlock;
3887+
3888+ ii_read_lock_child(inode);
3889+ bstart = au_ibstart(inode);
3890+ bend = au_ibend(inode);
3891+ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
3892+ h_inode = au_h_iptr(inode, ibusy.bindex);
3893+ if (h_inode && au_test_ibusy(inode, bstart, bend))
3894+ ibusy.h_ino = h_inode->i_ino;
3895+ }
3896+ ii_read_unlock(inode);
3897+ iput(inode);
3898+
3899+out_unlock:
3900+ si_read_unlock(sb);
3901+ if (!err) {
3902+ err = __put_user(ibusy.h_ino, &arg->h_ino);
3903+ if (unlikely(err)) {
3904+ err = -EFAULT;
3905+ AuTraceErr(err);
3906+ }
3907+ }
3908+out:
3909+ return err;
3910+}
3911+
3912+long au_ibusy_ioctl(struct file *file, unsigned long arg)
3913+{
2000de60 3914+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg);
027c5e7a
AM
3915+}
3916+
3917+#ifdef CONFIG_COMPAT
3918+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
3919+{
2000de60 3920+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg));
027c5e7a
AM
3921+}
3922+#endif
3923+
3924+/* ---------------------------------------------------------------------- */
3925+
1facf9fc 3926+/*
3927+ * change a branch permission
3928+ */
3929+
dece6358
AM
3930+static void au_warn_ima(void)
3931+{
3932+#ifdef CONFIG_IMA
1308ab2a 3933+ /* since it doesn't support mark_files_ro() */
027c5e7a 3934+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
3935+#endif
3936+}
3937+
1facf9fc 3938+static int do_need_sigen_inc(int a, int b)
3939+{
3940+ return au_br_whable(a) && !au_br_whable(b);
3941+}
3942+
3943+static int need_sigen_inc(int old, int new)
3944+{
3945+ return do_need_sigen_inc(old, new)
3946+ || do_need_sigen_inc(new, old);
3947+}
3948+
3949+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
3950+{
7f207e10 3951+ int err, do_warn;
027c5e7a 3952+ unsigned int mnt_flags;
7f207e10 3953+ unsigned long long ull, max;
e49829fe 3954+ aufs_bindex_t br_id;
38d290e6 3955+ unsigned char verbose, writer;
7f207e10 3956+ struct file *file, *hf, **array;
e49829fe 3957+ struct au_hfile *hfile;
1facf9fc 3958+
027c5e7a
AM
3959+ mnt_flags = au_mntflags(sb);
3960+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3961+
7f207e10
AM
3962+ array = au_farray_alloc(sb, &max);
3963+ err = PTR_ERR(array);
3964+ if (IS_ERR(array))
1facf9fc 3965+ goto out;
3966+
7f207e10 3967+ do_warn = 0;
e49829fe 3968+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
3969+ for (ull = 0; ull < max; ull++) {
3970+ file = array[ull];
076b876e
AM
3971+ if (unlikely(!file))
3972+ break;
1facf9fc 3973+
523b37e3 3974+ /* AuDbg("%pD\n", file); */
1facf9fc 3975+ fi_read_lock(file);
3976+ if (unlikely(au_test_mmapped(file))) {
3977+ err = -EBUSY;
523b37e3 3978+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 3979+ AuDbgFile(file);
1facf9fc 3980+ FiMustNoWaiters(file);
3981+ fi_read_unlock(file);
7f207e10 3982+ goto out_array;
1facf9fc 3983+ }
3984+
e49829fe
JR
3985+ hfile = &au_fi(file)->fi_htop;
3986+ hf = hfile->hf_file;
7e9cd9fe 3987+ if (!d_is_reg(file->f_path.dentry)
1facf9fc 3988+ || !(file->f_mode & FMODE_WRITE)
e49829fe 3989+ || hfile->hf_br->br_id != br_id
7f207e10
AM
3990+ || !(hf->f_mode & FMODE_WRITE))
3991+ array[ull] = NULL;
3992+ else {
3993+ do_warn = 1;
3994+ get_file(file);
1facf9fc 3995+ }
3996+
1facf9fc 3997+ FiMustNoWaiters(file);
3998+ fi_read_unlock(file);
7f207e10
AM
3999+ fput(file);
4000+ }
1facf9fc 4001+
4002+ err = 0;
7f207e10 4003+ if (do_warn)
dece6358 4004+ au_warn_ima();
7f207e10
AM
4005+
4006+ for (ull = 0; ull < max; ull++) {
4007+ file = array[ull];
4008+ if (!file)
4009+ continue;
4010+
1facf9fc 4011+ /* todo: already flushed? */
523b37e3
AM
4012+ /*
4013+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
4014+ * approach which resets f_mode and calls mnt_drop_write() and
4015+ * file_release_write() for each file, because the branch
4016+ * attribute in aufs world is totally different from the native
4017+ * fs rw/ro mode.
4018+ */
7f207e10
AM
4019+ /* fi_read_lock(file); */
4020+ hfile = &au_fi(file)->fi_htop;
4021+ hf = hfile->hf_file;
4022+ /* fi_read_unlock(file); */
027c5e7a 4023+ spin_lock(&hf->f_lock);
38d290e6
JR
4024+ writer = !!(hf->f_mode & FMODE_WRITER);
4025+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
027c5e7a 4026+ spin_unlock(&hf->f_lock);
38d290e6
JR
4027+ if (writer) {
4028+ put_write_access(file_inode(hf));
c06a8ce3 4029+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 4030+ }
4031+ }
4032+
7f207e10
AM
4033+out_array:
4034+ au_farray_free(array, max);
4f0767ce 4035+out:
7f207e10 4036+ AuTraceErr(err);
1facf9fc 4037+ return err;
4038+}
4039+
4040+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4041+ int *do_refresh)
1facf9fc 4042+{
4043+ int err, rerr;
4044+ aufs_bindex_t bindex;
4045+ struct dentry *root;
4046+ struct au_branch *br;
076b876e 4047+ struct au_br_fhsm *bf;
1facf9fc 4048+
4049+ root = sb->s_root;
1facf9fc 4050+ bindex = au_find_dbindex(root, mod->h_root);
4051+ if (bindex < 0) {
4052+ if (remount)
4053+ return 0; /* success */
4054+ err = -ENOENT;
4a4d8108 4055+ pr_err("%s no such branch\n", mod->path);
1facf9fc 4056+ goto out;
4057+ }
4058+ AuDbg("bindex b%d\n", bindex);
4059+
5527c038 4060+ err = test_br(d_inode(mod->h_root), mod->perm, mod->path);
1facf9fc 4061+ if (unlikely(err))
4062+ goto out;
4063+
4064+ br = au_sbr(sb, bindex);
86dc4139 4065+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 4066+ if (br->br_perm == mod->perm)
4067+ return 0; /* success */
4068+
076b876e
AM
4069+ /* pre-allocate for non-fhsm --> fhsm */
4070+ bf = NULL;
4071+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
4072+ err = au_fhsm_br_alloc(br);
4073+ if (unlikely(err))
4074+ goto out;
4075+ bf = br->br_fhsm;
4076+ br->br_fhsm = NULL;
4077+ }
4078+
1facf9fc 4079+ if (au_br_writable(br->br_perm)) {
4080+ /* remove whiteout base */
86dc4139 4081+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 4082+ if (unlikely(err))
076b876e 4083+ goto out_bf;
1facf9fc 4084+
4085+ if (!au_br_writable(mod->perm)) {
4086+ /* rw --> ro, file might be mmapped */
4087+ DiMustNoWaiters(root);
5527c038 4088+ IiMustNoWaiters(d_inode(root));
1facf9fc 4089+ di_write_unlock(root);
4090+ err = au_br_mod_files_ro(sb, bindex);
4091+ /* aufs_write_lock() calls ..._child() */
4092+ di_write_lock_child(root);
4093+
4094+ if (unlikely(err)) {
4095+ rerr = -ENOMEM;
4096+ br->br_wbr = kmalloc(sizeof(*br->br_wbr),
4097+ GFP_NOFS);
86dc4139
AM
4098+ if (br->br_wbr)
4099+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 4100+ if (unlikely(rerr)) {
4101+ AuIOErr("nested error %d (%d)\n",
4102+ rerr, err);
4103+ br->br_perm = mod->perm;
4104+ }
4105+ }
4106+ }
4107+ } else if (au_br_writable(mod->perm)) {
4108+ /* ro --> rw */
4109+ err = -ENOMEM;
4110+ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
4111+ if (br->br_wbr) {
86dc4139 4112+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 4113+ if (unlikely(err)) {
4114+ kfree(br->br_wbr);
4115+ br->br_wbr = NULL;
4116+ }
4117+ }
4118+ }
076b876e
AM
4119+ if (unlikely(err))
4120+ goto out_bf;
4121+
4122+ if (au_br_fhsm(br->br_perm)) {
4123+ if (!au_br_fhsm(mod->perm)) {
4124+ /* fhsm --> non-fhsm */
4125+ au_br_fhsm_fin(br->br_fhsm);
4126+ kfree(br->br_fhsm);
4127+ br->br_fhsm = NULL;
4128+ }
4129+ } else if (au_br_fhsm(mod->perm))
4130+ /* non-fhsm --> fhsm */
4131+ br->br_fhsm = bf;
4132+
076b876e
AM
4133+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
4134+ br->br_perm = mod->perm;
4135+ goto out; /* success */
1facf9fc 4136+
076b876e
AM
4137+out_bf:
4138+ kfree(bf);
4139+out:
4140+ AuTraceErr(err);
4141+ return err;
4142+}
4143+
4144+/* ---------------------------------------------------------------------- */
4145+
4146+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
4147+{
4148+ int err;
4149+ struct kstatfs kstfs;
4150+
4151+ err = vfs_statfs(&br->br_path, &kstfs);
1facf9fc 4152+ if (!err) {
076b876e
AM
4153+ stfs->f_blocks = kstfs.f_blocks;
4154+ stfs->f_bavail = kstfs.f_bavail;
4155+ stfs->f_files = kstfs.f_files;
4156+ stfs->f_ffree = kstfs.f_ffree;
1facf9fc 4157+ }
4158+
1facf9fc 4159+ return err;
4160+}
7f207e10
AM
4161diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
4162--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
79b8bda9 4163+++ linux/fs/aufs/branch.h 2015-11-11 17:21:46.915530388 +0100
b912730e 4164@@ -0,0 +1,279 @@
1facf9fc 4165+/*
2000de60 4166+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 4167+ *
4168+ * This program, aufs is free software; you can redistribute it and/or modify
4169+ * it under the terms of the GNU General Public License as published by
4170+ * the Free Software Foundation; either version 2 of the License, or
4171+ * (at your option) any later version.
dece6358
AM
4172+ *
4173+ * This program is distributed in the hope that it will be useful,
4174+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4175+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4176+ * GNU General Public License for more details.
4177+ *
4178+ * You should have received a copy of the GNU General Public License
523b37e3 4179+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4180+ */
4181+
4182+/*
4183+ * branch filesystems and xino for them
4184+ */
4185+
4186+#ifndef __AUFS_BRANCH_H__
4187+#define __AUFS_BRANCH_H__
4188+
4189+#ifdef __KERNEL__
4190+
1facf9fc 4191+#include <linux/mount.h>
4a4d8108 4192+#include "dynop.h"
1facf9fc 4193+#include "rwsem.h"
4194+#include "super.h"
4195+
4196+/* ---------------------------------------------------------------------- */
4197+
4198+/* a xino file */
4199+struct au_xino_file {
4200+ struct file *xi_file;
4201+ struct mutex xi_nondir_mtx;
4202+
4203+ /* todo: make xino files an array to support huge inode number */
4204+
4205+#ifdef CONFIG_DEBUG_FS
4206+ struct dentry *xi_dbgaufs;
4207+#endif
4208+};
4209+
076b876e
AM
4210+/* File-based Hierarchical Storage Management */
4211+struct au_br_fhsm {
4212+#ifdef CONFIG_AUFS_FHSM
4213+ struct mutex bf_lock;
4214+ unsigned long bf_jiffy;
4215+ struct aufs_stfs bf_stfs;
4216+ int bf_readable;
4217+#endif
4218+};
4219+
1facf9fc 4220+/* members for writable branch only */
4221+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
4222+struct au_wbr {
dece6358 4223+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 4224+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 4225+ atomic_t wbr_wh_running;
1facf9fc 4226+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
4227+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
4228+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
4229+
4230+ /* mfs mode */
4231+ unsigned long long wbr_bytes;
4232+};
4233+
4a4d8108
AM
4234+/* ext2 has 3 types of operations at least, ext3 has 4 */
4235+#define AuBrDynOp (AuDyLast * 4)
4236+
1716fcea
AM
4237+#ifdef CONFIG_AUFS_HFSNOTIFY
4238+/* support for asynchronous destruction */
4239+struct au_br_hfsnotify {
4240+ struct fsnotify_group *hfsn_group;
4241+};
4242+#endif
4243+
392086de
AM
4244+/* sysfs entries */
4245+struct au_brsysfs {
4246+ char name[16];
4247+ struct attribute attr;
4248+};
4249+
4250+enum {
4251+ AuBrSysfs_BR,
4252+ AuBrSysfs_BRID,
4253+ AuBrSysfs_Last
4254+};
4255+
1facf9fc 4256+/* protected by superblock rwsem */
4257+struct au_branch {
4258+ struct au_xino_file br_xino;
4259+
4260+ aufs_bindex_t br_id;
4261+
4262+ int br_perm;
86dc4139 4263+ struct path br_path;
4a4d8108
AM
4264+ spinlock_t br_dykey_lock;
4265+ struct au_dykey *br_dykey[AuBrDynOp];
1facf9fc 4266+ atomic_t br_count;
4267+
4268+ struct au_wbr *br_wbr;
076b876e 4269+ struct au_br_fhsm *br_fhsm;
1facf9fc 4270+
4271+ /* xino truncation */
1facf9fc 4272+ atomic_t br_xino_running;
4273+
027c5e7a 4274+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 4275+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
4276+#endif
4277+
1facf9fc 4278+#ifdef CONFIG_SYSFS
392086de
AM
4279+ /* entries under sysfs per mount-point */
4280+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 4281+#endif
4282+};
4283+
4284+/* ---------------------------------------------------------------------- */
4285+
86dc4139
AM
4286+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
4287+{
4288+ return br->br_path.mnt;
4289+}
4290+
4291+static inline struct dentry *au_br_dentry(struct au_branch *br)
4292+{
4293+ return br->br_path.dentry;
4294+}
4295+
4296+static inline struct super_block *au_br_sb(struct au_branch *br)
4297+{
4298+ return au_br_mnt(br)->mnt_sb;
4299+}
4300+
1facf9fc 4301+static inline int au_br_rdonly(struct au_branch *br)
4302+{
86dc4139 4303+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 4304+ || !au_br_writable(br->br_perm))
4305+ ? -EROFS : 0;
4306+}
4307+
4a4d8108 4308+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 4309+{
4a4d8108 4310+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 4311+ return !(brperm & AuBrPerm_RR);
1facf9fc 4312+#else
4313+ return 0;
4314+#endif
4315+}
4316+
b912730e
AM
4317+static inline int au_br_test_oflag(int oflag, struct au_branch *br)
4318+{
4319+ int err, exec_flag;
4320+
4321+ err = 0;
4322+ exec_flag = oflag & __FMODE_EXEC;
79b8bda9 4323+ if (unlikely(exec_flag && path_noexec(&br->br_path)))
b912730e
AM
4324+ err = -EACCES;
4325+
4326+ return err;
4327+}
4328+
1facf9fc 4329+/* ---------------------------------------------------------------------- */
4330+
4331+/* branch.c */
4332+struct au_sbinfo;
4333+void au_br_free(struct au_sbinfo *sinfo);
4334+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
4335+struct au_opt_add;
4336+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
4337+struct au_opt_del;
4338+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
4339+long au_ibusy_ioctl(struct file *file, unsigned long arg);
4340+#ifdef CONFIG_COMPAT
4341+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
4342+#endif
1facf9fc 4343+struct au_opt_mod;
4344+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4345+ int *do_refresh);
076b876e
AM
4346+struct aufs_stfs;
4347+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
1facf9fc 4348+
4349+/* xino.c */
4350+static const loff_t au_loff_max = LLONG_MAX;
4351+
4352+int au_xib_trunc(struct super_block *sb);
5527c038 4353+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size,
1facf9fc 4354+ loff_t *pos);
5527c038
JR
4355+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
4356+ size_t size, loff_t *pos);
1facf9fc 4357+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
4358+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
4359+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 4360+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 4361+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4362+ ino_t ino);
4363+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4364+ ino_t *ino);
4365+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
4366+ struct file *base_file, int do_test);
4367+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
4368+
4369+struct au_opt_xino;
4370+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
4371+void au_xino_clr(struct super_block *sb);
4372+struct file *au_xino_def(struct super_block *sb);
4373+int au_xino_path(struct seq_file *seq, struct file *file);
4374+
4375+/* ---------------------------------------------------------------------- */
4376+
4377+/* Superblock to branch */
4378+static inline
4379+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
4380+{
4381+ return au_sbr(sb, bindex)->br_id;
4382+}
4383+
4384+static inline
4385+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
4386+{
86dc4139 4387+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 4388+}
4389+
4390+static inline
4391+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
4392+{
86dc4139 4393+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 4394+}
4395+
4396+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
4397+{
e49829fe 4398+ atomic_dec(&au_sbr(sb, bindex)->br_count);
1facf9fc 4399+}
4400+
4401+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
4402+{
4403+ return au_sbr(sb, bindex)->br_perm;
4404+}
4405+
4406+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
4407+{
4408+ return au_br_whable(au_sbr_perm(sb, bindex));
4409+}
4410+
4411+/* ---------------------------------------------------------------------- */
4412+
4413+/*
4414+ * wbr_wh_read_lock, wbr_wh_write_lock
4415+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
4416+ */
4417+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
4418+
dece6358
AM
4419+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
4420+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
4421+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
4422+
076b876e
AM
4423+/* ---------------------------------------------------------------------- */
4424+
4425+#ifdef CONFIG_AUFS_FHSM
4426+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
4427+{
4428+ mutex_init(&brfhsm->bf_lock);
4429+ brfhsm->bf_jiffy = 0;
4430+ brfhsm->bf_readable = 0;
4431+}
4432+
4433+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
4434+{
4435+ mutex_destroy(&brfhsm->bf_lock);
4436+}
4437+#else
4438+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
4439+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
4440+#endif
4441+
1facf9fc 4442+#endif /* __KERNEL__ */
4443+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
4444diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
4445--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 4446+++ linux/fs/aufs/conf.mk 2015-09-24 10:47:58.248052907 +0200
c1595e42 4447@@ -0,0 +1,38 @@
4a4d8108
AM
4448+
4449+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
4450+
4451+define AuConf
4452+ifdef ${1}
4453+AuConfStr += ${1}=${${1}}
4454+endif
4455+endef
4456+
b752ccd1 4457+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 4458+ SBILIST \
7f207e10 4459+ HNOTIFY HFSNOTIFY \
4a4d8108 4460+ EXPORT INO_T_64 \
c1595e42 4461+ XATTR \
076b876e 4462+ FHSM \
4a4d8108 4463+ RDU \
4a4d8108
AM
4464+ SHWH \
4465+ BR_RAMFS \
4466+ BR_FUSE POLL \
4467+ BR_HFSPLUS \
4468+ BDEV_LOOP \
b752ccd1
AM
4469+ DEBUG MAGIC_SYSRQ
4470+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
4471+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
4472+
4473+AuConfName = ${obj}/conf.str
4474+${AuConfName}.tmp: FORCE
4475+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
4476+${AuConfName}: ${AuConfName}.tmp
4477+ @diff -q $< $@ > /dev/null 2>&1 || { \
4478+ echo ' GEN ' $@; \
4479+ cp -p $< $@; \
4480+ }
4481+FORCE:
4482+clean-files += ${AuConfName} ${AuConfName}.tmp
4483+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
4484+
4485+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
4486diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
4487--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9 4488+++ linux/fs/aufs/cpup.c 2015-11-11 17:21:46.915530388 +0100
5527c038 4489@@ -0,0 +1,1319 @@
1facf9fc 4490+/*
2000de60 4491+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 4492+ *
4493+ * This program, aufs is free software; you can redistribute it and/or modify
4494+ * it under the terms of the GNU General Public License as published by
4495+ * the Free Software Foundation; either version 2 of the License, or
4496+ * (at your option) any later version.
dece6358
AM
4497+ *
4498+ * This program is distributed in the hope that it will be useful,
4499+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4500+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4501+ * GNU General Public License for more details.
4502+ *
4503+ * You should have received a copy of the GNU General Public License
523b37e3 4504+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4505+ */
4506+
4507+/*
4508+ * copy-up functions, see wbr_policy.c for copy-down
4509+ */
4510+
4511+#include <linux/fs_stack.h>
dece6358 4512+#include <linux/mm.h>
1facf9fc 4513+#include "aufs.h"
4514+
86dc4139 4515+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 4516+{
4517+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 4518+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 4519+
86dc4139
AM
4520+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
4521+
4522+ dst->i_flags |= iflags & ~mask;
1facf9fc 4523+ if (au_test_fs_notime(dst->i_sb))
4524+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
4525+}
4526+
4527+void au_cpup_attr_timesizes(struct inode *inode)
4528+{
4529+ struct inode *h_inode;
4530+
4531+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4532+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 4533+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 4534+}
4535+
4536+void au_cpup_attr_nlink(struct inode *inode, int force)
4537+{
4538+ struct inode *h_inode;
4539+ struct super_block *sb;
4540+ aufs_bindex_t bindex, bend;
4541+
4542+ sb = inode->i_sb;
4543+ bindex = au_ibstart(inode);
4544+ h_inode = au_h_iptr(inode, bindex);
4545+ if (!force
4546+ && !S_ISDIR(h_inode->i_mode)
4547+ && au_opt_test(au_mntflags(sb), PLINK)
4548+ && au_plink_test(inode))
4549+ return;
4550+
7eafdf33
AM
4551+ /*
4552+ * 0 can happen in revalidating.
38d290e6
JR
4553+ * h_inode->i_mutex may not be held here, but it is harmless since once
4554+ * i_nlink reaches 0, it will never become positive except O_TMPFILE
4555+ * case.
4556+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
4557+ * the incorrect link count.
7eafdf33 4558+ */
92d182d2 4559+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 4560+
4561+ /*
4562+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
4563+ * it may includes whplink directory.
4564+ */
4565+ if (S_ISDIR(h_inode->i_mode)) {
4566+ bend = au_ibend(inode);
4567+ for (bindex++; bindex <= bend; bindex++) {
4568+ h_inode = au_h_iptr(inode, bindex);
4569+ if (h_inode)
4570+ au_add_nlink(inode, h_inode);
4571+ }
4572+ }
4573+}
4574+
4575+void au_cpup_attr_changeable(struct inode *inode)
4576+{
4577+ struct inode *h_inode;
4578+
4579+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4580+ inode->i_mode = h_inode->i_mode;
4581+ inode->i_uid = h_inode->i_uid;
4582+ inode->i_gid = h_inode->i_gid;
4583+ au_cpup_attr_timesizes(inode);
86dc4139 4584+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 4585+}
4586+
4587+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
4588+{
4589+ struct au_iinfo *iinfo = au_ii(inode);
4590+
1308ab2a 4591+ IiMustWriteLock(inode);
4592+
1facf9fc 4593+ iinfo->ii_higen = h_inode->i_generation;
4594+ iinfo->ii_hsb1 = h_inode->i_sb;
4595+}
4596+
4597+void au_cpup_attr_all(struct inode *inode, int force)
4598+{
4599+ struct inode *h_inode;
4600+
4601+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4602+ au_cpup_attr_changeable(inode);
4603+ if (inode->i_nlink > 0)
4604+ au_cpup_attr_nlink(inode, force);
4605+ inode->i_rdev = h_inode->i_rdev;
4606+ inode->i_blkbits = h_inode->i_blkbits;
4607+ au_cpup_igen(inode, h_inode);
4608+}
4609+
4610+/* ---------------------------------------------------------------------- */
4611+
4612+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
4613+
4614+/* keep the timestamps of the parent dir when cpup */
4615+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4616+ struct path *h_path)
4617+{
4618+ struct inode *h_inode;
4619+
4620+ dt->dt_dentry = dentry;
4621+ dt->dt_h_path = *h_path;
5527c038 4622+ h_inode = d_inode(h_path->dentry);
1facf9fc 4623+ dt->dt_atime = h_inode->i_atime;
4624+ dt->dt_mtime = h_inode->i_mtime;
4625+ /* smp_mb(); */
4626+}
4627+
4628+void au_dtime_revert(struct au_dtime *dt)
4629+{
4630+ struct iattr attr;
4631+ int err;
4632+
4633+ attr.ia_atime = dt->dt_atime;
4634+ attr.ia_mtime = dt->dt_mtime;
4635+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
4636+ | ATTR_ATIME | ATTR_ATIME_SET;
4637+
523b37e3
AM
4638+ /* no delegation since this is a directory */
4639+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 4640+ if (unlikely(err))
0c3ec466 4641+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 4642+}
4643+
4644+/* ---------------------------------------------------------------------- */
4645+
86dc4139
AM
4646+/* internal use only */
4647+struct au_cpup_reg_attr {
4648+ int valid;
4649+ struct kstat st;
4650+ unsigned int iflags; /* inode->i_flags */
4651+};
4652+
1facf9fc 4653+static noinline_for_stack
86dc4139
AM
4654+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
4655+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4656+{
c1595e42 4657+ int err, sbits, icex;
7e9cd9fe
AM
4658+ unsigned int mnt_flags;
4659+ unsigned char verbose;
1facf9fc 4660+ struct iattr ia;
4661+ struct path h_path;
1308ab2a 4662+ struct inode *h_isrc, *h_idst;
86dc4139 4663+ struct kstat *h_st;
c1595e42 4664+ struct au_branch *br;
1facf9fc 4665+
4666+ h_path.dentry = au_h_dptr(dst, bindex);
5527c038 4667+ h_idst = d_inode(h_path.dentry);
c1595e42
JR
4668+ br = au_sbr(dst->d_sb, bindex);
4669+ h_path.mnt = au_br_mnt(br);
5527c038 4670+ h_isrc = d_inode(h_src);
1308ab2a 4671+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 4672+ | ATTR_ATIME | ATTR_MTIME
4673+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
4674+ if (h_src_attr && h_src_attr->valid) {
4675+ h_st = &h_src_attr->st;
4676+ ia.ia_uid = h_st->uid;
4677+ ia.ia_gid = h_st->gid;
4678+ ia.ia_atime = h_st->atime;
4679+ ia.ia_mtime = h_st->mtime;
4680+ if (h_idst->i_mode != h_st->mode
4681+ && !S_ISLNK(h_idst->i_mode)) {
4682+ ia.ia_valid |= ATTR_MODE;
4683+ ia.ia_mode = h_st->mode;
4684+ }
4685+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
4686+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
4687+ } else {
4688+ ia.ia_uid = h_isrc->i_uid;
4689+ ia.ia_gid = h_isrc->i_gid;
4690+ ia.ia_atime = h_isrc->i_atime;
4691+ ia.ia_mtime = h_isrc->i_mtime;
4692+ if (h_idst->i_mode != h_isrc->i_mode
4693+ && !S_ISLNK(h_idst->i_mode)) {
4694+ ia.ia_valid |= ATTR_MODE;
4695+ ia.ia_mode = h_isrc->i_mode;
4696+ }
4697+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
4698+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 4699+ }
523b37e3
AM
4700+ /* no delegation since it is just created */
4701+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4702+
4703+ /* is this nfs only? */
4704+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
4705+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
4706+ ia.ia_mode = h_isrc->i_mode;
523b37e3 4707+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4708+ }
4709+
c1595e42 4710+ icex = br->br_perm & AuBrAttr_ICEX;
7e9cd9fe
AM
4711+ if (!err) {
4712+ mnt_flags = au_mntflags(dst->d_sb);
4713+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
4714+ err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose);
4715+ }
c1595e42 4716+
1facf9fc 4717+ return err;
4718+}
4719+
4720+/* ---------------------------------------------------------------------- */
4721+
4722+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
4723+ char *buf, unsigned long blksize)
4724+{
4725+ int err;
4726+ size_t sz, rbytes, wbytes;
4727+ unsigned char all_zero;
4728+ char *p, *zp;
4729+ struct mutex *h_mtx;
4730+ /* reduce stack usage */
4731+ struct iattr *ia;
4732+
4733+ zp = page_address(ZERO_PAGE(0));
4734+ if (unlikely(!zp))
4735+ return -ENOMEM; /* possible? */
4736+
4737+ err = 0;
4738+ all_zero = 0;
4739+ while (len) {
4740+ AuDbg("len %lld\n", len);
4741+ sz = blksize;
4742+ if (len < blksize)
4743+ sz = len;
4744+
4745+ rbytes = 0;
4746+ /* todo: signal_pending? */
4747+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
4748+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
4749+ err = rbytes;
4750+ }
4751+ if (unlikely(err < 0))
4752+ break;
4753+
4754+ all_zero = 0;
4755+ if (len >= rbytes && rbytes == blksize)
4756+ all_zero = !memcmp(buf, zp, rbytes);
4757+ if (!all_zero) {
4758+ wbytes = rbytes;
4759+ p = buf;
4760+ while (wbytes) {
4761+ size_t b;
4762+
4763+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
4764+ err = b;
4765+ /* todo: signal_pending? */
4766+ if (unlikely(err == -EAGAIN || err == -EINTR))
4767+ continue;
4768+ if (unlikely(err < 0))
4769+ break;
4770+ wbytes -= b;
4771+ p += b;
4772+ }
392086de
AM
4773+ if (unlikely(err < 0))
4774+ break;
1facf9fc 4775+ } else {
4776+ loff_t res;
4777+
4778+ AuLabel(hole);
4779+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
4780+ err = res;
4781+ if (unlikely(res < 0))
4782+ break;
4783+ }
4784+ len -= rbytes;
4785+ err = 0;
4786+ }
4787+
4788+ /* the last block may be a hole */
4789+ if (!err && all_zero) {
4790+ AuLabel(last hole);
4791+
4792+ err = 1;
2000de60 4793+ if (au_test_nfs(dst->f_path.dentry->d_sb)) {
1facf9fc 4794+ /* nfs requires this step to make last hole */
4795+ /* is this only nfs? */
4796+ do {
4797+ /* todo: signal_pending? */
4798+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
4799+ } while (err == -EAGAIN || err == -EINTR);
4800+ if (err == 1)
4801+ dst->f_pos--;
4802+ }
4803+
4804+ if (err == 1) {
4805+ ia = (void *)buf;
4806+ ia->ia_size = dst->f_pos;
4807+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
4808+ ia->ia_file = dst;
c06a8ce3 4809+ h_mtx = &file_inode(dst)->i_mutex;
1facf9fc 4810+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
523b37e3
AM
4811+ /* no delegation since it is just created */
4812+ err = vfsub_notify_change(&dst->f_path, ia,
4813+ /*delegated*/NULL);
1facf9fc 4814+ mutex_unlock(h_mtx);
4815+ }
4816+ }
4817+
4818+ return err;
4819+}
4820+
4821+int au_copy_file(struct file *dst, struct file *src, loff_t len)
4822+{
4823+ int err;
4824+ unsigned long blksize;
4825+ unsigned char do_kfree;
4826+ char *buf;
4827+
4828+ err = -ENOMEM;
2000de60 4829+ blksize = dst->f_path.dentry->d_sb->s_blocksize;
1facf9fc 4830+ if (!blksize || PAGE_SIZE < blksize)
4831+ blksize = PAGE_SIZE;
4832+ AuDbg("blksize %lu\n", blksize);
4833+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
4834+ if (do_kfree)
4835+ buf = kmalloc(blksize, GFP_NOFS);
4836+ else
4837+ buf = (void *)__get_free_page(GFP_NOFS);
4838+ if (unlikely(!buf))
4839+ goto out;
4840+
4841+ if (len > (1 << 22))
4842+ AuDbg("copying a large file %lld\n", (long long)len);
4843+
4844+ src->f_pos = 0;
4845+ dst->f_pos = 0;
4846+ err = au_do_copy_file(dst, src, len, buf, blksize);
4847+ if (do_kfree)
4848+ kfree(buf);
4849+ else
4850+ free_page((unsigned long)buf);
4851+
4f0767ce 4852+out:
1facf9fc 4853+ return err;
4854+}
4855+
4856+/*
4857+ * to support a sparse file which is opened with O_APPEND,
4858+ * we need to close the file.
4859+ */
c2b27bf2 4860+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 4861+{
4862+ int err, i;
4863+ enum { SRC, DST };
4864+ struct {
4865+ aufs_bindex_t bindex;
4866+ unsigned int flags;
4867+ struct dentry *dentry;
392086de 4868+ int force_wr;
1facf9fc 4869+ struct file *file;
523b37e3 4870+ void *label;
1facf9fc 4871+ } *f, file[] = {
4872+ {
c2b27bf2 4873+ .bindex = cpg->bsrc,
1facf9fc 4874+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
523b37e3 4875+ .label = &&out
1facf9fc 4876+ },
4877+ {
c2b27bf2 4878+ .bindex = cpg->bdst,
1facf9fc 4879+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 4880+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
523b37e3 4881+ .label = &&out_src
1facf9fc 4882+ }
4883+ };
4884+ struct super_block *sb;
4885+
4886+ /* bsrc branch can be ro/rw. */
c2b27bf2 4887+ sb = cpg->dentry->d_sb;
1facf9fc 4888+ f = file;
4889+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
4890+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
4891+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 4892+ /*file*/NULL, f->force_wr);
1facf9fc 4893+ err = PTR_ERR(f->file);
4894+ if (IS_ERR(f->file))
4895+ goto *f->label;
1facf9fc 4896+ }
4897+
4898+ /* try stopping to update while we copyup */
5527c038 4899+ IMustLock(d_inode(file[SRC].dentry));
c2b27bf2 4900+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 4901+
1facf9fc 4902+ fput(file[DST].file);
4903+ au_sbr_put(sb, file[DST].bindex);
523b37e3 4904+
4f0767ce 4905+out_src:
1facf9fc 4906+ fput(file[SRC].file);
4907+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 4908+out:
1facf9fc 4909+ return err;
4910+}
4911+
c2b27bf2 4912+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 4913+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4914+{
4915+ int err, rerr;
4916+ loff_t l;
86dc4139 4917+ struct path h_path;
38d290e6 4918+ struct inode *h_src_inode, *h_dst_inode;
1facf9fc 4919+
4920+ err = 0;
5527c038 4921+ h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc);
86dc4139 4922+ l = i_size_read(h_src_inode);
c2b27bf2
AM
4923+ if (cpg->len == -1 || l < cpg->len)
4924+ cpg->len = l;
4925+ if (cpg->len) {
86dc4139
AM
4926+ /* try stopping to update while we are referencing */
4927+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2 4928+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 4929+
c2b27bf2
AM
4930+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
4931+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139 4932+ h_src_attr->iflags = h_src_inode->i_flags;
5527c038
JR
4933+ if (!au_test_nfs(h_src_inode->i_sb))
4934+ err = vfs_getattr(&h_path, &h_src_attr->st);
4935+ else {
4936+ mutex_unlock(&h_src_inode->i_mutex);
4937+ err = vfs_getattr(&h_path, &h_src_attr->st);
4938+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
4939+ }
86dc4139
AM
4940+ if (unlikely(err)) {
4941+ mutex_unlock(&h_src_inode->i_mutex);
4942+ goto out;
4943+ }
4944+ h_src_attr->valid = 1;
c2b27bf2 4945+ err = au_cp_regular(cpg);
86dc4139 4946+ mutex_unlock(&h_src_inode->i_mutex);
c2b27bf2 4947+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
4948+ if (!err && rerr)
4949+ err = rerr;
1facf9fc 4950+ }
38d290e6
JR
4951+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
4952+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
5527c038 4953+ h_dst_inode = d_inode(h_path.dentry);
38d290e6
JR
4954+ spin_lock(&h_dst_inode->i_lock);
4955+ h_dst_inode->i_state |= I_LINKABLE;
4956+ spin_unlock(&h_dst_inode->i_lock);
4957+ }
1facf9fc 4958+
4f0767ce 4959+out:
1facf9fc 4960+ return err;
4961+}
4962+
4963+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
4964+ struct inode *h_dir)
4965+{
4966+ int err, symlen;
4967+ mm_segment_t old_fs;
b752ccd1
AM
4968+ union {
4969+ char *k;
4970+ char __user *u;
4971+ } sym;
5527c038
JR
4972+ struct inode *h_inode = d_inode(h_src);
4973+ const struct inode_operations *h_iop = h_inode->i_op;
1facf9fc 4974+
4975+ err = -ENOSYS;
5527c038 4976+ if (unlikely(!h_iop->readlink))
1facf9fc 4977+ goto out;
4978+
4979+ err = -ENOMEM;
537831f9 4980+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 4981+ if (unlikely(!sym.k))
1facf9fc 4982+ goto out;
4983+
9dbd164d 4984+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 4985+ old_fs = get_fs();
4986+ set_fs(KERNEL_DS);
5527c038 4987+ symlen = h_iop->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 4988+ err = symlen;
4989+ set_fs(old_fs);
4990+
4991+ if (symlen > 0) {
b752ccd1
AM
4992+ sym.k[symlen] = 0;
4993+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 4994+ }
537831f9 4995+ free_page((unsigned long)sym.k);
1facf9fc 4996+
4f0767ce 4997+out:
1facf9fc 4998+ return err;
4999+}
5000+
1facf9fc 5001+static noinline_for_stack
c2b27bf2 5002+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 5003+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 5004+{
5005+ int err;
5006+ umode_t mode;
5007+ unsigned int mnt_flags;
076b876e 5008+ unsigned char isdir, isreg, force;
c2b27bf2 5009+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5010+ struct au_dtime dt;
5011+ struct path h_path;
5012+ struct dentry *h_src, *h_dst, *h_parent;
5527c038 5013+ struct inode *h_inode, *h_dir, *dir, *inode;
1facf9fc 5014+ struct super_block *sb;
5015+
5016+ /* bsrc branch can be ro/rw. */
c2b27bf2 5017+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038
JR
5018+ h_inode = d_inode(h_src);
5019+ AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc));
1facf9fc 5020+
5021+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
5022+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
5023+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
5024+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
5025+ AUFS_WH_PFX_LEN));
1facf9fc 5026+ h_parent = h_dst->d_parent; /* dir inode is locked */
5527c038 5027+ h_dir = d_inode(h_parent);
1facf9fc 5028+ IMustLock(h_dir);
5029+ AuDebugOn(h_parent != h_dst->d_parent);
5030+
c2b27bf2
AM
5031+ sb = cpg->dentry->d_sb;
5032+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 5033+ if (do_dt) {
5034+ h_path.dentry = h_parent;
5035+ au_dtime_store(&dt, dst_parent, &h_path);
5036+ }
5037+ h_path.dentry = h_dst;
5038+
076b876e 5039+ isreg = 0;
1facf9fc 5040+ isdir = 0;
5041+ mode = h_inode->i_mode;
5042+ switch (mode & S_IFMT) {
5043+ case S_IFREG:
076b876e 5044+ isreg = 1;
b4510431
AM
5045+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
5046+ /*want_excl*/true);
1facf9fc 5047+ if (!err)
c2b27bf2 5048+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 5049+ break;
5050+ case S_IFDIR:
5051+ isdir = 1;
5052+ err = vfsub_mkdir(h_dir, &h_path, mode);
5053+ if (!err) {
5054+ /*
5055+ * strange behaviour from the users view,
5056+ * particularry setattr case
5057+ */
5527c038
JR
5058+ dir = d_inode(dst_parent);
5059+ if (au_ibstart(dir) == cpg->bdst)
5060+ au_cpup_attr_nlink(dir, /*force*/1);
5061+ inode = d_inode(cpg->dentry);
5062+ au_cpup_attr_nlink(inode, /*force*/1);
1facf9fc 5063+ }
5064+ break;
5065+ case S_IFLNK:
5066+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
5067+ break;
5068+ case S_IFCHR:
5069+ case S_IFBLK:
5070+ AuDebugOn(!capable(CAP_MKNOD));
5071+ /*FALLTHROUGH*/
5072+ case S_IFIFO:
5073+ case S_IFSOCK:
5074+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
5075+ break;
5076+ default:
5077+ AuIOErr("Unknown inode type 0%o\n", mode);
5078+ err = -EIO;
5079+ }
5080+
5081+ mnt_flags = au_mntflags(sb);
5082+ if (!au_opt_test(mnt_flags, UDBA_NONE)
5083+ && !isdir
5084+ && au_opt_test(mnt_flags, XINO)
38d290e6
JR
5085+ && (h_inode->i_nlink == 1
5086+ || (h_inode->i_state & I_LINKABLE))
1facf9fc 5087+ /* todo: unnecessary? */
5527c038 5088+ /* && d_inode(cpg->dentry)->i_nlink == 1 */
c2b27bf2
AM
5089+ && cpg->bdst < cpg->bsrc
5090+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
5091+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 5092+ /* ignore this error */
5093+
076b876e
AM
5094+ if (!err) {
5095+ force = 0;
5096+ if (isreg) {
5097+ force = !!cpg->len;
5098+ if (cpg->len == -1)
5099+ force = !!i_size_read(h_inode);
5100+ }
5101+ au_fhsm_wrote(sb, cpg->bdst, force);
5102+ }
5103+
1facf9fc 5104+ if (do_dt)
5105+ au_dtime_revert(&dt);
5106+ return err;
5107+}
5108+
392086de 5109+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
5110+{
5111+ int err;
392086de 5112+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 5113+ struct inode *h_dir;
392086de 5114+ aufs_bindex_t bdst;
86dc4139 5115+
392086de
AM
5116+ dentry = cpg->dentry;
5117+ bdst = cpg->bdst;
5118+ h_dentry = au_h_dptr(dentry, bdst);
5119+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
5120+ dget(h_dentry);
5121+ au_set_h_dptr(dentry, bdst, NULL);
5122+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
5123+ if (!err)
5124+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 5125+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
5126+ } else {
5127+ err = 0;
5128+ parent = dget_parent(dentry);
5129+ h_parent = au_h_dptr(parent, bdst);
5130+ dput(parent);
5131+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
5132+ if (IS_ERR(h_path->dentry))
5133+ err = PTR_ERR(h_path->dentry);
86dc4139 5134+ }
392086de
AM
5135+ if (unlikely(err))
5136+ goto out;
86dc4139 5137+
86dc4139 5138+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5527c038 5139+ h_dir = d_inode(h_parent);
86dc4139 5140+ IMustLock(h_dir);
523b37e3
AM
5141+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
5142+ /* no delegation since it is just created */
5143+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL);
86dc4139
AM
5144+ dput(h_path->dentry);
5145+
5146+out:
5147+ return err;
5148+}
5149+
1facf9fc 5150+/*
5151+ * copyup the @dentry from @bsrc to @bdst.
5152+ * the caller must set the both of lower dentries.
5153+ * @len is for truncating when it is -1 copyup the entire file.
5154+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 5155+ * basic->bsrc can be larger than basic->bdst.
1facf9fc 5156+ */
c2b27bf2 5157+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5158+{
5159+ int err, rerr;
5160+ aufs_bindex_t old_ibstart;
5161+ unsigned char isdir, plink;
1facf9fc 5162+ struct dentry *h_src, *h_dst, *h_parent;
5527c038 5163+ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode;
1facf9fc 5164+ struct super_block *sb;
86dc4139 5165+ struct au_branch *br;
c2b27bf2
AM
5166+ /* to reuduce stack size */
5167+ struct {
5168+ struct au_dtime dt;
5169+ struct path h_path;
5170+ struct au_cpup_reg_attr h_src_attr;
5171+ } *a;
1facf9fc 5172+
c2b27bf2
AM
5173+ err = -ENOMEM;
5174+ a = kmalloc(sizeof(*a), GFP_NOFS);
5175+ if (unlikely(!a))
5176+ goto out;
5177+ a->h_src_attr.valid = 0;
1facf9fc 5178+
c2b27bf2
AM
5179+ sb = cpg->dentry->d_sb;
5180+ br = au_sbr(sb, cpg->bdst);
5181+ a->h_path.mnt = au_br_mnt(br);
5182+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 5183+ h_parent = h_dst->d_parent; /* dir inode is locked */
5527c038 5184+ h_dir = d_inode(h_parent);
1facf9fc 5185+ IMustLock(h_dir);
5186+
c2b27bf2 5187+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038 5188+ inode = d_inode(cpg->dentry);
1facf9fc 5189+
5190+ if (!dst_parent)
c2b27bf2 5191+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 5192+ else
5193+ dget(dst_parent);
5194+
5195+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 5196+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 5197+ if (dst_inode) {
5198+ if (unlikely(!plink)) {
5199+ err = -EIO;
027c5e7a
AM
5200+ AuIOErr("hi%lu(i%lu) exists on b%d "
5201+ "but plink is disabled\n",
c2b27bf2
AM
5202+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
5203+ goto out_parent;
1facf9fc 5204+ }
5205+
5206+ if (dst_inode->i_nlink) {
c2b27bf2 5207+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5208+
c2b27bf2 5209+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 5210+ err = PTR_ERR(h_src);
5211+ if (IS_ERR(h_src))
c2b27bf2 5212+ goto out_parent;
5527c038 5213+ if (unlikely(d_is_negative(h_src))) {
1facf9fc 5214+ err = -EIO;
79b8bda9 5215+ AuIOErr("i%lu exists on b%d "
027c5e7a 5216+ "but not pseudo-linked\n",
79b8bda9 5217+ inode->i_ino, cpg->bdst);
1facf9fc 5218+ dput(h_src);
c2b27bf2 5219+ goto out_parent;
1facf9fc 5220+ }
5221+
5222+ if (do_dt) {
c2b27bf2
AM
5223+ a->h_path.dentry = h_parent;
5224+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 5225+ }
86dc4139 5226+
c2b27bf2 5227+ a->h_path.dentry = h_dst;
523b37e3
AM
5228+ delegated = NULL;
5229+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 5230+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 5231+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 5232+ if (do_dt)
c2b27bf2 5233+ au_dtime_revert(&a->dt);
523b37e3
AM
5234+ if (unlikely(err == -EWOULDBLOCK)) {
5235+ pr_warn("cannot retry for NFSv4 delegation"
5236+ " for an internal link\n");
5237+ iput(delegated);
5238+ }
1facf9fc 5239+ dput(h_src);
c2b27bf2 5240+ goto out_parent;
1facf9fc 5241+ } else
5242+ /* todo: cpup_wh_file? */
5243+ /* udba work */
4a4d8108 5244+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 5245+ }
5246+
86dc4139 5247+ isdir = S_ISDIR(inode->i_mode);
1facf9fc 5248+ old_ibstart = au_ibstart(inode);
c2b27bf2 5249+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 5250+ if (unlikely(err))
86dc4139 5251+ goto out_rev;
5527c038 5252+ dst_inode = d_inode(h_dst);
1facf9fc 5253+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
86dc4139 5254+ /* todo: necessary? */
c2b27bf2 5255+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 5256+
c2b27bf2 5257+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
5258+ if (unlikely(err)) {
5259+ /* todo: necessary? */
c2b27bf2 5260+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
86dc4139
AM
5261+ mutex_unlock(&dst_inode->i_mutex);
5262+ goto out_rev;
5263+ }
5264+
c2b27bf2 5265+ if (cpg->bdst < old_ibstart) {
86dc4139 5266+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 5267+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 5268+ if (unlikely(err)) {
c2b27bf2
AM
5269+ /* ignore an error */
5270+ /* au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
5271+ mutex_unlock(&dst_inode->i_mutex);
5272+ goto out_rev;
4a4d8108 5273+ }
4a4d8108 5274+ }
c2b27bf2
AM
5275+ au_set_ibstart(inode, cpg->bdst);
5276+ } else
5277+ au_set_ibend(inode, cpg->bdst);
5278+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
5279+ au_hi_flags(inode, isdir));
5280+
5281+ /* todo: necessary? */
c2b27bf2 5282+ /* err = au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
5283+ mutex_unlock(&dst_inode->i_mutex);
5284+ if (unlikely(err))
5285+ goto out_rev;
5286+
5527c038 5287+ src_inode = d_inode(h_src);
86dc4139 5288+ if (!isdir
5527c038
JR
5289+ && (src_inode->i_nlink > 1
5290+ || src_inode->i_state & I_LINKABLE)
86dc4139 5291+ && plink)
c2b27bf2 5292+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 5293+
c2b27bf2
AM
5294+ if (au_ftest_cpup(cpg->flags, RENAME)) {
5295+ a->h_path.dentry = h_dst;
392086de 5296+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
5297+ }
5298+ if (!err)
c2b27bf2 5299+ goto out_parent; /* success */
1facf9fc 5300+
5301+ /* revert */
4a4d8108 5302+out_rev:
c2b27bf2
AM
5303+ a->h_path.dentry = h_parent;
5304+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5305+ a->h_path.dentry = h_dst;
86dc4139 5306+ rerr = 0;
5527c038 5307+ if (d_is_positive(h_dst)) {
523b37e3
AM
5308+ if (!isdir) {
5309+ /* no delegation since it is just created */
5310+ rerr = vfsub_unlink(h_dir, &a->h_path,
5311+ /*delegated*/NULL, /*force*/0);
5312+ } else
c2b27bf2 5313+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 5314+ }
c2b27bf2 5315+ au_dtime_revert(&a->dt);
1facf9fc 5316+ if (rerr) {
5317+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
5318+ err = -EIO;
5319+ }
c2b27bf2 5320+out_parent:
1facf9fc 5321+ dput(dst_parent);
c2b27bf2
AM
5322+ kfree(a);
5323+out:
1facf9fc 5324+ return err;
5325+}
5326+
7e9cd9fe 5327+#if 0 /* reserved */
1facf9fc 5328+struct au_cpup_single_args {
5329+ int *errp;
c2b27bf2 5330+ struct au_cp_generic *cpg;
1facf9fc 5331+ struct dentry *dst_parent;
5332+};
5333+
5334+static void au_call_cpup_single(void *args)
5335+{
5336+ struct au_cpup_single_args *a = args;
86dc4139 5337+
c2b27bf2
AM
5338+ au_pin_hdir_acquire_nest(a->cpg->pin);
5339+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
5340+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5341+}
c2b27bf2 5342+#endif
1facf9fc 5343+
53392da6
AM
5344+/*
5345+ * prevent SIGXFSZ in copy-up.
5346+ * testing CAP_MKNOD is for generic fs,
5347+ * but CAP_FSETID is for xfs only, currently.
5348+ */
86dc4139 5349+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
5350+{
5351+ int do_sio;
86dc4139
AM
5352+ struct super_block *sb;
5353+ struct inode *h_dir;
53392da6
AM
5354+
5355+ do_sio = 0;
86dc4139 5356+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
5357+ if (!au_wkq_test()
5358+ && (!au_sbi(sb)->si_plink_maint_pid
5359+ || au_plink_maint(sb, AuLock_NOPLM))) {
5360+ switch (mode & S_IFMT) {
5361+ case S_IFREG:
5362+ /* no condition about RLIMIT_FSIZE and the file size */
5363+ do_sio = 1;
5364+ break;
5365+ case S_IFCHR:
5366+ case S_IFBLK:
5367+ do_sio = !capable(CAP_MKNOD);
5368+ break;
5369+ }
5370+ if (!do_sio)
5371+ do_sio = ((mode & (S_ISUID | S_ISGID))
5372+ && !capable(CAP_FSETID));
86dc4139
AM
5373+ /* this workaround may be removed in the future */
5374+ if (!do_sio) {
5375+ h_dir = au_pinned_h_dir(pin);
5376+ do_sio = h_dir->i_mode & S_ISVTX;
5377+ }
53392da6
AM
5378+ }
5379+
5380+ return do_sio;
5381+}
5382+
7e9cd9fe 5383+#if 0 /* reserved */
c2b27bf2 5384+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5385+{
5386+ int err, wkq_err;
1facf9fc 5387+ struct dentry *h_dentry;
5388+
c2b27bf2 5389+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
5527c038 5390+ if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode))
c2b27bf2 5391+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 5392+ else {
5393+ struct au_cpup_single_args args = {
5394+ .errp = &err,
c2b27bf2
AM
5395+ .cpg = cpg,
5396+ .dst_parent = dst_parent
1facf9fc 5397+ };
5398+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
5399+ if (unlikely(wkq_err))
5400+ err = wkq_err;
5401+ }
5402+
5403+ return err;
5404+}
c2b27bf2 5405+#endif
1facf9fc 5406+
5407+/*
5408+ * copyup the @dentry from the first active lower branch to @bdst,
5409+ * using au_cpup_single().
5410+ */
c2b27bf2 5411+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5412+{
5413+ int err;
c2b27bf2
AM
5414+ unsigned int flags_orig;
5415+ struct dentry *dentry;
5416+
5417+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 5418+
c2b27bf2 5419+ dentry = cpg->dentry;
86dc4139 5420+ DiMustWriteLock(dentry);
1facf9fc 5421+
c2b27bf2 5422+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 5423+ if (!err) {
c2b27bf2
AM
5424+ flags_orig = cpg->flags;
5425+ au_fset_cpup(cpg->flags, RENAME);
5426+ err = au_cpup_single(cpg, NULL);
5427+ cpg->flags = flags_orig;
1facf9fc 5428+ if (!err)
5429+ return 0; /* success */
5430+
5431+ /* revert */
c2b27bf2
AM
5432+ au_set_h_dptr(dentry, cpg->bdst, NULL);
5433+ au_set_dbstart(dentry, cpg->bsrc);
1facf9fc 5434+ }
5435+
5436+ return err;
5437+}
5438+
5439+struct au_cpup_simple_args {
5440+ int *errp;
c2b27bf2 5441+ struct au_cp_generic *cpg;
1facf9fc 5442+};
5443+
5444+static void au_call_cpup_simple(void *args)
5445+{
5446+ struct au_cpup_simple_args *a = args;
86dc4139 5447+
c2b27bf2
AM
5448+ au_pin_hdir_acquire_nest(a->cpg->pin);
5449+ *a->errp = au_cpup_simple(a->cpg);
5450+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5451+}
5452+
c2b27bf2 5453+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5454+{
5455+ int err, wkq_err;
c2b27bf2
AM
5456+ struct dentry *dentry, *parent;
5457+ struct file *h_file;
1facf9fc 5458+ struct inode *h_dir;
5459+
c2b27bf2
AM
5460+ dentry = cpg->dentry;
5461+ h_file = NULL;
5462+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
5463+ AuDebugOn(cpg->bsrc < 0);
392086de 5464+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
5465+ err = PTR_ERR(h_file);
5466+ if (IS_ERR(h_file))
5467+ goto out;
5468+ }
5469+
1facf9fc 5470+ parent = dget_parent(dentry);
5527c038 5471+ h_dir = au_h_iptr(d_inode(parent), cpg->bdst);
53392da6 5472+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
5527c038 5473+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
c2b27bf2 5474+ err = au_cpup_simple(cpg);
1facf9fc 5475+ else {
5476+ struct au_cpup_simple_args args = {
5477+ .errp = &err,
c2b27bf2 5478+ .cpg = cpg
1facf9fc 5479+ };
5480+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
5481+ if (unlikely(wkq_err))
5482+ err = wkq_err;
5483+ }
5484+
5485+ dput(parent);
c2b27bf2
AM
5486+ if (h_file)
5487+ au_h_open_post(dentry, cpg->bsrc, h_file);
5488+
5489+out:
1facf9fc 5490+ return err;
5491+}
5492+
c2b27bf2 5493+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 5494+{
c2b27bf2
AM
5495+ aufs_bindex_t bsrc, bend;
5496+ struct dentry *dentry, *h_dentry;
367653fa 5497+
c2b27bf2
AM
5498+ if (cpg->bsrc < 0) {
5499+ dentry = cpg->dentry;
5500+ bend = au_dbend(dentry);
5501+ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
5502+ h_dentry = au_h_dptr(dentry, bsrc);
5503+ if (h_dentry) {
5527c038 5504+ AuDebugOn(d_is_negative(h_dentry));
c2b27bf2
AM
5505+ break;
5506+ }
5507+ }
5508+ AuDebugOn(bsrc > bend);
5509+ cpg->bsrc = bsrc;
367653fa 5510+ }
c2b27bf2
AM
5511+ AuDebugOn(cpg->bsrc <= cpg->bdst);
5512+ return au_do_sio_cpup_simple(cpg);
5513+}
367653fa 5514+
c2b27bf2
AM
5515+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
5516+{
5517+ AuDebugOn(cpg->bdst <= cpg->bsrc);
5518+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
5519+}
5520+
1facf9fc 5521+/* ---------------------------------------------------------------------- */
5522+
5523+/*
5524+ * copyup the deleted file for writing.
5525+ */
c2b27bf2
AM
5526+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
5527+ struct file *file)
1facf9fc 5528+{
5529+ int err;
c2b27bf2
AM
5530+ unsigned int flags_orig;
5531+ aufs_bindex_t bsrc_orig;
1facf9fc 5532+ struct dentry *h_d_dst, *h_d_start;
c2b27bf2 5533+ struct au_dinfo *dinfo;
4a4d8108 5534+ struct au_hdentry *hdp;
1facf9fc 5535+
c2b27bf2 5536+ dinfo = au_di(cpg->dentry);
1308ab2a 5537+ AuRwMustWriteLock(&dinfo->di_rwsem);
5538+
c2b27bf2
AM
5539+ bsrc_orig = cpg->bsrc;
5540+ cpg->bsrc = dinfo->di_bstart;
4a4d8108 5541+ hdp = dinfo->di_hdentry;
c2b27bf2
AM
5542+ h_d_dst = hdp[0 + cpg->bdst].hd_dentry;
5543+ dinfo->di_bstart = cpg->bdst;
5544+ hdp[0 + cpg->bdst].hd_dentry = wh_dentry;
86dc4139 5545+ h_d_start = NULL;
027c5e7a 5546+ if (file) {
c2b27bf2 5547+ h_d_start = hdp[0 + cpg->bsrc].hd_dentry;
2000de60 5548+ hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_path.dentry;
027c5e7a 5549+ }
c2b27bf2
AM
5550+ flags_orig = cpg->flags;
5551+ cpg->flags = !AuCpup_DTIME;
5552+ err = au_cpup_single(cpg, /*h_parent*/NULL);
5553+ cpg->flags = flags_orig;
027c5e7a
AM
5554+ if (file) {
5555+ if (!err)
5556+ err = au_reopen_nondir(file);
c2b27bf2 5557+ hdp[0 + cpg->bsrc].hd_dentry = h_d_start;
1facf9fc 5558+ }
c2b27bf2
AM
5559+ hdp[0 + cpg->bdst].hd_dentry = h_d_dst;
5560+ dinfo->di_bstart = cpg->bsrc;
5561+ cpg->bsrc = bsrc_orig;
1facf9fc 5562+
5563+ return err;
5564+}
5565+
c2b27bf2 5566+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5567+{
5568+ int err;
c2b27bf2 5569+ aufs_bindex_t bdst;
1facf9fc 5570+ struct au_dtime dt;
c2b27bf2 5571+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 5572+ struct au_branch *br;
5573+ struct path h_path;
5574+
c2b27bf2
AM
5575+ dentry = cpg->dentry;
5576+ bdst = cpg->bdst;
1facf9fc 5577+ br = au_sbr(dentry->d_sb, bdst);
5578+ parent = dget_parent(dentry);
5579+ h_parent = au_h_dptr(parent, bdst);
5580+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
5581+ err = PTR_ERR(wh_dentry);
5582+ if (IS_ERR(wh_dentry))
5583+ goto out;
5584+
5585+ h_path.dentry = h_parent;
86dc4139 5586+ h_path.mnt = au_br_mnt(br);
1facf9fc 5587+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 5588+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 5589+ if (unlikely(err))
5590+ goto out_wh;
5591+
5592+ dget(wh_dentry);
5593+ h_path.dentry = wh_dentry;
2000de60 5594+ if (!d_is_dir(wh_dentry)) {
523b37e3 5595+ /* no delegation since it is just created */
5527c038 5596+ err = vfsub_unlink(d_inode(h_parent), &h_path,
523b37e3
AM
5597+ /*delegated*/NULL, /*force*/0);
5598+ } else
5527c038 5599+ err = vfsub_rmdir(d_inode(h_parent), &h_path);
1facf9fc 5600+ if (unlikely(err)) {
523b37e3
AM
5601+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
5602+ wh_dentry, err);
1facf9fc 5603+ err = -EIO;
5604+ }
5605+ au_dtime_revert(&dt);
5527c038 5606+ au_set_hi_wh(d_inode(dentry), bdst, wh_dentry);
1facf9fc 5607+
4f0767ce 5608+out_wh:
1facf9fc 5609+ dput(wh_dentry);
4f0767ce 5610+out:
1facf9fc 5611+ dput(parent);
5612+ return err;
5613+}
5614+
5615+struct au_cpup_wh_args {
5616+ int *errp;
c2b27bf2 5617+ struct au_cp_generic *cpg;
1facf9fc 5618+ struct file *file;
5619+};
5620+
5621+static void au_call_cpup_wh(void *args)
5622+{
5623+ struct au_cpup_wh_args *a = args;
86dc4139 5624+
c2b27bf2
AM
5625+ au_pin_hdir_acquire_nest(a->cpg->pin);
5626+ *a->errp = au_cpup_wh(a->cpg, a->file);
5627+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5628+}
5629+
c2b27bf2 5630+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5631+{
5632+ int err, wkq_err;
c2b27bf2 5633+ aufs_bindex_t bdst;
c1595e42 5634+ struct dentry *dentry, *parent, *h_orph, *h_parent;
86dc4139 5635+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 5636+ struct au_wbr *wbr;
c2b27bf2 5637+ struct au_pin wh_pin, *pin_orig;
1facf9fc 5638+
c2b27bf2
AM
5639+ dentry = cpg->dentry;
5640+ bdst = cpg->bdst;
1facf9fc 5641+ parent = dget_parent(dentry);
5527c038 5642+ dir = d_inode(parent);
1facf9fc 5643+ h_orph = NULL;
5644+ h_parent = NULL;
5645+ h_dir = au_igrab(au_h_iptr(dir, bdst));
5646+ h_tmpdir = h_dir;
c2b27bf2 5647+ pin_orig = NULL;
1facf9fc 5648+ if (!h_dir->i_nlink) {
5649+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
5650+ h_orph = wbr->wbr_orph;
5651+
5652+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 5653+ au_set_h_dptr(parent, bdst, dget(h_orph));
5527c038 5654+ h_tmpdir = d_inode(h_orph);
1facf9fc 5655+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
5656+
dece6358 5657+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4a4d8108 5658+ /* todo: au_h_open_pre()? */
86dc4139 5659+
c2b27bf2 5660+ pin_orig = cpg->pin;
86dc4139 5661+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
5662+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
5663+ cpg->pin = &wh_pin;
1facf9fc 5664+ }
5665+
53392da6 5666+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
5527c038 5667+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode))
c2b27bf2 5668+ err = au_cpup_wh(cpg, file);
1facf9fc 5669+ else {
5670+ struct au_cpup_wh_args args = {
5671+ .errp = &err,
c2b27bf2
AM
5672+ .cpg = cpg,
5673+ .file = file
1facf9fc 5674+ };
5675+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
5676+ if (unlikely(wkq_err))
5677+ err = wkq_err;
5678+ }
5679+
5680+ if (h_orph) {
5681+ mutex_unlock(&h_tmpdir->i_mutex);
4a4d8108 5682+ /* todo: au_h_open_post()? */
1facf9fc 5683+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 5684+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
5685+ AuDebugOn(!pin_orig);
5686+ cpg->pin = pin_orig;
1facf9fc 5687+ }
5688+ iput(h_dir);
5689+ dput(parent);
5690+
5691+ return err;
5692+}
5693+
5694+/* ---------------------------------------------------------------------- */
5695+
5696+/*
5697+ * generic routine for both of copy-up and copy-down.
5698+ */
5699+/* cf. revalidate function in file.c */
5700+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5701+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5702+ struct au_pin *pin,
1facf9fc 5703+ struct dentry *h_parent, void *arg),
5704+ void *arg)
5705+{
5706+ int err;
5707+ struct au_pin pin;
5527c038 5708+ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry;
1facf9fc 5709+
5710+ err = 0;
5711+ parent = dget_parent(dentry);
5712+ if (IS_ROOT(parent))
5713+ goto out;
5714+
5715+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
5716+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
5717+
5718+ /* do not use au_dpage */
5719+ real_parent = parent;
5720+ while (1) {
5721+ dput(parent);
5722+ parent = dget_parent(dentry);
5723+ h_parent = au_h_dptr(parent, bdst);
5724+ if (h_parent)
5725+ goto out; /* success */
5726+
5727+ /* find top dir which is necessary to cpup */
5728+ do {
5729+ d = parent;
5730+ dput(parent);
5731+ parent = dget_parent(d);
5732+ di_read_lock_parent3(parent, !AuLock_IR);
5733+ h_parent = au_h_dptr(parent, bdst);
5734+ di_read_unlock(parent, !AuLock_IR);
5735+ } while (!h_parent);
5736+
5737+ if (d != real_parent)
5738+ di_write_lock_child3(d);
5739+
5740+ /* somebody else might create while we were sleeping */
5527c038
JR
5741+ h_dentry = au_h_dptr(d, bdst);
5742+ if (!h_dentry || d_is_negative(h_dentry)) {
5743+ if (h_dentry)
1facf9fc 5744+ au_update_dbstart(d);
5745+
5746+ au_pin_set_dentry(&pin, d);
5747+ err = au_do_pin(&pin);
5748+ if (!err) {
86dc4139 5749+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 5750+ au_unpin(&pin);
5751+ }
5752+ }
5753+
5754+ if (d != real_parent)
5755+ di_write_unlock(d);
5756+ if (unlikely(err))
5757+ break;
5758+ }
5759+
4f0767ce 5760+out:
1facf9fc 5761+ dput(parent);
5762+ return err;
5763+}
5764+
5765+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5766+ struct au_pin *pin,
2000de60 5767+ struct dentry *h_parent __maybe_unused,
1facf9fc 5768+ void *arg __maybe_unused)
5769+{
c2b27bf2
AM
5770+ struct au_cp_generic cpg = {
5771+ .dentry = dentry,
5772+ .bdst = bdst,
5773+ .bsrc = -1,
5774+ .len = 0,
5775+ .pin = pin,
5776+ .flags = AuCpup_DTIME
5777+ };
5778+ return au_sio_cpup_simple(&cpg);
1facf9fc 5779+}
5780+
5781+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5782+{
5783+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
5784+}
5785+
5786+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5787+{
5788+ int err;
5789+ struct dentry *parent;
5790+ struct inode *dir;
5791+
5792+ parent = dget_parent(dentry);
5527c038 5793+ dir = d_inode(parent);
1facf9fc 5794+ err = 0;
5795+ if (au_h_iptr(dir, bdst))
5796+ goto out;
5797+
5798+ di_read_unlock(parent, AuLock_IR);
5799+ di_write_lock_parent(parent);
5800+ /* someone else might change our inode while we were sleeping */
5801+ if (!au_h_iptr(dir, bdst))
5802+ err = au_cpup_dirs(dentry, bdst);
5803+ di_downgrade_lock(parent, AuLock_IR);
5804+
4f0767ce 5805+out:
1facf9fc 5806+ dput(parent);
5807+ return err;
5808+}
7f207e10
AM
5809diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
5810--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 5811+++ linux/fs/aufs/cpup.h 2015-09-24 10:47:58.248052907 +0200
523b37e3 5812@@ -0,0 +1,94 @@
1facf9fc 5813+/*
2000de60 5814+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 5815+ *
5816+ * This program, aufs is free software; you can redistribute it and/or modify
5817+ * it under the terms of the GNU General Public License as published by
5818+ * the Free Software Foundation; either version 2 of the License, or
5819+ * (at your option) any later version.
dece6358
AM
5820+ *
5821+ * This program is distributed in the hope that it will be useful,
5822+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5823+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5824+ * GNU General Public License for more details.
5825+ *
5826+ * You should have received a copy of the GNU General Public License
523b37e3 5827+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5828+ */
5829+
5830+/*
5831+ * copy-up/down functions
5832+ */
5833+
5834+#ifndef __AUFS_CPUP_H__
5835+#define __AUFS_CPUP_H__
5836+
5837+#ifdef __KERNEL__
5838+
dece6358 5839+#include <linux/path.h>
1facf9fc 5840+
dece6358
AM
5841+struct inode;
5842+struct file;
86dc4139 5843+struct au_pin;
dece6358 5844+
86dc4139 5845+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 5846+void au_cpup_attr_timesizes(struct inode *inode);
5847+void au_cpup_attr_nlink(struct inode *inode, int force);
5848+void au_cpup_attr_changeable(struct inode *inode);
5849+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
5850+void au_cpup_attr_all(struct inode *inode, int force);
5851+
5852+/* ---------------------------------------------------------------------- */
5853+
c2b27bf2
AM
5854+struct au_cp_generic {
5855+ struct dentry *dentry;
5856+ aufs_bindex_t bdst, bsrc;
5857+ loff_t len;
5858+ struct au_pin *pin;
5859+ unsigned int flags;
5860+};
5861+
1facf9fc 5862+/* cpup flags */
392086de
AM
5863+#define AuCpup_DTIME 1 /* do dtime_store/revert */
5864+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
5865+ for link(2) */
5866+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
5867+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
5868+ cpup */
5869+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
5870+ existing entry */
5871+#define AuCpup_RWDST (1 << 5) /* force write target even if
5872+ the branch is marked as RO */
c2b27bf2 5873+
1facf9fc 5874+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
5875+#define au_fset_cpup(flags, name) \
5876+ do { (flags) |= AuCpup_##name; } while (0)
5877+#define au_fclr_cpup(flags, name) \
5878+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 5879+
5880+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
5881+int au_sio_cpup_simple(struct au_cp_generic *cpg);
5882+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
5883+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 5884+
5885+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5886+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5887+ struct au_pin *pin,
1facf9fc 5888+ struct dentry *h_parent, void *arg),
5889+ void *arg);
5890+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5891+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5892+
5893+/* ---------------------------------------------------------------------- */
5894+
5895+/* keep timestamps when copyup */
5896+struct au_dtime {
5897+ struct dentry *dt_dentry;
5898+ struct path dt_h_path;
5899+ struct timespec dt_atime, dt_mtime;
5900+};
5901+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
5902+ struct path *h_path);
5903+void au_dtime_revert(struct au_dtime *dt);
5904+
5905+#endif /* __KERNEL__ */
5906+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
5907diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
5908--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 5909+++ linux/fs/aufs/dbgaufs.c 2015-09-24 10:47:58.248052907 +0200
523b37e3 5910@@ -0,0 +1,432 @@
1facf9fc 5911+/*
2000de60 5912+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 5913+ *
5914+ * This program, aufs is free software; you can redistribute it and/or modify
5915+ * it under the terms of the GNU General Public License as published by
5916+ * the Free Software Foundation; either version 2 of the License, or
5917+ * (at your option) any later version.
dece6358
AM
5918+ *
5919+ * This program is distributed in the hope that it will be useful,
5920+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5921+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5922+ * GNU General Public License for more details.
5923+ *
5924+ * You should have received a copy of the GNU General Public License
523b37e3 5925+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5926+ */
5927+
5928+/*
5929+ * debugfs interface
5930+ */
5931+
5932+#include <linux/debugfs.h>
5933+#include "aufs.h"
5934+
5935+#ifndef CONFIG_SYSFS
5936+#error DEBUG_FS depends upon SYSFS
5937+#endif
5938+
5939+static struct dentry *dbgaufs;
5940+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
5941+
5942+/* 20 is max digits length of ulong 64 */
5943+struct dbgaufs_arg {
5944+ int n;
5945+ char a[20 * 4];
5946+};
5947+
5948+/*
5949+ * common function for all XINO files
5950+ */
5951+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
5952+ struct file *file)
5953+{
5954+ kfree(file->private_data);
5955+ return 0;
5956+}
5957+
5958+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
5959+{
5960+ int err;
5961+ struct kstat st;
5962+ struct dbgaufs_arg *p;
5963+
5964+ err = -ENOMEM;
5965+ p = kmalloc(sizeof(*p), GFP_NOFS);
5966+ if (unlikely(!p))
5967+ goto out;
5968+
5969+ err = 0;
5970+ p->n = 0;
5971+ file->private_data = p;
5972+ if (!xf)
5973+ goto out;
5974+
c06a8ce3 5975+ err = vfs_getattr(&xf->f_path, &st);
1facf9fc 5976+ if (!err) {
5977+ if (do_fcnt)
5978+ p->n = snprintf
5979+ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
5980+ (long)file_count(xf), st.blocks, st.blksize,
5981+ (long long)st.size);
5982+ else
5983+ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
5984+ st.blocks, st.blksize,
5985+ (long long)st.size);
5986+ AuDebugOn(p->n >= sizeof(p->a));
5987+ } else {
5988+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
5989+ err = 0;
5990+ }
5991+
4f0767ce 5992+out:
1facf9fc 5993+ return err;
5994+
5995+}
5996+
5997+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
5998+ size_t count, loff_t *ppos)
5999+{
6000+ struct dbgaufs_arg *p;
6001+
6002+ p = file->private_data;
6003+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6004+}
6005+
6006+/* ---------------------------------------------------------------------- */
6007+
86dc4139
AM
6008+struct dbgaufs_plink_arg {
6009+ int n;
6010+ char a[];
6011+};
6012+
6013+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
6014+ struct file *file)
6015+{
6016+ free_page((unsigned long)file->private_data);
6017+ return 0;
6018+}
6019+
6020+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
6021+{
6022+ int err, i, limit;
6023+ unsigned long n, sum;
6024+ struct dbgaufs_plink_arg *p;
6025+ struct au_sbinfo *sbinfo;
6026+ struct super_block *sb;
6027+ struct au_sphlhead *sphl;
6028+
6029+ err = -ENOMEM;
6030+ p = (void *)get_zeroed_page(GFP_NOFS);
6031+ if (unlikely(!p))
6032+ goto out;
6033+
6034+ err = -EFBIG;
6035+ sbinfo = inode->i_private;
6036+ sb = sbinfo->si_sb;
6037+ si_noflush_read_lock(sb);
6038+ if (au_opt_test(au_mntflags(sb), PLINK)) {
6039+ limit = PAGE_SIZE - sizeof(p->n);
6040+
6041+ /* the number of buckets */
6042+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
6043+ p->n += n;
6044+ limit -= n;
6045+
6046+ sum = 0;
6047+ for (i = 0, sphl = sbinfo->si_plink;
6048+ i < AuPlink_NHASH;
6049+ i++, sphl++) {
6050+ n = au_sphl_count(sphl);
6051+ sum += n;
6052+
6053+ n = snprintf(p->a + p->n, limit, "%lu ", n);
6054+ p->n += n;
6055+ limit -= n;
6056+ if (unlikely(limit <= 0))
6057+ goto out_free;
6058+ }
6059+ p->a[p->n - 1] = '\n';
6060+
6061+ /* the sum of plinks */
6062+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
6063+ p->n += n;
6064+ limit -= n;
6065+ if (unlikely(limit <= 0))
6066+ goto out_free;
6067+ } else {
6068+#define str "1\n0\n0\n"
6069+ p->n = sizeof(str) - 1;
6070+ strcpy(p->a, str);
6071+#undef str
6072+ }
6073+ si_read_unlock(sb);
6074+
6075+ err = 0;
6076+ file->private_data = p;
6077+ goto out; /* success */
6078+
6079+out_free:
6080+ free_page((unsigned long)p);
6081+out:
6082+ return err;
6083+}
6084+
6085+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
6086+ size_t count, loff_t *ppos)
6087+{
6088+ struct dbgaufs_plink_arg *p;
6089+
6090+ p = file->private_data;
6091+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
6092+}
6093+
6094+static const struct file_operations dbgaufs_plink_fop = {
6095+ .owner = THIS_MODULE,
6096+ .open = dbgaufs_plink_open,
6097+ .release = dbgaufs_plink_release,
6098+ .read = dbgaufs_plink_read
6099+};
6100+
6101+/* ---------------------------------------------------------------------- */
6102+
1facf9fc 6103+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
6104+{
6105+ int err;
6106+ struct au_sbinfo *sbinfo;
6107+ struct super_block *sb;
6108+
6109+ sbinfo = inode->i_private;
6110+ sb = sbinfo->si_sb;
6111+ si_noflush_read_lock(sb);
6112+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
6113+ si_read_unlock(sb);
6114+ return err;
6115+}
6116+
6117+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 6118+ .owner = THIS_MODULE,
1facf9fc 6119+ .open = dbgaufs_xib_open,
6120+ .release = dbgaufs_xi_release,
6121+ .read = dbgaufs_xi_read
6122+};
6123+
6124+/* ---------------------------------------------------------------------- */
6125+
6126+#define DbgaufsXi_PREFIX "xi"
6127+
6128+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
6129+{
6130+ int err;
6131+ long l;
6132+ struct au_sbinfo *sbinfo;
6133+ struct super_block *sb;
6134+ struct file *xf;
6135+ struct qstr *name;
6136+
6137+ err = -ENOENT;
6138+ xf = NULL;
2000de60 6139+ name = &file->f_path.dentry->d_name;
1facf9fc 6140+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
6141+ || memcmp(name->name, DbgaufsXi_PREFIX,
6142+ sizeof(DbgaufsXi_PREFIX) - 1)))
6143+ goto out;
9dbd164d 6144+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 6145+ if (unlikely(err))
6146+ goto out;
6147+
6148+ sbinfo = inode->i_private;
6149+ sb = sbinfo->si_sb;
6150+ si_noflush_read_lock(sb);
6151+ if (l <= au_sbend(sb)) {
6152+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
6153+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
6154+ } else
6155+ err = -ENOENT;
6156+ si_read_unlock(sb);
6157+
4f0767ce 6158+out:
1facf9fc 6159+ return err;
6160+}
6161+
6162+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 6163+ .owner = THIS_MODULE,
1facf9fc 6164+ .open = dbgaufs_xino_open,
6165+ .release = dbgaufs_xi_release,
6166+ .read = dbgaufs_xi_read
6167+};
6168+
6169+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
6170+{
6171+ aufs_bindex_t bend;
6172+ struct au_branch *br;
6173+ struct au_xino_file *xi;
6174+
6175+ if (!au_sbi(sb)->si_dbgaufs)
6176+ return;
6177+
6178+ bend = au_sbend(sb);
6179+ for (; bindex <= bend; bindex++) {
6180+ br = au_sbr(sb, bindex);
6181+ xi = &br->br_xino;
c06a8ce3
AM
6182+ debugfs_remove(xi->xi_dbgaufs);
6183+ xi->xi_dbgaufs = NULL;
1facf9fc 6184+ }
6185+}
6186+
6187+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
6188+{
6189+ struct au_sbinfo *sbinfo;
6190+ struct dentry *parent;
6191+ struct au_branch *br;
6192+ struct au_xino_file *xi;
6193+ aufs_bindex_t bend;
6194+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
6195+
6196+ sbinfo = au_sbi(sb);
6197+ parent = sbinfo->si_dbgaufs;
6198+ if (!parent)
6199+ return;
6200+
6201+ bend = au_sbend(sb);
6202+ for (; bindex <= bend; bindex++) {
6203+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
6204+ br = au_sbr(sb, bindex);
6205+ xi = &br->br_xino;
6206+ AuDebugOn(xi->xi_dbgaufs);
6207+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
6208+ sbinfo, &dbgaufs_xino_fop);
6209+ /* ignore an error */
6210+ if (unlikely(!xi->xi_dbgaufs))
6211+ AuWarn1("failed %s under debugfs\n", name);
6212+ }
6213+}
6214+
6215+/* ---------------------------------------------------------------------- */
6216+
6217+#ifdef CONFIG_AUFS_EXPORT
6218+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
6219+{
6220+ int err;
6221+ struct au_sbinfo *sbinfo;
6222+ struct super_block *sb;
6223+
6224+ sbinfo = inode->i_private;
6225+ sb = sbinfo->si_sb;
6226+ si_noflush_read_lock(sb);
6227+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
6228+ si_read_unlock(sb);
6229+ return err;
6230+}
6231+
6232+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 6233+ .owner = THIS_MODULE,
1facf9fc 6234+ .open = dbgaufs_xigen_open,
6235+ .release = dbgaufs_xi_release,
6236+ .read = dbgaufs_xi_read
6237+};
6238+
6239+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6240+{
6241+ int err;
6242+
dece6358 6243+ /*
c1595e42 6244+ * This function is a dynamic '__init' function actually,
dece6358
AM
6245+ * so the tiny check for si_rwsem is unnecessary.
6246+ */
6247+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6248+
1facf9fc 6249+ err = -EIO;
6250+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
6251+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6252+ &dbgaufs_xigen_fop);
6253+ if (sbinfo->si_dbgaufs_xigen)
6254+ err = 0;
6255+
6256+ return err;
6257+}
6258+#else
6259+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6260+{
6261+ return 0;
6262+}
6263+#endif /* CONFIG_AUFS_EXPORT */
6264+
6265+/* ---------------------------------------------------------------------- */
6266+
6267+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
6268+{
dece6358 6269+ /*
7e9cd9fe 6270+ * This function is a dynamic '__fin' function actually,
dece6358
AM
6271+ * so the tiny check for si_rwsem is unnecessary.
6272+ */
6273+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6274+
1facf9fc 6275+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
6276+ sbinfo->si_dbgaufs = NULL;
6277+ kobject_put(&sbinfo->si_kobj);
6278+}
6279+
6280+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
6281+{
6282+ int err;
6283+ char name[SysaufsSiNameLen];
6284+
dece6358 6285+ /*
c1595e42 6286+ * This function is a dynamic '__init' function actually,
dece6358
AM
6287+ * so the tiny check for si_rwsem is unnecessary.
6288+ */
6289+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6290+
1facf9fc 6291+ err = -ENOENT;
6292+ if (!dbgaufs) {
6293+ AuErr1("/debug/aufs is uninitialized\n");
6294+ goto out;
6295+ }
6296+
6297+ err = -EIO;
6298+ sysaufs_name(sbinfo, name);
6299+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
6300+ if (unlikely(!sbinfo->si_dbgaufs))
6301+ goto out;
6302+ kobject_get(&sbinfo->si_kobj);
6303+
6304+ sbinfo->si_dbgaufs_xib = debugfs_create_file
6305+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6306+ &dbgaufs_xib_fop);
6307+ if (unlikely(!sbinfo->si_dbgaufs_xib))
6308+ goto out_dir;
6309+
86dc4139
AM
6310+ sbinfo->si_dbgaufs_plink = debugfs_create_file
6311+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6312+ &dbgaufs_plink_fop);
6313+ if (unlikely(!sbinfo->si_dbgaufs_plink))
6314+ goto out_dir;
6315+
1facf9fc 6316+ err = dbgaufs_xigen_init(sbinfo);
6317+ if (!err)
6318+ goto out; /* success */
6319+
4f0767ce 6320+out_dir:
1facf9fc 6321+ dbgaufs_si_fin(sbinfo);
4f0767ce 6322+out:
1facf9fc 6323+ return err;
6324+}
6325+
6326+/* ---------------------------------------------------------------------- */
6327+
6328+void dbgaufs_fin(void)
6329+{
6330+ debugfs_remove(dbgaufs);
6331+}
6332+
6333+int __init dbgaufs_init(void)
6334+{
6335+ int err;
6336+
6337+ err = -EIO;
6338+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
6339+ if (dbgaufs)
6340+ err = 0;
6341+ return err;
6342+}
7f207e10
AM
6343diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
6344--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 6345+++ linux/fs/aufs/dbgaufs.h 2015-09-24 10:47:58.248052907 +0200
523b37e3 6346@@ -0,0 +1,48 @@
1facf9fc 6347+/*
2000de60 6348+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6349+ *
6350+ * This program, aufs is free software; you can redistribute it and/or modify
6351+ * it under the terms of the GNU General Public License as published by
6352+ * the Free Software Foundation; either version 2 of the License, or
6353+ * (at your option) any later version.
dece6358
AM
6354+ *
6355+ * This program is distributed in the hope that it will be useful,
6356+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6357+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6358+ * GNU General Public License for more details.
6359+ *
6360+ * You should have received a copy of the GNU General Public License
523b37e3 6361+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6362+ */
6363+
6364+/*
6365+ * debugfs interface
6366+ */
6367+
6368+#ifndef __DBGAUFS_H__
6369+#define __DBGAUFS_H__
6370+
6371+#ifdef __KERNEL__
6372+
dece6358 6373+struct super_block;
1facf9fc 6374+struct au_sbinfo;
dece6358 6375+
1facf9fc 6376+#ifdef CONFIG_DEBUG_FS
6377+/* dbgaufs.c */
6378+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
6379+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
6380+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
6381+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
6382+void dbgaufs_fin(void);
6383+int __init dbgaufs_init(void);
1facf9fc 6384+#else
4a4d8108
AM
6385+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
6386+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
6387+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
6388+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
6389+AuStubVoid(dbgaufs_fin, void)
6390+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 6391+#endif /* CONFIG_DEBUG_FS */
6392+
6393+#endif /* __KERNEL__ */
6394+#endif /* __DBGAUFS_H__ */
7f207e10
AM
6395diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
6396--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 6397+++ linux/fs/aufs/dcsub.c 2015-09-24 10:47:58.248052907 +0200
c1595e42 6398@@ -0,0 +1,224 @@
1facf9fc 6399+/*
2000de60 6400+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6401+ *
6402+ * This program, aufs is free software; you can redistribute it and/or modify
6403+ * it under the terms of the GNU General Public License as published by
6404+ * the Free Software Foundation; either version 2 of the License, or
6405+ * (at your option) any later version.
dece6358
AM
6406+ *
6407+ * This program is distributed in the hope that it will be useful,
6408+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6409+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6410+ * GNU General Public License for more details.
6411+ *
6412+ * You should have received a copy of the GNU General Public License
523b37e3 6413+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6414+ */
6415+
6416+/*
6417+ * sub-routines for dentry cache
6418+ */
6419+
6420+#include "aufs.h"
6421+
6422+static void au_dpage_free(struct au_dpage *dpage)
6423+{
6424+ int i;
6425+ struct dentry **p;
6426+
6427+ p = dpage->dentries;
6428+ for (i = 0; i < dpage->ndentry; i++)
6429+ dput(*p++);
6430+ free_page((unsigned long)dpage->dentries);
6431+}
6432+
6433+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
6434+{
6435+ int err;
6436+ void *p;
6437+
6438+ err = -ENOMEM;
6439+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
6440+ if (unlikely(!dpages->dpages))
6441+ goto out;
6442+
6443+ p = (void *)__get_free_page(gfp);
6444+ if (unlikely(!p))
6445+ goto out_dpages;
6446+
6447+ dpages->dpages[0].ndentry = 0;
6448+ dpages->dpages[0].dentries = p;
6449+ dpages->ndpage = 1;
6450+ return 0; /* success */
6451+
4f0767ce 6452+out_dpages:
1facf9fc 6453+ kfree(dpages->dpages);
4f0767ce 6454+out:
1facf9fc 6455+ return err;
6456+}
6457+
6458+void au_dpages_free(struct au_dcsub_pages *dpages)
6459+{
6460+ int i;
6461+ struct au_dpage *p;
6462+
6463+ p = dpages->dpages;
6464+ for (i = 0; i < dpages->ndpage; i++)
6465+ au_dpage_free(p++);
6466+ kfree(dpages->dpages);
6467+}
6468+
6469+static int au_dpages_append(struct au_dcsub_pages *dpages,
6470+ struct dentry *dentry, gfp_t gfp)
6471+{
6472+ int err, sz;
6473+ struct au_dpage *dpage;
6474+ void *p;
6475+
6476+ dpage = dpages->dpages + dpages->ndpage - 1;
6477+ sz = PAGE_SIZE / sizeof(dentry);
6478+ if (unlikely(dpage->ndentry >= sz)) {
6479+ AuLabel(new dpage);
6480+ err = -ENOMEM;
6481+ sz = dpages->ndpage * sizeof(*dpages->dpages);
6482+ p = au_kzrealloc(dpages->dpages, sz,
6483+ sz + sizeof(*dpages->dpages), gfp);
6484+ if (unlikely(!p))
6485+ goto out;
6486+
6487+ dpages->dpages = p;
6488+ dpage = dpages->dpages + dpages->ndpage;
6489+ p = (void *)__get_free_page(gfp);
6490+ if (unlikely(!p))
6491+ goto out;
6492+
6493+ dpage->ndentry = 0;
6494+ dpage->dentries = p;
6495+ dpages->ndpage++;
6496+ }
6497+
c1595e42 6498+ AuDebugOn(au_dcount(dentry) <= 0);
027c5e7a 6499+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 6500+ return 0; /* success */
6501+
4f0767ce 6502+out:
1facf9fc 6503+ return err;
6504+}
6505+
c1595e42
JR
6506+/* todo: BAD approach */
6507+/* copied from linux/fs/dcache.c */
6508+enum d_walk_ret {
6509+ D_WALK_CONTINUE,
6510+ D_WALK_QUIT,
6511+ D_WALK_NORETRY,
6512+ D_WALK_SKIP,
6513+};
6514+
6515+extern void d_walk(struct dentry *parent, void *data,
6516+ enum d_walk_ret (*enter)(void *, struct dentry *),
6517+ void (*finish)(void *));
6518+
6519+struct ac_dpages_arg {
1facf9fc 6520+ int err;
c1595e42
JR
6521+ struct au_dcsub_pages *dpages;
6522+ struct super_block *sb;
6523+ au_dpages_test test;
6524+ void *arg;
6525+};
1facf9fc 6526+
c1595e42
JR
6527+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry)
6528+{
6529+ enum d_walk_ret ret;
6530+ struct ac_dpages_arg *arg = _arg;
1facf9fc 6531+
c1595e42
JR
6532+ ret = D_WALK_CONTINUE;
6533+ if (dentry->d_sb == arg->sb
6534+ && !IS_ROOT(dentry)
6535+ && au_dcount(dentry) > 0
6536+ && au_di(dentry)
6537+ && (!arg->test || arg->test(dentry, arg->arg))) {
6538+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC);
6539+ if (unlikely(arg->err))
6540+ ret = D_WALK_QUIT;
1facf9fc 6541+ }
6542+
c1595e42
JR
6543+ return ret;
6544+}
027c5e7a 6545+
c1595e42
JR
6546+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6547+ au_dpages_test test, void *arg)
6548+{
6549+ struct ac_dpages_arg args = {
6550+ .err = 0,
6551+ .dpages = dpages,
6552+ .sb = root->d_sb,
6553+ .test = test,
6554+ .arg = arg
6555+ };
027c5e7a 6556+
c1595e42
JR
6557+ d_walk(root, &args, au_call_dpages_append, NULL);
6558+
6559+ return args.err;
1facf9fc 6560+}
6561+
6562+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6563+ int do_include, au_dpages_test test, void *arg)
6564+{
6565+ int err;
6566+
6567+ err = 0;
027c5e7a
AM
6568+ write_seqlock(&rename_lock);
6569+ spin_lock(&dentry->d_lock);
6570+ if (do_include
c1595e42 6571+ && au_dcount(dentry) > 0
027c5e7a 6572+ && (!test || test(dentry, arg)))
1facf9fc 6573+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6574+ spin_unlock(&dentry->d_lock);
6575+ if (unlikely(err))
6576+ goto out;
6577+
6578+ /*
523b37e3 6579+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
6580+ * mount
6581+ */
1facf9fc 6582+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
6583+ dentry = dentry->d_parent; /* rename_lock is locked */
6584+ spin_lock(&dentry->d_lock);
c1595e42 6585+ if (au_dcount(dentry) > 0
027c5e7a 6586+ && (!test || test(dentry, arg)))
1facf9fc 6587+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6588+ spin_unlock(&dentry->d_lock);
6589+ if (unlikely(err))
6590+ break;
1facf9fc 6591+ }
6592+
4f0767ce 6593+out:
027c5e7a 6594+ write_sequnlock(&rename_lock);
1facf9fc 6595+ return err;
6596+}
6597+
027c5e7a
AM
6598+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
6599+{
6600+ return au_di(dentry) && dentry->d_sb == arg;
6601+}
6602+
6603+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6604+ struct dentry *dentry, int do_include)
6605+{
6606+ return au_dcsub_pages_rev(dpages, dentry, do_include,
6607+ au_dcsub_dpages_aufs, dentry->d_sb);
6608+}
6609+
4a4d8108 6610+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 6611+{
4a4d8108
AM
6612+ struct path path[2] = {
6613+ {
6614+ .dentry = d1
6615+ },
6616+ {
6617+ .dentry = d2
6618+ }
6619+ };
1facf9fc 6620+
4a4d8108 6621+ return path_is_under(path + 0, path + 1);
1facf9fc 6622+}
7f207e10
AM
6623diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
6624--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 6625+++ linux/fs/aufs/dcsub.h 2015-09-24 10:47:58.251386326 +0200
5527c038 6626@@ -0,0 +1,136 @@
1facf9fc 6627+/*
2000de60 6628+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6629+ *
6630+ * This program, aufs is free software; you can redistribute it and/or modify
6631+ * it under the terms of the GNU General Public License as published by
6632+ * the Free Software Foundation; either version 2 of the License, or
6633+ * (at your option) any later version.
dece6358
AM
6634+ *
6635+ * This program is distributed in the hope that it will be useful,
6636+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6637+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6638+ * GNU General Public License for more details.
6639+ *
6640+ * You should have received a copy of the GNU General Public License
523b37e3 6641+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6642+ */
6643+
6644+/*
6645+ * sub-routines for dentry cache
6646+ */
6647+
6648+#ifndef __AUFS_DCSUB_H__
6649+#define __AUFS_DCSUB_H__
6650+
6651+#ifdef __KERNEL__
6652+
7f207e10 6653+#include <linux/dcache.h>
027c5e7a 6654+#include <linux/fs.h>
dece6358 6655+
1facf9fc 6656+struct au_dpage {
6657+ int ndentry;
6658+ struct dentry **dentries;
6659+};
6660+
6661+struct au_dcsub_pages {
6662+ int ndpage;
6663+ struct au_dpage *dpages;
6664+};
6665+
6666+/* ---------------------------------------------------------------------- */
6667+
7f207e10 6668+/* dcsub.c */
1facf9fc 6669+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
6670+void au_dpages_free(struct au_dcsub_pages *dpages);
6671+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
6672+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6673+ au_dpages_test test, void *arg);
6674+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6675+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
6676+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6677+ struct dentry *dentry, int do_include);
4a4d8108 6678+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 6679+
7f207e10
AM
6680+/* ---------------------------------------------------------------------- */
6681+
523b37e3
AM
6682+/*
6683+ * todo: in linux-3.13, several similar (but faster) helpers are added to
6684+ * include/linux/dcache.h. Try them (in the future).
6685+ */
6686+
027c5e7a
AM
6687+static inline int au_d_hashed_positive(struct dentry *d)
6688+{
6689+ int err;
5527c038 6690+ struct inode *inode = d_inode(d);
076b876e 6691+
027c5e7a 6692+ err = 0;
5527c038
JR
6693+ if (unlikely(d_unhashed(d)
6694+ || d_is_negative(d)
6695+ || !inode->i_nlink))
027c5e7a
AM
6696+ err = -ENOENT;
6697+ return err;
6698+}
6699+
38d290e6
JR
6700+static inline int au_d_linkable(struct dentry *d)
6701+{
6702+ int err;
5527c038 6703+ struct inode *inode = d_inode(d);
076b876e 6704+
38d290e6
JR
6705+ err = au_d_hashed_positive(d);
6706+ if (err
5527c038 6707+ && d_is_positive(d)
38d290e6
JR
6708+ && (inode->i_state & I_LINKABLE))
6709+ err = 0;
6710+ return err;
6711+}
6712+
027c5e7a
AM
6713+static inline int au_d_alive(struct dentry *d)
6714+{
6715+ int err;
6716+ struct inode *inode;
076b876e 6717+
027c5e7a
AM
6718+ err = 0;
6719+ if (!IS_ROOT(d))
6720+ err = au_d_hashed_positive(d);
6721+ else {
5527c038
JR
6722+ inode = d_inode(d);
6723+ if (unlikely(d_unlinked(d)
6724+ || d_is_negative(d)
6725+ || !inode->i_nlink))
027c5e7a
AM
6726+ err = -ENOENT;
6727+ }
6728+ return err;
6729+}
6730+
6731+static inline int au_alive_dir(struct dentry *d)
7f207e10 6732+{
027c5e7a 6733+ int err;
076b876e 6734+
027c5e7a 6735+ err = au_d_alive(d);
5527c038 6736+ if (unlikely(err || IS_DEADDIR(d_inode(d))))
027c5e7a
AM
6737+ err = -ENOENT;
6738+ return err;
7f207e10
AM
6739+}
6740+
38d290e6
JR
6741+static inline int au_qstreq(struct qstr *a, struct qstr *b)
6742+{
6743+ return a->len == b->len
6744+ && !memcmp(a->name, b->name, a->len);
6745+}
6746+
7e9cd9fe
AM
6747+/*
6748+ * by the commit
6749+ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without
6750+ * taking d_lock
6751+ * the type of d_lockref.count became int, but the inlined function d_count()
6752+ * still returns unsigned int.
6753+ * I don't know why. Maybe it is for every d_count() users?
6754+ * Anyway au_dcount() lives on.
6755+ */
c1595e42
JR
6756+static inline int au_dcount(struct dentry *d)
6757+{
6758+ return (int)d_count(d);
6759+}
6760+
1facf9fc 6761+#endif /* __KERNEL__ */
6762+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
6763diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
6764--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 6765+++ linux/fs/aufs/debug.c 2015-09-24 10:47:58.251386326 +0200
5527c038 6766@@ -0,0 +1,440 @@
1facf9fc 6767+/*
2000de60 6768+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6769+ *
6770+ * This program, aufs is free software; you can redistribute it and/or modify
6771+ * it under the terms of the GNU General Public License as published by
6772+ * the Free Software Foundation; either version 2 of the License, or
6773+ * (at your option) any later version.
dece6358
AM
6774+ *
6775+ * This program is distributed in the hope that it will be useful,
6776+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6777+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6778+ * GNU General Public License for more details.
6779+ *
6780+ * You should have received a copy of the GNU General Public License
523b37e3 6781+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6782+ */
6783+
6784+/*
6785+ * debug print functions
6786+ */
6787+
6788+#include "aufs.h"
6789+
392086de
AM
6790+/* Returns 0, or -errno. arg is in kp->arg. */
6791+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
6792+{
6793+ int err, n;
6794+
6795+ err = kstrtoint(val, 0, &n);
6796+ if (!err) {
6797+ if (n > 0)
6798+ au_debug_on();
6799+ else
6800+ au_debug_off();
6801+ }
6802+ return err;
6803+}
6804+
6805+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
6806+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
6807+{
6808+ atomic_t *a;
6809+
6810+ a = kp->arg;
6811+ return sprintf(buffer, "%d", atomic_read(a));
6812+}
6813+
6814+static struct kernel_param_ops param_ops_atomic_t = {
6815+ .set = param_atomic_t_set,
6816+ .get = param_atomic_t_get
6817+ /* void (*free)(void *arg) */
6818+};
6819+
6820+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 6821+MODULE_PARM_DESC(debug, "debug print");
392086de 6822+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
1facf9fc 6823+
c1595e42 6824+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */
1facf9fc 6825+char *au_plevel = KERN_DEBUG;
e49829fe
JR
6826+#define dpri(fmt, ...) do { \
6827+ if ((au_plevel \
6828+ && strcmp(au_plevel, KERN_DEBUG)) \
6829+ || au_debug_test()) \
6830+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 6831+} while (0)
6832+
6833+/* ---------------------------------------------------------------------- */
6834+
6835+void au_dpri_whlist(struct au_nhash *whlist)
6836+{
6837+ unsigned long ul, n;
6838+ struct hlist_head *head;
c06a8ce3 6839+ struct au_vdir_wh *pos;
1facf9fc 6840+
6841+ n = whlist->nh_num;
6842+ head = whlist->nh_head;
6843+ for (ul = 0; ul < n; ul++) {
c06a8ce3 6844+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 6845+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
6846+ pos->wh_bindex,
6847+ pos->wh_str.len, pos->wh_str.name,
6848+ pos->wh_str.len);
1facf9fc 6849+ head++;
6850+ }
6851+}
6852+
6853+void au_dpri_vdir(struct au_vdir *vdir)
6854+{
6855+ unsigned long ul;
6856+ union au_vdir_deblk_p p;
6857+ unsigned char *o;
6858+
6859+ if (!vdir || IS_ERR(vdir)) {
6860+ dpri("err %ld\n", PTR_ERR(vdir));
6861+ return;
6862+ }
6863+
6864+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
6865+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
6866+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
6867+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
6868+ p.deblk = vdir->vd_deblk[ul];
6869+ o = p.deblk;
6870+ dpri("[%lu]: %p\n", ul, o);
6871+ }
6872+}
6873+
53392da6 6874+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 6875+ struct dentry *wh)
6876+{
6877+ char *n = NULL;
6878+ int l = 0;
6879+
6880+ if (!inode || IS_ERR(inode)) {
6881+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
6882+ return -1;
6883+ }
6884+
c2b27bf2 6885+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 6886+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
6887+ && sizeof(inode->i_blocks) != sizeof(u64));
6888+ if (wh) {
6889+ n = (void *)wh->d_name.name;
6890+ l = wh->d_name.len;
6891+ }
6892+
53392da6
AM
6893+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
6894+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
6895+ bindex, inode,
1facf9fc 6896+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
6897+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
6898+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 6899+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 6900+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
6901+ inode->i_state, inode->i_flags, inode->i_version,
6902+ inode->i_generation,
1facf9fc 6903+ l ? ", wh " : "", l, n);
6904+ return 0;
6905+}
6906+
6907+void au_dpri_inode(struct inode *inode)
6908+{
6909+ struct au_iinfo *iinfo;
6910+ aufs_bindex_t bindex;
53392da6 6911+ int err, hn;
1facf9fc 6912+
53392da6 6913+ err = do_pri_inode(-1, inode, -1, NULL);
1facf9fc 6914+ if (err || !au_test_aufs(inode->i_sb))
6915+ return;
6916+
6917+ iinfo = au_ii(inode);
6918+ if (!iinfo)
6919+ return;
6920+ dpri("i-1: bstart %d, bend %d, gen %d\n",
537831f9 6921+ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
1facf9fc 6922+ if (iinfo->ii_bstart < 0)
6923+ return;
53392da6
AM
6924+ hn = 0;
6925+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
6926+ hn = !!au_hn(iinfo->ii_hinode + bindex);
6927+ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
1facf9fc 6928+ iinfo->ii_hinode[0 + bindex].hi_whdentry);
53392da6 6929+ }
1facf9fc 6930+}
6931+
2cbb1c4b
JR
6932+void au_dpri_dalias(struct inode *inode)
6933+{
6934+ struct dentry *d;
6935+
6936+ spin_lock(&inode->i_lock);
c1595e42 6937+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias)
2cbb1c4b
JR
6938+ au_dpri_dentry(d);
6939+ spin_unlock(&inode->i_lock);
6940+}
6941+
1facf9fc 6942+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
6943+{
6944+ struct dentry *wh = NULL;
53392da6 6945+ int hn;
076b876e 6946+ struct au_iinfo *iinfo;
1facf9fc 6947+
6948+ if (!dentry || IS_ERR(dentry)) {
6949+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
6950+ return -1;
6951+ }
6952+ /* do not call dget_parent() here */
027c5e7a 6953+ /* note: access d_xxx without d_lock */
523b37e3
AM
6954+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
6955+ bindex, dentry, dentry,
1facf9fc 6956+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
c1595e42 6957+ au_dcount(dentry), dentry->d_flags,
523b37e3 6958+ d_unhashed(dentry) ? "un" : "");
53392da6 6959+ hn = -1;
5527c038
JR
6960+ if (bindex >= 0
6961+ && d_is_positive(dentry)
6962+ && au_test_aufs(dentry->d_sb)) {
6963+ iinfo = au_ii(d_inode(dentry));
53392da6
AM
6964+ if (iinfo) {
6965+ hn = !!au_hn(iinfo->ii_hinode + bindex);
1facf9fc 6966+ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
53392da6 6967+ }
1facf9fc 6968+ }
5527c038 6969+ do_pri_inode(bindex, d_inode(dentry), hn, wh);
1facf9fc 6970+ return 0;
6971+}
6972+
6973+void au_dpri_dentry(struct dentry *dentry)
6974+{
6975+ struct au_dinfo *dinfo;
6976+ aufs_bindex_t bindex;
6977+ int err;
4a4d8108 6978+ struct au_hdentry *hdp;
1facf9fc 6979+
6980+ err = do_pri_dentry(-1, dentry);
6981+ if (err || !au_test_aufs(dentry->d_sb))
6982+ return;
6983+
6984+ dinfo = au_di(dentry);
6985+ if (!dinfo)
6986+ return;
38d290e6 6987+ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
1facf9fc 6988+ dinfo->di_bstart, dinfo->di_bend,
38d290e6
JR
6989+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
6990+ dinfo->di_tmpfile);
1facf9fc 6991+ if (dinfo->di_bstart < 0)
6992+ return;
4a4d8108 6993+ hdp = dinfo->di_hdentry;
1facf9fc 6994+ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
4a4d8108 6995+ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
1facf9fc 6996+}
6997+
6998+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
6999+{
7000+ char a[32];
7001+
7002+ if (!file || IS_ERR(file)) {
7003+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
7004+ return -1;
7005+ }
7006+ a[0] = 0;
7007+ if (bindex < 0
b912730e 7008+ && !IS_ERR_OR_NULL(file->f_path.dentry)
2000de60 7009+ && au_test_aufs(file->f_path.dentry->d_sb)
1facf9fc 7010+ && au_fi(file))
e49829fe 7011+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 7012+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 7013+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 7014+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 7015+ file->f_version, file->f_pos, a);
b912730e 7016+ if (!IS_ERR_OR_NULL(file->f_path.dentry))
2000de60 7017+ do_pri_dentry(bindex, file->f_path.dentry);
1facf9fc 7018+ return 0;
7019+}
7020+
7021+void au_dpri_file(struct file *file)
7022+{
7023+ struct au_finfo *finfo;
4a4d8108
AM
7024+ struct au_fidir *fidir;
7025+ struct au_hfile *hfile;
1facf9fc 7026+ aufs_bindex_t bindex;
7027+ int err;
7028+
7029+ err = do_pri_file(-1, file);
2000de60 7030+ if (err
b912730e 7031+ || IS_ERR_OR_NULL(file->f_path.dentry)
2000de60 7032+ || !au_test_aufs(file->f_path.dentry->d_sb))
1facf9fc 7033+ return;
7034+
7035+ finfo = au_fi(file);
7036+ if (!finfo)
7037+ return;
4a4d8108 7038+ if (finfo->fi_btop < 0)
1facf9fc 7039+ return;
4a4d8108
AM
7040+ fidir = finfo->fi_hdir;
7041+ if (!fidir)
7042+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
7043+ else
e49829fe
JR
7044+ for (bindex = finfo->fi_btop;
7045+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
7046+ bindex++) {
7047+ hfile = fidir->fd_hfile + bindex;
7048+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
7049+ }
1facf9fc 7050+}
7051+
7052+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
7053+{
7054+ struct vfsmount *mnt;
7055+ struct super_block *sb;
7056+
7057+ if (!br || IS_ERR(br))
7058+ goto out;
86dc4139 7059+ mnt = au_br_mnt(br);
1facf9fc 7060+ if (!mnt || IS_ERR(mnt))
7061+ goto out;
7062+ sb = mnt->mnt_sb;
7063+ if (!sb || IS_ERR(sb))
7064+ goto out;
7065+
1e00d052 7066+ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
b752ccd1 7067+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 7068+ "xino %d\n",
1e00d052
AM
7069+ bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
7070+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 7071+ sb->s_flags, sb->s_count,
1facf9fc 7072+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
7073+ return 0;
7074+
4f0767ce 7075+out:
1facf9fc 7076+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
7077+ return -1;
7078+}
7079+
7080+void au_dpri_sb(struct super_block *sb)
7081+{
7082+ struct au_sbinfo *sbinfo;
7083+ aufs_bindex_t bindex;
7084+ int err;
7085+ /* to reuduce stack size */
7086+ struct {
7087+ struct vfsmount mnt;
7088+ struct au_branch fake;
7089+ } *a;
7090+
7091+ /* this function can be called from magic sysrq */
7092+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
7093+ if (unlikely(!a)) {
7094+ dpri("no memory\n");
7095+ return;
7096+ }
7097+
7098+ a->mnt.mnt_sb = sb;
7099+ a->fake.br_perm = 0;
86dc4139 7100+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 7101+ a->fake.br_xino.xi_file = NULL;
7102+ atomic_set(&a->fake.br_count, 0);
7103+ smp_mb(); /* atomic_set */
7104+ err = do_pri_br(-1, &a->fake);
7105+ kfree(a);
7106+ dpri("dev 0x%x\n", sb->s_dev);
7107+ if (err || !au_test_aufs(sb))
7108+ return;
7109+
7110+ sbinfo = au_sbi(sb);
7111+ if (!sbinfo)
7112+ return;
7113+ dpri("nw %d, gen %u, kobj %d\n",
7114+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
7115+ atomic_read(&sbinfo->si_kobj.kref.refcount));
7116+ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
7117+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
7118+}
7119+
7120+/* ---------------------------------------------------------------------- */
7121+
027c5e7a
AM
7122+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
7123+{
5527c038 7124+ struct inode *h_inode, *inode = d_inode(dentry);
027c5e7a
AM
7125+ struct dentry *h_dentry;
7126+ aufs_bindex_t bindex, bend, bi;
7127+
7128+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
7129+ return;
7130+
7131+ bend = au_dbend(dentry);
7132+ bi = au_ibend(inode);
7133+ if (bi < bend)
7134+ bend = bi;
7135+ bindex = au_dbstart(dentry);
7136+ bi = au_ibstart(inode);
7137+ if (bi > bindex)
7138+ bindex = bi;
7139+
7140+ for (; bindex <= bend; bindex++) {
7141+ h_dentry = au_h_dptr(dentry, bindex);
7142+ if (!h_dentry)
7143+ continue;
7144+ h_inode = au_h_iptr(inode, bindex);
5527c038 7145+ if (unlikely(h_inode != d_inode(h_dentry))) {
392086de 7146+ au_debug_on();
027c5e7a
AM
7147+ AuDbg("b%d, %s:%d\n", bindex, func, line);
7148+ AuDbgDentry(dentry);
7149+ AuDbgInode(inode);
392086de 7150+ au_debug_off();
027c5e7a
AM
7151+ BUG();
7152+ }
7153+ }
7154+}
7155+
1facf9fc 7156+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
7157+{
7158+ int err, i, j;
7159+ struct au_dcsub_pages dpages;
7160+ struct au_dpage *dpage;
7161+ struct dentry **dentries;
7162+
7163+ err = au_dpages_init(&dpages, GFP_NOFS);
7164+ AuDebugOn(err);
027c5e7a 7165+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 7166+ AuDebugOn(err);
7167+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
7168+ dpage = dpages.dpages + i;
7169+ dentries = dpage->dentries;
7170+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 7171+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 7172+ }
7173+ au_dpages_free(&dpages);
7174+}
7175+
1facf9fc 7176+void au_dbg_verify_kthread(void)
7177+{
53392da6 7178+ if (au_wkq_test()) {
1facf9fc 7179+ au_dbg_blocked();
1e00d052
AM
7180+ /*
7181+ * It may be recursive, but udba=notify between two aufs mounts,
7182+ * where a single ro branch is shared, is not a problem.
7183+ */
7184+ /* WARN_ON(1); */
1facf9fc 7185+ }
7186+}
7187+
7188+/* ---------------------------------------------------------------------- */
7189+
1facf9fc 7190+int __init au_debug_init(void)
7191+{
7192+ aufs_bindex_t bindex;
7193+ struct au_vdir_destr destr;
7194+
7195+ bindex = -1;
7196+ AuDebugOn(bindex >= 0);
7197+
7198+ destr.len = -1;
7199+ AuDebugOn(destr.len < NAME_MAX);
7200+
7201+#ifdef CONFIG_4KSTACKS
0c3ec466 7202+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 7203+#endif
7204+
1facf9fc 7205+ return 0;
7206+}
7f207e10
AM
7207diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
7208--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 7209+++ linux/fs/aufs/debug.h 2015-09-24 10:47:58.251386326 +0200
5527c038 7210@@ -0,0 +1,225 @@
1facf9fc 7211+/*
2000de60 7212+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 7213+ *
7214+ * This program, aufs is free software; you can redistribute it and/or modify
7215+ * it under the terms of the GNU General Public License as published by
7216+ * the Free Software Foundation; either version 2 of the License, or
7217+ * (at your option) any later version.
dece6358
AM
7218+ *
7219+ * This program is distributed in the hope that it will be useful,
7220+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7221+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7222+ * GNU General Public License for more details.
7223+ *
7224+ * You should have received a copy of the GNU General Public License
523b37e3 7225+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7226+ */
7227+
7228+/*
7229+ * debug print functions
7230+ */
7231+
7232+#ifndef __AUFS_DEBUG_H__
7233+#define __AUFS_DEBUG_H__
7234+
7235+#ifdef __KERNEL__
7236+
392086de 7237+#include <linux/atomic.h>
4a4d8108
AM
7238+#include <linux/module.h>
7239+#include <linux/kallsyms.h>
1facf9fc 7240+#include <linux/sysrq.h>
4a4d8108 7241+
1facf9fc 7242+#ifdef CONFIG_AUFS_DEBUG
7243+#define AuDebugOn(a) BUG_ON(a)
7244+
7245+/* module parameter */
392086de
AM
7246+extern atomic_t aufs_debug;
7247+static inline void au_debug_on(void)
1facf9fc 7248+{
392086de
AM
7249+ atomic_inc(&aufs_debug);
7250+}
7251+static inline void au_debug_off(void)
7252+{
7253+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 7254+}
7255+
7256+static inline int au_debug_test(void)
7257+{
392086de 7258+ return atomic_read(&aufs_debug) > 0;
1facf9fc 7259+}
7260+#else
7261+#define AuDebugOn(a) do {} while (0)
392086de
AM
7262+AuStubVoid(au_debug_on, void)
7263+AuStubVoid(au_debug_off, void)
4a4d8108 7264+AuStubInt0(au_debug_test, void)
1facf9fc 7265+#endif /* CONFIG_AUFS_DEBUG */
7266+
392086de
AM
7267+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
7268+
1facf9fc 7269+/* ---------------------------------------------------------------------- */
7270+
7271+/* debug print */
7272+
4a4d8108 7273+#define AuDbg(fmt, ...) do { \
1facf9fc 7274+ if (au_debug_test()) \
4a4d8108 7275+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 7276+} while (0)
4a4d8108
AM
7277+#define AuLabel(l) AuDbg(#l "\n")
7278+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
7279+#define AuWarn1(fmt, ...) do { \
1facf9fc 7280+ static unsigned char _c; \
7281+ if (!_c++) \
0c3ec466 7282+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 7283+} while (0)
7284+
4a4d8108 7285+#define AuErr1(fmt, ...) do { \
1facf9fc 7286+ static unsigned char _c; \
7287+ if (!_c++) \
4a4d8108 7288+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 7289+} while (0)
7290+
4a4d8108 7291+#define AuIOErr1(fmt, ...) do { \
1facf9fc 7292+ static unsigned char _c; \
7293+ if (!_c++) \
4a4d8108 7294+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 7295+} while (0)
7296+
7297+#define AuUnsupportMsg "This operation is not supported." \
7298+ " Please report this application to aufs-users ML."
4a4d8108
AM
7299+#define AuUnsupport(fmt, ...) do { \
7300+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 7301+ dump_stack(); \
7302+} while (0)
7303+
7304+#define AuTraceErr(e) do { \
7305+ if (unlikely((e) < 0)) \
7306+ AuDbg("err %d\n", (int)(e)); \
7307+} while (0)
7308+
7309+#define AuTraceErrPtr(p) do { \
7310+ if (IS_ERR(p)) \
7311+ AuDbg("err %ld\n", PTR_ERR(p)); \
7312+} while (0)
7313+
7314+/* dirty macros for debug print, use with "%.*s" and caution */
7315+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 7316+
7317+/* ---------------------------------------------------------------------- */
7318+
dece6358 7319+struct dentry;
1facf9fc 7320+#ifdef CONFIG_AUFS_DEBUG
c1595e42 7321+extern struct mutex au_dbg_mtx;
1facf9fc 7322+extern char *au_plevel;
7323+struct au_nhash;
7324+void au_dpri_whlist(struct au_nhash *whlist);
7325+struct au_vdir;
7326+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 7327+struct inode;
1facf9fc 7328+void au_dpri_inode(struct inode *inode);
2cbb1c4b 7329+void au_dpri_dalias(struct inode *inode);
1facf9fc 7330+void au_dpri_dentry(struct dentry *dentry);
dece6358 7331+struct file;
1facf9fc 7332+void au_dpri_file(struct file *filp);
dece6358 7333+struct super_block;
1facf9fc 7334+void au_dpri_sb(struct super_block *sb);
7335+
027c5e7a
AM
7336+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
7337+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 7338+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 7339+void au_dbg_verify_kthread(void);
7340+
7341+int __init au_debug_init(void);
7e9cd9fe 7342+
1facf9fc 7343+#define AuDbgWhlist(w) do { \
c1595e42 7344+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7345+ AuDbg(#w "\n"); \
7346+ au_dpri_whlist(w); \
c1595e42 7347+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7348+} while (0)
7349+
7350+#define AuDbgVdir(v) do { \
c1595e42 7351+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7352+ AuDbg(#v "\n"); \
7353+ au_dpri_vdir(v); \
c1595e42 7354+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7355+} while (0)
7356+
7357+#define AuDbgInode(i) do { \
c1595e42 7358+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7359+ AuDbg(#i "\n"); \
7360+ au_dpri_inode(i); \
c1595e42 7361+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7362+} while (0)
7363+
2cbb1c4b 7364+#define AuDbgDAlias(i) do { \
c1595e42 7365+ mutex_lock(&au_dbg_mtx); \
2cbb1c4b
JR
7366+ AuDbg(#i "\n"); \
7367+ au_dpri_dalias(i); \
c1595e42 7368+ mutex_unlock(&au_dbg_mtx); \
2cbb1c4b
JR
7369+} while (0)
7370+
1facf9fc 7371+#define AuDbgDentry(d) do { \
c1595e42 7372+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7373+ AuDbg(#d "\n"); \
7374+ au_dpri_dentry(d); \
c1595e42 7375+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7376+} while (0)
7377+
7378+#define AuDbgFile(f) do { \
c1595e42 7379+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7380+ AuDbg(#f "\n"); \
7381+ au_dpri_file(f); \
c1595e42 7382+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7383+} while (0)
7384+
7385+#define AuDbgSb(sb) do { \
c1595e42 7386+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7387+ AuDbg(#sb "\n"); \
7388+ au_dpri_sb(sb); \
c1595e42 7389+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7390+} while (0)
7391+
4a4d8108
AM
7392+#define AuDbgSym(addr) do { \
7393+ char sym[KSYM_SYMBOL_LEN]; \
7394+ sprint_symbol(sym, (unsigned long)addr); \
7395+ AuDbg("%s\n", sym); \
7396+} while (0)
1facf9fc 7397+#else
027c5e7a 7398+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
7399+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
7400+AuStubVoid(au_dbg_verify_kthread, void)
7401+AuStubInt0(__init au_debug_init, void)
1facf9fc 7402+
1facf9fc 7403+#define AuDbgWhlist(w) do {} while (0)
7404+#define AuDbgVdir(v) do {} while (0)
7405+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 7406+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 7407+#define AuDbgDentry(d) do {} while (0)
7408+#define AuDbgFile(f) do {} while (0)
7409+#define AuDbgSb(sb) do {} while (0)
4a4d8108 7410+#define AuDbgSym(addr) do {} while (0)
1facf9fc 7411+#endif /* CONFIG_AUFS_DEBUG */
7412+
7413+/* ---------------------------------------------------------------------- */
7414+
7415+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
7416+int __init au_sysrq_init(void);
7417+void au_sysrq_fin(void);
7418+
7419+#ifdef CONFIG_HW_CONSOLE
7420+#define au_dbg_blocked() do { \
7421+ WARN_ON(1); \
0c5527e5 7422+ handle_sysrq('w'); \
1facf9fc 7423+} while (0)
7424+#else
4a4d8108 7425+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7426+#endif
7427+
7428+#else
4a4d8108
AM
7429+AuStubInt0(__init au_sysrq_init, void)
7430+AuStubVoid(au_sysrq_fin, void)
7431+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7432+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
7433+
7434+#endif /* __KERNEL__ */
7435+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
7436diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
7437--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
7438+++ linux/fs/aufs/dentry.c 2015-11-11 17:21:46.918863802 +0100
7439@@ -0,0 +1,1136 @@
1facf9fc 7440+/*
2000de60 7441+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 7442+ *
7443+ * This program, aufs is free software; you can redistribute it and/or modify
7444+ * it under the terms of the GNU General Public License as published by
7445+ * the Free Software Foundation; either version 2 of the License, or
7446+ * (at your option) any later version.
dece6358
AM
7447+ *
7448+ * This program is distributed in the hope that it will be useful,
7449+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7450+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7451+ * GNU General Public License for more details.
7452+ *
7453+ * You should have received a copy of the GNU General Public License
523b37e3 7454+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7455+ */
7456+
7457+/*
7458+ * lookup and dentry operations
7459+ */
7460+
dece6358 7461+#include <linux/namei.h>
1facf9fc 7462+#include "aufs.h"
7463+
1facf9fc 7464+#define AuLkup_ALLOW_NEG 1
076b876e 7465+#define AuLkup_IGNORE_PERM (1 << 1)
1facf9fc 7466+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
7f207e10
AM
7467+#define au_fset_lkup(flags, name) \
7468+ do { (flags) |= AuLkup_##name; } while (0)
7469+#define au_fclr_lkup(flags, name) \
7470+ do { (flags) &= ~AuLkup_##name; } while (0)
1facf9fc 7471+
7472+struct au_do_lookup_args {
7473+ unsigned int flags;
7474+ mode_t type;
1facf9fc 7475+};
7476+
7477+/*
7478+ * returns positive/negative dentry, NULL or an error.
7479+ * NULL means whiteout-ed or not-found.
7480+ */
7481+static struct dentry*
7482+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
7483+ aufs_bindex_t bindex, struct qstr *wh_name,
7484+ struct au_do_lookup_args *args)
7485+{
7486+ struct dentry *h_dentry;
2000de60 7487+ struct inode *h_inode;
1facf9fc 7488+ struct au_branch *br;
7489+ int wh_found, opq;
7490+ unsigned char wh_able;
7491+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
076b876e
AM
7492+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
7493+ IGNORE_PERM);
1facf9fc 7494+
1facf9fc 7495+ wh_found = 0;
7496+ br = au_sbr(dentry->d_sb, bindex);
7497+ wh_able = !!au_br_whable(br->br_perm);
7498+ if (wh_able)
076b876e 7499+ wh_found = au_wh_test(h_parent, wh_name, /*try_sio*/0);
1facf9fc 7500+ h_dentry = ERR_PTR(wh_found);
7501+ if (!wh_found)
7502+ goto real_lookup;
7503+ if (unlikely(wh_found < 0))
7504+ goto out;
7505+
7506+ /* We found a whiteout */
7507+ /* au_set_dbend(dentry, bindex); */
7508+ au_set_dbwh(dentry, bindex);
7509+ if (!allow_neg)
7510+ return NULL; /* success */
7511+
4f0767ce 7512+real_lookup:
076b876e
AM
7513+ if (!ignore_perm)
7514+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
7515+ else
7516+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
2000de60
JR
7517+ if (IS_ERR(h_dentry)) {
7518+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG
7519+ && !allow_neg)
7520+ h_dentry = NULL;
1facf9fc 7521+ goto out;
2000de60 7522+ }
1facf9fc 7523+
5527c038
JR
7524+ h_inode = d_inode(h_dentry);
7525+ if (d_is_negative(h_dentry)) {
1facf9fc 7526+ if (!allow_neg)
7527+ goto out_neg;
7528+ } else if (wh_found
7529+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
7530+ goto out_neg;
7531+
7532+ if (au_dbend(dentry) <= bindex)
7533+ au_set_dbend(dentry, bindex);
7534+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
7535+ au_set_dbstart(dentry, bindex);
7536+ au_set_h_dptr(dentry, bindex, h_dentry);
7537+
2000de60
JR
7538+ if (!d_is_dir(h_dentry)
7539+ || !wh_able
5527c038 7540+ || (d_really_is_positive(dentry) && !d_is_dir(dentry)))
1facf9fc 7541+ goto out; /* success */
7542+
7543+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
076b876e 7544+ opq = au_diropq_test(h_dentry);
1facf9fc 7545+ mutex_unlock(&h_inode->i_mutex);
7546+ if (opq > 0)
7547+ au_set_dbdiropq(dentry, bindex);
7548+ else if (unlikely(opq < 0)) {
7549+ au_set_h_dptr(dentry, bindex, NULL);
7550+ h_dentry = ERR_PTR(opq);
7551+ }
7552+ goto out;
7553+
4f0767ce 7554+out_neg:
1facf9fc 7555+ dput(h_dentry);
7556+ h_dentry = NULL;
4f0767ce 7557+out:
1facf9fc 7558+ return h_dentry;
7559+}
7560+
dece6358
AM
7561+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
7562+{
7563+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
7564+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
7565+ return -EPERM;
7566+ return 0;
7567+}
7568+
1facf9fc 7569+/*
7570+ * returns the number of lower positive dentries,
7571+ * otherwise an error.
7572+ * can be called at unlinking with @type is zero.
7573+ */
537831f9 7574+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
1facf9fc 7575+{
7576+ int npositive, err;
7577+ aufs_bindex_t bindex, btail, bdiropq;
076b876e 7578+ unsigned char isdir, dirperm1;
1facf9fc 7579+ struct qstr whname;
7580+ struct au_do_lookup_args args = {
b4510431 7581+ .flags = 0,
537831f9 7582+ .type = type
1facf9fc 7583+ };
7584+ const struct qstr *name = &dentry->d_name;
7585+ struct dentry *parent;
076b876e 7586+ struct super_block *sb;
1facf9fc 7587+
076b876e
AM
7588+ sb = dentry->d_sb;
7589+ err = au_test_shwh(sb, name);
dece6358 7590+ if (unlikely(err))
1facf9fc 7591+ goto out;
7592+
7593+ err = au_wh_name_alloc(&whname, name);
7594+ if (unlikely(err))
7595+ goto out;
7596+
2000de60 7597+ isdir = !!d_is_dir(dentry);
1facf9fc 7598+ if (!type)
7599+ au_fset_lkup(args.flags, ALLOW_NEG);
076b876e 7600+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
1facf9fc 7601+
7602+ npositive = 0;
4a4d8108 7603+ parent = dget_parent(dentry);
1facf9fc 7604+ btail = au_dbtaildir(parent);
7605+ for (bindex = bstart; bindex <= btail; bindex++) {
7606+ struct dentry *h_parent, *h_dentry;
7607+ struct inode *h_inode, *h_dir;
7608+
7609+ h_dentry = au_h_dptr(dentry, bindex);
7610+ if (h_dentry) {
5527c038 7611+ if (d_is_positive(h_dentry))
1facf9fc 7612+ npositive++;
7613+ if (type != S_IFDIR)
7614+ break;
7615+ continue;
7616+ }
7617+ h_parent = au_h_dptr(parent, bindex);
2000de60 7618+ if (!h_parent || !d_is_dir(h_parent))
1facf9fc 7619+ continue;
7620+
5527c038 7621+ h_dir = d_inode(h_parent);
1facf9fc 7622+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
7623+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
7624+ &args);
7625+ mutex_unlock(&h_dir->i_mutex);
7626+ err = PTR_ERR(h_dentry);
7627+ if (IS_ERR(h_dentry))
4a4d8108 7628+ goto out_parent;
2000de60
JR
7629+ if (h_dentry)
7630+ au_fclr_lkup(args.flags, ALLOW_NEG);
076b876e
AM
7631+ if (dirperm1)
7632+ au_fset_lkup(args.flags, IGNORE_PERM);
1facf9fc 7633+
79b8bda9 7634+ if (au_dbwh(dentry) == bindex)
1facf9fc 7635+ break;
7636+ if (!h_dentry)
7637+ continue;
5527c038 7638+ if (d_is_negative(h_dentry))
1facf9fc 7639+ continue;
5527c038 7640+ h_inode = d_inode(h_dentry);
1facf9fc 7641+ npositive++;
7642+ if (!args.type)
7643+ args.type = h_inode->i_mode & S_IFMT;
7644+ if (args.type != S_IFDIR)
7645+ break;
7646+ else if (isdir) {
7647+ /* the type of lower may be different */
7648+ bdiropq = au_dbdiropq(dentry);
7649+ if (bdiropq >= 0 && bdiropq <= bindex)
7650+ break;
7651+ }
7652+ }
7653+
7654+ if (npositive) {
7655+ AuLabel(positive);
7656+ au_update_dbstart(dentry);
7657+ }
7658+ err = npositive;
076b876e 7659+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
027c5e7a 7660+ && au_dbstart(dentry) < 0)) {
1facf9fc 7661+ err = -EIO;
523b37e3
AM
7662+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
7663+ dentry, err);
027c5e7a 7664+ }
1facf9fc 7665+
4f0767ce 7666+out_parent:
4a4d8108 7667+ dput(parent);
1facf9fc 7668+ kfree(whname.name);
4f0767ce 7669+out:
1facf9fc 7670+ return err;
7671+}
7672+
076b876e 7673+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
1facf9fc 7674+{
7675+ struct dentry *dentry;
7676+ int wkq_err;
7677+
5527c038 7678+ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC))
b4510431 7679+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 7680+ else {
b4510431
AM
7681+ struct vfsub_lkup_one_args args = {
7682+ .errp = &dentry,
7683+ .name = name,
7684+ .parent = parent
1facf9fc 7685+ };
7686+
b4510431 7687+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 7688+ if (unlikely(wkq_err))
7689+ dentry = ERR_PTR(wkq_err);
7690+ }
7691+
7692+ return dentry;
7693+}
7694+
7695+/*
7696+ * lookup @dentry on @bindex which should be negative.
7697+ */
86dc4139 7698+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 7699+{
7700+ int err;
7701+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 7702+ struct au_branch *br;
1facf9fc 7703+
1facf9fc 7704+ parent = dget_parent(dentry);
7705+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
7706+ br = au_sbr(dentry->d_sb, bindex);
7707+ if (wh)
7708+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
7709+ else
076b876e 7710+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 7711+ err = PTR_ERR(h_dentry);
7712+ if (IS_ERR(h_dentry))
7713+ goto out;
5527c038 7714+ if (unlikely(d_is_positive(h_dentry))) {
1facf9fc 7715+ err = -EIO;
523b37e3 7716+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 7717+ dput(h_dentry);
7718+ goto out;
7719+ }
7720+
4a4d8108 7721+ err = 0;
1facf9fc 7722+ if (bindex < au_dbstart(dentry))
7723+ au_set_dbstart(dentry, bindex);
7724+ if (au_dbend(dentry) < bindex)
7725+ au_set_dbend(dentry, bindex);
7726+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 7727+
4f0767ce 7728+out:
1facf9fc 7729+ dput(parent);
7730+ return err;
7731+}
7732+
7733+/* ---------------------------------------------------------------------- */
7734+
7735+/* subset of struct inode */
7736+struct au_iattr {
7737+ unsigned long i_ino;
7738+ /* unsigned int i_nlink; */
0c3ec466
AM
7739+ kuid_t i_uid;
7740+ kgid_t i_gid;
1facf9fc 7741+ u64 i_version;
7742+/*
7743+ loff_t i_size;
7744+ blkcnt_t i_blocks;
7745+*/
7746+ umode_t i_mode;
7747+};
7748+
7749+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
7750+{
7751+ ia->i_ino = h_inode->i_ino;
7752+ /* ia->i_nlink = h_inode->i_nlink; */
7753+ ia->i_uid = h_inode->i_uid;
7754+ ia->i_gid = h_inode->i_gid;
7755+ ia->i_version = h_inode->i_version;
7756+/*
7757+ ia->i_size = h_inode->i_size;
7758+ ia->i_blocks = h_inode->i_blocks;
7759+*/
7760+ ia->i_mode = (h_inode->i_mode & S_IFMT);
7761+}
7762+
7763+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
7764+{
7765+ return ia->i_ino != h_inode->i_ino
7766+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 7767+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 7768+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 7769+ || ia->i_version != h_inode->i_version
7770+/*
7771+ || ia->i_size != h_inode->i_size
7772+ || ia->i_blocks != h_inode->i_blocks
7773+*/
7774+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
7775+}
7776+
7777+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
7778+ struct au_branch *br)
7779+{
7780+ int err;
7781+ struct au_iattr ia;
7782+ struct inode *h_inode;
7783+ struct dentry *h_d;
7784+ struct super_block *h_sb;
7785+
7786+ err = 0;
7787+ memset(&ia, -1, sizeof(ia));
7788+ h_sb = h_dentry->d_sb;
5527c038
JR
7789+ h_inode = NULL;
7790+ if (d_is_positive(h_dentry)) {
7791+ h_inode = d_inode(h_dentry);
1facf9fc 7792+ au_iattr_save(&ia, h_inode);
5527c038 7793+ } else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
1facf9fc 7794+ /* nfs d_revalidate may return 0 for negative dentry */
7795+ /* fuse d_revalidate always return 0 for negative dentry */
7796+ goto out;
7797+
7798+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 7799+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 7800+ err = PTR_ERR(h_d);
7801+ if (IS_ERR(h_d))
7802+ goto out;
7803+
7804+ err = 0;
7805+ if (unlikely(h_d != h_dentry
5527c038 7806+ || d_inode(h_d) != h_inode
1facf9fc 7807+ || (h_inode && au_iattr_test(&ia, h_inode))))
7808+ err = au_busy_or_stale();
7809+ dput(h_d);
7810+
4f0767ce 7811+out:
1facf9fc 7812+ AuTraceErr(err);
7813+ return err;
7814+}
7815+
7816+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7817+ struct dentry *h_parent, struct au_branch *br)
7818+{
7819+ int err;
7820+
7821+ err = 0;
027c5e7a
AM
7822+ if (udba == AuOpt_UDBA_REVAL
7823+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 7824+ IMustLock(h_dir);
5527c038 7825+ err = (d_inode(h_dentry->d_parent) != h_dir);
027c5e7a 7826+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 7827+ err = au_h_verify_dentry(h_dentry, h_parent, br);
7828+
7829+ return err;
7830+}
7831+
7832+/* ---------------------------------------------------------------------- */
7833+
027c5e7a 7834+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 7835+{
027c5e7a 7836+ int err;
1facf9fc 7837+ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
027c5e7a
AM
7838+ struct au_hdentry tmp, *p, *q;
7839+ struct au_dinfo *dinfo;
7840+ struct super_block *sb;
1facf9fc 7841+
027c5e7a 7842+ DiMustWriteLock(dentry);
1308ab2a 7843+
027c5e7a
AM
7844+ sb = dentry->d_sb;
7845+ dinfo = au_di(dentry);
1facf9fc 7846+ bend = dinfo->di_bend;
7847+ bwh = dinfo->di_bwh;
7848+ bdiropq = dinfo->di_bdiropq;
027c5e7a 7849+ p = dinfo->di_hdentry + dinfo->di_bstart;
1facf9fc 7850+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
027c5e7a 7851+ if (!p->hd_dentry)
1facf9fc 7852+ continue;
7853+
027c5e7a
AM
7854+ new_bindex = au_br_index(sb, p->hd_id);
7855+ if (new_bindex == bindex)
1facf9fc 7856+ continue;
1facf9fc 7857+
1facf9fc 7858+ if (dinfo->di_bwh == bindex)
7859+ bwh = new_bindex;
7860+ if (dinfo->di_bdiropq == bindex)
7861+ bdiropq = new_bindex;
7862+ if (new_bindex < 0) {
7863+ au_hdput(p);
7864+ p->hd_dentry = NULL;
7865+ continue;
7866+ }
7867+
7868+ /* swap two lower dentries, and loop again */
7869+ q = dinfo->di_hdentry + new_bindex;
7870+ tmp = *q;
7871+ *q = *p;
7872+ *p = tmp;
7873+ if (tmp.hd_dentry) {
7874+ bindex--;
7875+ p--;
7876+ }
7877+ }
7878+
1facf9fc 7879+ dinfo->di_bwh = -1;
7880+ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
7881+ dinfo->di_bwh = bwh;
7882+
7883+ dinfo->di_bdiropq = -1;
7884+ if (bdiropq >= 0
7885+ && bdiropq <= au_sbend(sb)
7886+ && au_sbr_whable(sb, bdiropq))
7887+ dinfo->di_bdiropq = bdiropq;
7888+
027c5e7a
AM
7889+ err = -EIO;
7890+ dinfo->di_bstart = -1;
7891+ dinfo->di_bend = -1;
1facf9fc 7892+ bend = au_dbend(parent);
7893+ p = dinfo->di_hdentry;
7894+ for (bindex = 0; bindex <= bend; bindex++, p++)
7895+ if (p->hd_dentry) {
7896+ dinfo->di_bstart = bindex;
7897+ break;
7898+ }
7899+
027c5e7a
AM
7900+ if (dinfo->di_bstart >= 0) {
7901+ p = dinfo->di_hdentry + bend;
7902+ for (bindex = bend; bindex >= 0; bindex--, p--)
7903+ if (p->hd_dentry) {
7904+ dinfo->di_bend = bindex;
7905+ err = 0;
7906+ break;
7907+ }
7908+ }
7909+
7910+ return err;
1facf9fc 7911+}
7912+
027c5e7a 7913+static void au_do_hide(struct dentry *dentry)
1facf9fc 7914+{
027c5e7a 7915+ struct inode *inode;
1facf9fc 7916+
5527c038
JR
7917+ if (d_really_is_positive(dentry)) {
7918+ inode = d_inode(dentry);
7919+ if (!d_is_dir(dentry)) {
027c5e7a
AM
7920+ if (inode->i_nlink && !d_unhashed(dentry))
7921+ drop_nlink(inode);
7922+ } else {
7923+ clear_nlink(inode);
7924+ /* stop next lookup */
7925+ inode->i_flags |= S_DEAD;
7926+ }
7927+ smp_mb(); /* necessary? */
7928+ }
7929+ d_drop(dentry);
7930+}
1308ab2a 7931+
027c5e7a
AM
7932+static int au_hide_children(struct dentry *parent)
7933+{
7934+ int err, i, j, ndentry;
7935+ struct au_dcsub_pages dpages;
7936+ struct au_dpage *dpage;
7937+ struct dentry *dentry;
1facf9fc 7938+
027c5e7a 7939+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 7940+ if (unlikely(err))
7941+ goto out;
027c5e7a
AM
7942+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
7943+ if (unlikely(err))
7944+ goto out_dpages;
1facf9fc 7945+
027c5e7a
AM
7946+ /* in reverse order */
7947+ for (i = dpages.ndpage - 1; i >= 0; i--) {
7948+ dpage = dpages.dpages + i;
7949+ ndentry = dpage->ndentry;
7950+ for (j = ndentry - 1; j >= 0; j--) {
7951+ dentry = dpage->dentries[j];
7952+ if (dentry != parent)
7953+ au_do_hide(dentry);
7954+ }
7955+ }
1facf9fc 7956+
027c5e7a
AM
7957+out_dpages:
7958+ au_dpages_free(&dpages);
4f0767ce 7959+out:
027c5e7a 7960+ return err;
1facf9fc 7961+}
7962+
027c5e7a 7963+static void au_hide(struct dentry *dentry)
1facf9fc 7964+{
027c5e7a 7965+ int err;
1facf9fc 7966+
027c5e7a 7967+ AuDbgDentry(dentry);
2000de60 7968+ if (d_is_dir(dentry)) {
027c5e7a
AM
7969+ /* shrink_dcache_parent(dentry); */
7970+ err = au_hide_children(dentry);
7971+ if (unlikely(err))
523b37e3
AM
7972+ AuIOErr("%pd, failed hiding children, ignored %d\n",
7973+ dentry, err);
027c5e7a
AM
7974+ }
7975+ au_do_hide(dentry);
7976+}
1facf9fc 7977+
027c5e7a
AM
7978+/*
7979+ * By adding a dirty branch, a cached dentry may be affected in various ways.
7980+ *
7981+ * a dirty branch is added
7982+ * - on the top of layers
7983+ * - in the middle of layers
7984+ * - to the bottom of layers
7985+ *
7986+ * on the added branch there exists
7987+ * - a whiteout
7988+ * - a diropq
7989+ * - a same named entry
7990+ * + exist
7991+ * * negative --> positive
7992+ * * positive --> positive
7993+ * - type is unchanged
7994+ * - type is changed
7995+ * + doesn't exist
7996+ * * negative --> negative
7997+ * * positive --> negative (rejected by au_br_del() for non-dir case)
7998+ * - none
7999+ */
8000+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
8001+ struct au_dinfo *tmp)
8002+{
8003+ int err;
8004+ aufs_bindex_t bindex, bend;
8005+ struct {
8006+ struct dentry *dentry;
8007+ struct inode *inode;
8008+ mode_t mode;
8009+ } orig_h, tmp_h;
8010+ struct au_hdentry *hd;
8011+ struct inode *inode, *h_inode;
8012+ struct dentry *h_dentry;
8013+
8014+ err = 0;
8015+ AuDebugOn(dinfo->di_bstart < 0);
027c5e7a 8016+ orig_h.mode = 0;
5527c038
JR
8017+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
8018+ orig_h.inode = NULL;
8019+ if (d_is_positive(orig_h.dentry)) {
8020+ orig_h.inode = d_inode(orig_h.dentry);
027c5e7a 8021+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
5527c038 8022+ }
027c5e7a
AM
8023+ memset(&tmp_h, 0, sizeof(tmp_h));
8024+ if (tmp->di_bstart >= 0) {
8025+ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
5527c038
JR
8026+ tmp_h.inode = NULL;
8027+ if (d_is_positive(tmp_h.dentry)) {
8028+ tmp_h.inode = d_inode(tmp_h.dentry);
027c5e7a 8029+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
5527c038 8030+ }
027c5e7a
AM
8031+ }
8032+
5527c038
JR
8033+ inode = NULL;
8034+ if (d_really_is_positive(dentry))
8035+ inode = d_inode(dentry);
027c5e7a
AM
8036+ if (!orig_h.inode) {
8037+ AuDbg("nagative originally\n");
8038+ if (inode) {
8039+ au_hide(dentry);
8040+ goto out;
8041+ }
8042+ AuDebugOn(inode);
8043+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
8044+ AuDebugOn(dinfo->di_bdiropq != -1);
8045+
8046+ if (!tmp_h.inode) {
8047+ AuDbg("negative --> negative\n");
8048+ /* should have only one negative lower */
8049+ if (tmp->di_bstart >= 0
8050+ && tmp->di_bstart < dinfo->di_bstart) {
8051+ AuDebugOn(tmp->di_bstart != tmp->di_bend);
8052+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
8053+ au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
8054+ au_di_cp(dinfo, tmp);
8055+ hd = tmp->di_hdentry + tmp->di_bstart;
8056+ au_set_h_dptr(dentry, tmp->di_bstart,
8057+ dget(hd->hd_dentry));
8058+ }
8059+ au_dbg_verify_dinode(dentry);
8060+ } else {
8061+ AuDbg("negative --> positive\n");
8062+ /*
8063+ * similar to the behaviour of creating with bypassing
8064+ * aufs.
8065+ * unhash it in order to force an error in the
8066+ * succeeding create operation.
8067+ * we should not set S_DEAD here.
8068+ */
8069+ d_drop(dentry);
8070+ /* au_di_swap(tmp, dinfo); */
8071+ au_dbg_verify_dinode(dentry);
8072+ }
8073+ } else {
8074+ AuDbg("positive originally\n");
8075+ /* inode may be NULL */
8076+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
8077+ if (!tmp_h.inode) {
8078+ AuDbg("positive --> negative\n");
8079+ /* or bypassing aufs */
8080+ au_hide(dentry);
8081+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
8082+ dinfo->di_bwh = tmp->di_bwh;
8083+ if (inode)
8084+ err = au_refresh_hinode_self(inode);
8085+ au_dbg_verify_dinode(dentry);
8086+ } else if (orig_h.mode == tmp_h.mode) {
8087+ AuDbg("positive --> positive, same type\n");
8088+ if (!S_ISDIR(orig_h.mode)
8089+ && dinfo->di_bstart > tmp->di_bstart) {
8090+ /*
8091+ * similar to the behaviour of removing and
8092+ * creating.
8093+ */
8094+ au_hide(dentry);
8095+ if (inode)
8096+ err = au_refresh_hinode_self(inode);
8097+ au_dbg_verify_dinode(dentry);
8098+ } else {
8099+ /* fill empty slots */
8100+ if (dinfo->di_bstart > tmp->di_bstart)
8101+ dinfo->di_bstart = tmp->di_bstart;
8102+ if (dinfo->di_bend < tmp->di_bend)
8103+ dinfo->di_bend = tmp->di_bend;
8104+ dinfo->di_bwh = tmp->di_bwh;
8105+ dinfo->di_bdiropq = tmp->di_bdiropq;
8106+ hd = tmp->di_hdentry;
8107+ bend = dinfo->di_bend;
8108+ for (bindex = tmp->di_bstart; bindex <= bend;
8109+ bindex++) {
8110+ if (au_h_dptr(dentry, bindex))
8111+ continue;
8112+ h_dentry = hd[bindex].hd_dentry;
8113+ if (!h_dentry)
8114+ continue;
5527c038
JR
8115+ AuDebugOn(d_is_negative(h_dentry));
8116+ h_inode = d_inode(h_dentry);
027c5e7a
AM
8117+ AuDebugOn(orig_h.mode
8118+ != (h_inode->i_mode
8119+ & S_IFMT));
8120+ au_set_h_dptr(dentry, bindex,
8121+ dget(h_dentry));
8122+ }
8123+ err = au_refresh_hinode(inode, dentry);
8124+ au_dbg_verify_dinode(dentry);
8125+ }
8126+ } else {
8127+ AuDbg("positive --> positive, different type\n");
8128+ /* similar to the behaviour of removing and creating */
8129+ au_hide(dentry);
8130+ if (inode)
8131+ err = au_refresh_hinode_self(inode);
8132+ au_dbg_verify_dinode(dentry);
8133+ }
8134+ }
8135+
8136+out:
8137+ return err;
8138+}
8139+
79b8bda9
AM
8140+void au_refresh_dop(struct dentry *dentry, int force_reval)
8141+{
8142+ const struct dentry_operations *dop
8143+ = force_reval ? &aufs_dop : dentry->d_sb->s_d_op;
8144+ static const unsigned int mask
8145+ = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE;
8146+
8147+ BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags));
8148+
8149+ if (dentry->d_op == dop)
8150+ return;
8151+
8152+ AuDbg("%pd\n", dentry);
8153+ spin_lock(&dentry->d_lock);
8154+ if (dop == &aufs_dop)
8155+ dentry->d_flags |= mask;
8156+ else
8157+ dentry->d_flags &= ~mask;
8158+ dentry->d_op = dop;
8159+ spin_unlock(&dentry->d_lock);
8160+}
8161+
027c5e7a
AM
8162+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
8163+{
8164+ int err, ebrange;
8165+ unsigned int sigen;
8166+ struct au_dinfo *dinfo, *tmp;
8167+ struct super_block *sb;
8168+ struct inode *inode;
8169+
8170+ DiMustWriteLock(dentry);
8171+ AuDebugOn(IS_ROOT(dentry));
5527c038 8172+ AuDebugOn(d_really_is_negative(parent));
027c5e7a
AM
8173+
8174+ sb = dentry->d_sb;
027c5e7a
AM
8175+ sigen = au_sigen(sb);
8176+ err = au_digen_test(parent, sigen);
8177+ if (unlikely(err))
8178+ goto out;
8179+
8180+ dinfo = au_di(dentry);
8181+ err = au_di_realloc(dinfo, au_sbend(sb) + 1);
8182+ if (unlikely(err))
8183+ goto out;
8184+ ebrange = au_dbrange_test(dentry);
8185+ if (!ebrange)
8186+ ebrange = au_do_refresh_hdentry(dentry, parent);
8187+
38d290e6 8188+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
027c5e7a 8189+ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
5527c038
JR
8190+ if (d_really_is_positive(dentry)) {
8191+ inode = d_inode(dentry);
027c5e7a 8192+ err = au_refresh_hinode_self(inode);
5527c038 8193+ }
027c5e7a
AM
8194+ au_dbg_verify_dinode(dentry);
8195+ if (!err)
8196+ goto out_dgen; /* success */
8197+ goto out;
8198+ }
8199+
8200+ /* temporary dinfo */
8201+ AuDbgDentry(dentry);
8202+ err = -ENOMEM;
8203+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
8204+ if (unlikely(!tmp))
8205+ goto out;
8206+ au_di_swap(tmp, dinfo);
8207+ /* returns the number of positive dentries */
8208+ /*
8209+ * if current working dir is removed, it returns an error.
8210+ * but the dentry is legal.
8211+ */
537831f9 8212+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
027c5e7a
AM
8213+ AuDbgDentry(dentry);
8214+ au_di_swap(tmp, dinfo);
8215+ if (err == -ENOENT)
8216+ err = 0;
8217+ if (err >= 0) {
8218+ /* compare/refresh by dinfo */
8219+ AuDbgDentry(dentry);
8220+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
8221+ au_dbg_verify_dinode(dentry);
8222+ AuTraceErr(err);
8223+ }
8224+ au_rw_write_unlock(&tmp->di_rwsem);
8225+ au_di_free(tmp);
8226+ if (unlikely(err))
8227+ goto out;
8228+
8229+out_dgen:
8230+ au_update_digen(dentry);
8231+out:
8232+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 8233+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
8234+ AuDbgDentry(dentry);
8235+ }
8236+ AuTraceErr(err);
8237+ return err;
8238+}
8239+
b4510431
AM
8240+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
8241+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
8242+{
8243+ int err, valid;
027c5e7a
AM
8244+
8245+ err = 0;
8246+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
8247+ goto out;
027c5e7a
AM
8248+
8249+ AuDbg("b%d\n", bindex);
b4510431
AM
8250+ /*
8251+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
8252+ * due to whiteout and branch permission.
8253+ */
8254+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
8255+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
8256+ /* it may return tri-state */
8257+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 8258+
8259+ if (unlikely(valid < 0))
8260+ err = valid;
8261+ else if (!valid)
8262+ err = -EINVAL;
8263+
4f0767ce 8264+out:
1facf9fc 8265+ AuTraceErr(err);
8266+ return err;
8267+}
8268+
8269+/* todo: remove this */
8270+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 8271+ unsigned int flags, int do_udba)
1facf9fc 8272+{
8273+ int err;
8274+ umode_t mode, h_mode;
8275+ aufs_bindex_t bindex, btail, bstart, ibs, ibe;
38d290e6 8276+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
4a4d8108 8277+ struct inode *h_inode, *h_cached_inode;
1facf9fc 8278+ struct dentry *h_dentry;
8279+ struct qstr *name, *h_name;
8280+
8281+ err = 0;
8282+ plus = 0;
8283+ mode = 0;
1facf9fc 8284+ ibs = -1;
8285+ ibe = -1;
8286+ unhashed = !!d_unhashed(dentry);
8287+ is_root = !!IS_ROOT(dentry);
8288+ name = &dentry->d_name;
38d290e6 8289+ tmpfile = au_di(dentry)->di_tmpfile;
1facf9fc 8290+
8291+ /*
7f207e10
AM
8292+ * Theoretically, REVAL test should be unnecessary in case of
8293+ * {FS,I}NOTIFY.
8294+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 8295+ * IN_ATTRIB for atime/nlink/pageio
1facf9fc 8296+ * Let's do REVAL test too.
8297+ */
8298+ if (do_udba && inode) {
8299+ mode = (inode->i_mode & S_IFMT);
8300+ plus = (inode->i_nlink > 0);
1facf9fc 8301+ ibs = au_ibstart(inode);
8302+ ibe = au_ibend(inode);
8303+ }
8304+
8305+ bstart = au_dbstart(dentry);
8306+ btail = bstart;
8307+ if (inode && S_ISDIR(inode->i_mode))
8308+ btail = au_dbtaildir(dentry);
8309+ for (bindex = bstart; bindex <= btail; bindex++) {
8310+ h_dentry = au_h_dptr(dentry, bindex);
8311+ if (!h_dentry)
8312+ continue;
8313+
523b37e3
AM
8314+ AuDbg("b%d, %pd\n", bindex, h_dentry);
8315+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 8316+ spin_lock(&h_dentry->d_lock);
1facf9fc 8317+ h_name = &h_dentry->d_name;
8318+ if (unlikely(do_udba
8319+ && !is_root
523b37e3
AM
8320+ && ((!h_nfs
8321+ && (unhashed != !!d_unhashed(h_dentry)
38d290e6
JR
8322+ || (!tmpfile
8323+ && !au_qstreq(name, h_name))
8324+ ))
523b37e3
AM
8325+ || (h_nfs
8326+ && !(flags & LOOKUP_OPEN)
8327+ && (h_dentry->d_flags
8328+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 8329+ )) {
38d290e6
JR
8330+ int h_unhashed;
8331+
8332+ h_unhashed = d_unhashed(h_dentry);
027c5e7a 8333+ spin_unlock(&h_dentry->d_lock);
38d290e6
JR
8334+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
8335+ unhashed, h_unhashed, dentry, h_dentry);
1facf9fc 8336+ goto err;
8337+ }
027c5e7a 8338+ spin_unlock(&h_dentry->d_lock);
1facf9fc 8339+
b4510431 8340+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 8341+ if (unlikely(err))
8342+ /* do not goto err, to keep the errno */
8343+ break;
8344+
8345+ /* todo: plink too? */
8346+ if (!do_udba)
8347+ continue;
8348+
8349+ /* UDBA tests */
5527c038 8350+ if (unlikely(!!inode != d_is_positive(h_dentry)))
1facf9fc 8351+ goto err;
8352+
5527c038
JR
8353+ h_inode = NULL;
8354+ if (d_is_positive(h_dentry))
8355+ h_inode = d_inode(h_dentry);
1facf9fc 8356+ h_plus = plus;
8357+ h_mode = mode;
8358+ h_cached_inode = h_inode;
8359+ if (h_inode) {
8360+ h_mode = (h_inode->i_mode & S_IFMT);
8361+ h_plus = (h_inode->i_nlink > 0);
8362+ }
8363+ if (inode && ibs <= bindex && bindex <= ibe)
8364+ h_cached_inode = au_h_iptr(inode, bindex);
8365+
523b37e3 8366+ if (!h_nfs) {
38d290e6 8367+ if (unlikely(plus != h_plus && !tmpfile))
523b37e3
AM
8368+ goto err;
8369+ } else {
8370+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
8371+ && !is_root
8372+ && !IS_ROOT(h_dentry)
8373+ && unhashed != d_unhashed(h_dentry)))
8374+ goto err;
8375+ }
8376+ if (unlikely(mode != h_mode
1facf9fc 8377+ || h_cached_inode != h_inode))
8378+ goto err;
8379+ continue;
8380+
f6b6e03d 8381+err:
1facf9fc 8382+ err = -EINVAL;
8383+ break;
8384+ }
8385+
523b37e3 8386+ AuTraceErr(err);
1facf9fc 8387+ return err;
8388+}
8389+
027c5e7a 8390+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 8391+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
8392+{
8393+ int err;
8394+ struct dentry *parent;
1facf9fc 8395+
027c5e7a 8396+ if (!au_digen_test(dentry, sigen))
1facf9fc 8397+ return 0;
8398+
8399+ parent = dget_parent(dentry);
8400+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8401+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 8402+ au_dbg_verify_gen(parent, sigen);
027c5e7a 8403+ err = au_refresh_dentry(dentry, parent);
1facf9fc 8404+ di_read_unlock(parent, AuLock_IR);
8405+ dput(parent);
027c5e7a 8406+ AuTraceErr(err);
1facf9fc 8407+ return err;
8408+}
8409+
8410+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
8411+{
8412+ int err;
8413+ struct dentry *d, *parent;
1facf9fc 8414+
027c5e7a 8415+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 8416+ return simple_reval_dpath(dentry, sigen);
8417+
8418+ /* slow loop, keep it simple and stupid */
8419+ /* cf: au_cpup_dirs() */
8420+ err = 0;
8421+ parent = NULL;
027c5e7a 8422+ while (au_digen_test(dentry, sigen)) {
1facf9fc 8423+ d = dentry;
8424+ while (1) {
8425+ dput(parent);
8426+ parent = dget_parent(d);
027c5e7a 8427+ if (!au_digen_test(parent, sigen))
1facf9fc 8428+ break;
8429+ d = parent;
8430+ }
8431+
1facf9fc 8432+ if (d != dentry)
027c5e7a 8433+ di_write_lock_child2(d);
1facf9fc 8434+
8435+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
8436+ if (au_digen_test(d, sigen)) {
8437+ /*
8438+ * todo: consolidate with simple_reval_dpath(),
8439+ * do_refresh() and au_reval_for_attr().
8440+ */
1facf9fc 8441+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8442+ err = au_refresh_dentry(d, parent);
1facf9fc 8443+ di_read_unlock(parent, AuLock_IR);
8444+ }
8445+
8446+ if (d != dentry)
8447+ di_write_unlock(d);
8448+ dput(parent);
8449+ if (unlikely(err))
8450+ break;
8451+ }
8452+
8453+ return err;
8454+}
8455+
8456+/*
8457+ * if valid returns 1, otherwise 0.
8458+ */
b4510431 8459+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 8460+{
8461+ int valid, err;
8462+ unsigned int sigen;
8463+ unsigned char do_udba;
8464+ struct super_block *sb;
8465+ struct inode *inode;
8466+
027c5e7a 8467+ /* todo: support rcu-walk? */
b4510431 8468+ if (flags & LOOKUP_RCU)
027c5e7a
AM
8469+ return -ECHILD;
8470+
8471+ valid = 0;
8472+ if (unlikely(!au_di(dentry)))
8473+ goto out;
8474+
e49829fe 8475+ valid = 1;
1facf9fc 8476+ sb = dentry->d_sb;
e49829fe
JR
8477+ /*
8478+ * todo: very ugly
8479+ * i_mutex of parent dir may be held,
8480+ * but we should not return 'invalid' due to busy.
8481+ */
8482+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
8483+ if (unlikely(err)) {
8484+ valid = err;
027c5e7a 8485+ AuTraceErr(err);
e49829fe
JR
8486+ goto out;
8487+ }
5527c038
JR
8488+ inode = NULL;
8489+ if (d_really_is_positive(dentry))
8490+ inode = d_inode(dentry);
c1595e42
JR
8491+ if (unlikely(inode && is_bad_inode(inode))) {
8492+ err = -EINVAL;
8493+ AuTraceErr(err);
8494+ goto out_dgrade;
8495+ }
027c5e7a
AM
8496+ if (unlikely(au_dbrange_test(dentry))) {
8497+ err = -EINVAL;
8498+ AuTraceErr(err);
8499+ goto out_dgrade;
1facf9fc 8500+ }
027c5e7a
AM
8501+
8502+ sigen = au_sigen(sb);
8503+ if (au_digen_test(dentry, sigen)) {
1facf9fc 8504+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
8505+ err = au_reval_dpath(dentry, sigen);
8506+ if (unlikely(err)) {
8507+ AuTraceErr(err);
1facf9fc 8508+ goto out_dgrade;
027c5e7a 8509+ }
1facf9fc 8510+ }
8511+ di_downgrade_lock(dentry, AuLock_IR);
8512+
1facf9fc 8513+ err = -EINVAL;
c1595e42 8514+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
523b37e3 8515+ && inode
38d290e6 8516+ && !(inode->i_state && I_LINKABLE)
79b8bda9
AM
8517+ && (IS_DEADDIR(inode) || !inode->i_nlink)) {
8518+ AuTraceErr(err);
027c5e7a 8519+ goto out_inval;
79b8bda9 8520+ }
027c5e7a 8521+
1facf9fc 8522+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
8523+ if (do_udba && inode) {
8524+ aufs_bindex_t bstart = au_ibstart(inode);
027c5e7a 8525+ struct inode *h_inode;
1facf9fc 8526+
027c5e7a
AM
8527+ if (bstart >= 0) {
8528+ h_inode = au_h_iptr(inode, bstart);
79b8bda9
AM
8529+ if (h_inode && au_test_higen(inode, h_inode)) {
8530+ AuTraceErr(err);
027c5e7a 8531+ goto out_inval;
79b8bda9 8532+ }
027c5e7a 8533+ }
1facf9fc 8534+ }
8535+
b4510431 8536+ err = h_d_revalidate(dentry, inode, flags, do_udba);
027c5e7a 8537+ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
1facf9fc 8538+ err = -EIO;
523b37e3
AM
8539+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
8540+ dentry, err);
027c5e7a 8541+ }
e49829fe 8542+ goto out_inval;
1facf9fc 8543+
4f0767ce 8544+out_dgrade:
1facf9fc 8545+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 8546+out_inval:
1facf9fc 8547+ aufs_read_unlock(dentry, AuLock_IR);
8548+ AuTraceErr(err);
8549+ valid = !err;
e49829fe 8550+out:
027c5e7a 8551+ if (!valid) {
523b37e3 8552+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
8553+ d_drop(dentry);
8554+ }
1facf9fc 8555+ return valid;
8556+}
8557+
8558+static void aufs_d_release(struct dentry *dentry)
8559+{
027c5e7a 8560+ if (au_di(dentry)) {
4a4d8108
AM
8561+ au_di_fin(dentry);
8562+ au_hn_di_reinit(dentry);
1facf9fc 8563+ }
1facf9fc 8564+}
8565+
4a4d8108 8566+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
8567+ .d_revalidate = aufs_d_revalidate,
8568+ .d_weak_revalidate = aufs_d_revalidate,
8569+ .d_release = aufs_d_release
1facf9fc 8570+};
79b8bda9
AM
8571+
8572+/* aufs_dop without d_revalidate */
8573+const struct dentry_operations aufs_dop_noreval = {
8574+ .d_release = aufs_d_release
8575+};
7f207e10
AM
8576diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
8577--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
8578+++ linux/fs/aufs/dentry.h 2015-11-11 17:21:46.918863802 +0100
8579@@ -0,0 +1,234 @@
1facf9fc 8580+/*
2000de60 8581+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 8582+ *
8583+ * This program, aufs is free software; you can redistribute it and/or modify
8584+ * it under the terms of the GNU General Public License as published by
8585+ * the Free Software Foundation; either version 2 of the License, or
8586+ * (at your option) any later version.
dece6358
AM
8587+ *
8588+ * This program is distributed in the hope that it will be useful,
8589+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8590+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8591+ * GNU General Public License for more details.
8592+ *
8593+ * You should have received a copy of the GNU General Public License
523b37e3 8594+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8595+ */
8596+
8597+/*
8598+ * lookup and dentry operations
8599+ */
8600+
8601+#ifndef __AUFS_DENTRY_H__
8602+#define __AUFS_DENTRY_H__
8603+
8604+#ifdef __KERNEL__
8605+
dece6358 8606+#include <linux/dcache.h>
1facf9fc 8607+#include "rwsem.h"
8608+
1facf9fc 8609+struct au_hdentry {
8610+ struct dentry *hd_dentry;
027c5e7a 8611+ aufs_bindex_t hd_id;
1facf9fc 8612+};
8613+
8614+struct au_dinfo {
8615+ atomic_t di_generation;
8616+
dece6358 8617+ struct au_rwsem di_rwsem;
1facf9fc 8618+ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
38d290e6 8619+ unsigned char di_tmpfile; /* to allow the different name */
1facf9fc 8620+ struct au_hdentry *di_hdentry;
4a4d8108 8621+} ____cacheline_aligned_in_smp;
1facf9fc 8622+
8623+/* ---------------------------------------------------------------------- */
8624+
8625+/* dentry.c */
79b8bda9 8626+extern const struct dentry_operations aufs_dop, aufs_dop_noreval;
1facf9fc 8627+struct au_branch;
076b876e 8628+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
1facf9fc 8629+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8630+ struct dentry *h_parent, struct au_branch *br);
8631+
537831f9 8632+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
86dc4139 8633+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 8634+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 8635+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
79b8bda9 8636+void au_refresh_dop(struct dentry *dentry, int force_reval);
1facf9fc 8637+
8638+/* dinfo.c */
4a4d8108 8639+void au_di_init_once(void *_di);
027c5e7a
AM
8640+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
8641+void au_di_free(struct au_dinfo *dinfo);
8642+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
8643+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
8644+int au_di_init(struct dentry *dentry);
8645+void au_di_fin(struct dentry *dentry);
1facf9fc 8646+int au_di_realloc(struct au_dinfo *dinfo, int nbr);
8647+
8648+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
8649+void di_read_unlock(struct dentry *d, int flags);
8650+void di_downgrade_lock(struct dentry *d, int flags);
8651+void di_write_lock(struct dentry *d, unsigned int lsc);
8652+void di_write_unlock(struct dentry *d);
8653+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
8654+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
8655+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
8656+
8657+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 8658+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 8659+aufs_bindex_t au_dbtail(struct dentry *dentry);
8660+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
8661+
8662+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8663+ struct dentry *h_dentry);
027c5e7a
AM
8664+int au_digen_test(struct dentry *dentry, unsigned int sigen);
8665+int au_dbrange_test(struct dentry *dentry);
1facf9fc 8666+void au_update_digen(struct dentry *dentry);
8667+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
8668+void au_update_dbstart(struct dentry *dentry);
8669+void au_update_dbend(struct dentry *dentry);
8670+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
8671+
8672+/* ---------------------------------------------------------------------- */
8673+
8674+static inline struct au_dinfo *au_di(struct dentry *dentry)
8675+{
8676+ return dentry->d_fsdata;
8677+}
8678+
8679+/* ---------------------------------------------------------------------- */
8680+
8681+/* lock subclass for dinfo */
8682+enum {
8683+ AuLsc_DI_CHILD, /* child first */
4a4d8108 8684+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 8685+ AuLsc_DI_CHILD3, /* copyup dirs */
8686+ AuLsc_DI_PARENT,
8687+ AuLsc_DI_PARENT2,
027c5e7a
AM
8688+ AuLsc_DI_PARENT3,
8689+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 8690+};
8691+
8692+/*
8693+ * di_read_lock_child, di_write_lock_child,
8694+ * di_read_lock_child2, di_write_lock_child2,
8695+ * di_read_lock_child3, di_write_lock_child3,
8696+ * di_read_lock_parent, di_write_lock_parent,
8697+ * di_read_lock_parent2, di_write_lock_parent2,
8698+ * di_read_lock_parent3, di_write_lock_parent3,
8699+ */
8700+#define AuReadLockFunc(name, lsc) \
8701+static inline void di_read_lock_##name(struct dentry *d, int flags) \
8702+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
8703+
8704+#define AuWriteLockFunc(name, lsc) \
8705+static inline void di_write_lock_##name(struct dentry *d) \
8706+{ di_write_lock(d, AuLsc_DI_##lsc); }
8707+
8708+#define AuRWLockFuncs(name, lsc) \
8709+ AuReadLockFunc(name, lsc) \
8710+ AuWriteLockFunc(name, lsc)
8711+
8712+AuRWLockFuncs(child, CHILD);
8713+AuRWLockFuncs(child2, CHILD2);
8714+AuRWLockFuncs(child3, CHILD3);
8715+AuRWLockFuncs(parent, PARENT);
8716+AuRWLockFuncs(parent2, PARENT2);
8717+AuRWLockFuncs(parent3, PARENT3);
8718+
8719+#undef AuReadLockFunc
8720+#undef AuWriteLockFunc
8721+#undef AuRWLockFuncs
8722+
8723+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
8724+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
8725+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 8726+
8727+/* ---------------------------------------------------------------------- */
8728+
8729+/* todo: memory barrier? */
8730+static inline unsigned int au_digen(struct dentry *d)
8731+{
8732+ return atomic_read(&au_di(d)->di_generation);
8733+}
8734+
8735+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
8736+{
8737+ hdentry->hd_dentry = NULL;
8738+}
8739+
8740+static inline void au_hdput(struct au_hdentry *hd)
8741+{
4a4d8108
AM
8742+ if (hd)
8743+ dput(hd->hd_dentry);
1facf9fc 8744+}
8745+
8746+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
8747+{
1308ab2a 8748+ DiMustAnyLock(dentry);
1facf9fc 8749+ return au_di(dentry)->di_bstart;
8750+}
8751+
8752+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
8753+{
1308ab2a 8754+ DiMustAnyLock(dentry);
1facf9fc 8755+ return au_di(dentry)->di_bend;
8756+}
8757+
8758+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
8759+{
1308ab2a 8760+ DiMustAnyLock(dentry);
1facf9fc 8761+ return au_di(dentry)->di_bwh;
8762+}
8763+
8764+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
8765+{
1308ab2a 8766+ DiMustAnyLock(dentry);
1facf9fc 8767+ return au_di(dentry)->di_bdiropq;
8768+}
8769+
8770+/* todo: hard/soft set? */
8771+static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
8772+{
1308ab2a 8773+ DiMustWriteLock(dentry);
1facf9fc 8774+ au_di(dentry)->di_bstart = bindex;
8775+}
8776+
8777+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
8778+{
1308ab2a 8779+ DiMustWriteLock(dentry);
1facf9fc 8780+ au_di(dentry)->di_bend = bindex;
8781+}
8782+
8783+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
8784+{
1308ab2a 8785+ DiMustWriteLock(dentry);
1facf9fc 8786+ /* dbwh can be outside of bstart - bend range */
8787+ au_di(dentry)->di_bwh = bindex;
8788+}
8789+
8790+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
8791+{
1308ab2a 8792+ DiMustWriteLock(dentry);
1facf9fc 8793+ au_di(dentry)->di_bdiropq = bindex;
8794+}
8795+
8796+/* ---------------------------------------------------------------------- */
8797+
4a4d8108 8798+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 8799+static inline void au_digen_dec(struct dentry *d)
8800+{
e49829fe 8801+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 8802+}
8803+
4a4d8108 8804+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 8805+{
8806+ dentry->d_fsdata = NULL;
8807+}
8808+#else
4a4d8108
AM
8809+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
8810+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 8811+
8812+#endif /* __KERNEL__ */
8813+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
8814diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
8815--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 8816+++ linux/fs/aufs/dinfo.c 2015-09-24 10:47:58.251386326 +0200
5527c038 8817@@ -0,0 +1,550 @@
1facf9fc 8818+/*
2000de60 8819+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 8820+ *
8821+ * This program, aufs is free software; you can redistribute it and/or modify
8822+ * it under the terms of the GNU General Public License as published by
8823+ * the Free Software Foundation; either version 2 of the License, or
8824+ * (at your option) any later version.
dece6358
AM
8825+ *
8826+ * This program is distributed in the hope that it will be useful,
8827+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8828+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8829+ * GNU General Public License for more details.
8830+ *
8831+ * You should have received a copy of the GNU General Public License
523b37e3 8832+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8833+ */
8834+
8835+/*
8836+ * dentry private data
8837+ */
8838+
8839+#include "aufs.h"
8840+
e49829fe 8841+void au_di_init_once(void *_dinfo)
4a4d8108 8842+{
e49829fe
JR
8843+ struct au_dinfo *dinfo = _dinfo;
8844+ static struct lock_class_key aufs_di;
4a4d8108 8845+
e49829fe
JR
8846+ au_rw_init(&dinfo->di_rwsem);
8847+ au_rw_class(&dinfo->di_rwsem, &aufs_di);
4a4d8108
AM
8848+}
8849+
027c5e7a 8850+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 8851+{
8852+ struct au_dinfo *dinfo;
027c5e7a 8853+ int nbr, i;
1facf9fc 8854+
8855+ dinfo = au_cache_alloc_dinfo();
8856+ if (unlikely(!dinfo))
8857+ goto out;
8858+
1facf9fc 8859+ nbr = au_sbend(sb) + 1;
8860+ if (nbr <= 0)
8861+ nbr = 1;
8862+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
8863+ if (dinfo->di_hdentry) {
8864+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
8865+ dinfo->di_bstart = -1;
8866+ dinfo->di_bend = -1;
8867+ dinfo->di_bwh = -1;
8868+ dinfo->di_bdiropq = -1;
38d290e6 8869+ dinfo->di_tmpfile = 0;
027c5e7a
AM
8870+ for (i = 0; i < nbr; i++)
8871+ dinfo->di_hdentry[i].hd_id = -1;
8872+ goto out;
8873+ }
1facf9fc 8874+
1facf9fc 8875+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
8876+ dinfo = NULL;
8877+
4f0767ce 8878+out:
027c5e7a 8879+ return dinfo;
1facf9fc 8880+}
8881+
027c5e7a 8882+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 8883+{
4a4d8108
AM
8884+ struct au_hdentry *p;
8885+ aufs_bindex_t bend, bindex;
8886+
8887+ /* dentry may not be revalidated */
027c5e7a 8888+ bindex = dinfo->di_bstart;
4a4d8108 8889+ if (bindex >= 0) {
027c5e7a
AM
8890+ bend = dinfo->di_bend;
8891+ p = dinfo->di_hdentry + bindex;
4a4d8108
AM
8892+ while (bindex++ <= bend)
8893+ au_hdput(p++);
8894+ }
027c5e7a
AM
8895+ kfree(dinfo->di_hdentry);
8896+ au_cache_free_dinfo(dinfo);
8897+}
8898+
8899+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
8900+{
8901+ struct au_hdentry *p;
8902+ aufs_bindex_t bi;
8903+
8904+ AuRwMustWriteLock(&a->di_rwsem);
8905+ AuRwMustWriteLock(&b->di_rwsem);
8906+
8907+#define DiSwap(v, name) \
8908+ do { \
8909+ v = a->di_##name; \
8910+ a->di_##name = b->di_##name; \
8911+ b->di_##name = v; \
8912+ } while (0)
8913+
8914+ DiSwap(p, hdentry);
8915+ DiSwap(bi, bstart);
8916+ DiSwap(bi, bend);
8917+ DiSwap(bi, bwh);
8918+ DiSwap(bi, bdiropq);
8919+ /* smp_mb(); */
8920+
8921+#undef DiSwap
8922+}
8923+
8924+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
8925+{
8926+ AuRwMustWriteLock(&dst->di_rwsem);
8927+ AuRwMustWriteLock(&src->di_rwsem);
8928+
8929+ dst->di_bstart = src->di_bstart;
8930+ dst->di_bend = src->di_bend;
8931+ dst->di_bwh = src->di_bwh;
8932+ dst->di_bdiropq = src->di_bdiropq;
8933+ /* smp_mb(); */
8934+}
8935+
8936+int au_di_init(struct dentry *dentry)
8937+{
8938+ int err;
8939+ struct super_block *sb;
8940+ struct au_dinfo *dinfo;
8941+
8942+ err = 0;
8943+ sb = dentry->d_sb;
8944+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
8945+ if (dinfo) {
8946+ atomic_set(&dinfo->di_generation, au_sigen(sb));
8947+ /* smp_mb(); */ /* atomic_set */
8948+ dentry->d_fsdata = dinfo;
8949+ } else
8950+ err = -ENOMEM;
8951+
8952+ return err;
8953+}
8954+
8955+void au_di_fin(struct dentry *dentry)
8956+{
8957+ struct au_dinfo *dinfo;
8958+
8959+ dinfo = au_di(dentry);
8960+ AuRwDestroy(&dinfo->di_rwsem);
8961+ au_di_free(dinfo);
4a4d8108
AM
8962+}
8963+
1facf9fc 8964+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
8965+{
8966+ int err, sz;
8967+ struct au_hdentry *hdp;
8968+
1308ab2a 8969+ AuRwMustWriteLock(&dinfo->di_rwsem);
8970+
1facf9fc 8971+ err = -ENOMEM;
8972+ sz = sizeof(*hdp) * (dinfo->di_bend + 1);
8973+ if (!sz)
8974+ sz = sizeof(*hdp);
8975+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
8976+ if (hdp) {
8977+ dinfo->di_hdentry = hdp;
8978+ err = 0;
8979+ }
8980+
8981+ return err;
8982+}
8983+
8984+/* ---------------------------------------------------------------------- */
8985+
8986+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
8987+{
8988+ switch (lsc) {
8989+ case AuLsc_DI_CHILD:
8990+ ii_write_lock_child(inode);
8991+ break;
8992+ case AuLsc_DI_CHILD2:
8993+ ii_write_lock_child2(inode);
8994+ break;
8995+ case AuLsc_DI_CHILD3:
8996+ ii_write_lock_child3(inode);
8997+ break;
8998+ case AuLsc_DI_PARENT:
8999+ ii_write_lock_parent(inode);
9000+ break;
9001+ case AuLsc_DI_PARENT2:
9002+ ii_write_lock_parent2(inode);
9003+ break;
9004+ case AuLsc_DI_PARENT3:
9005+ ii_write_lock_parent3(inode);
9006+ break;
9007+ default:
9008+ BUG();
9009+ }
9010+}
9011+
9012+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
9013+{
9014+ switch (lsc) {
9015+ case AuLsc_DI_CHILD:
9016+ ii_read_lock_child(inode);
9017+ break;
9018+ case AuLsc_DI_CHILD2:
9019+ ii_read_lock_child2(inode);
9020+ break;
9021+ case AuLsc_DI_CHILD3:
9022+ ii_read_lock_child3(inode);
9023+ break;
9024+ case AuLsc_DI_PARENT:
9025+ ii_read_lock_parent(inode);
9026+ break;
9027+ case AuLsc_DI_PARENT2:
9028+ ii_read_lock_parent2(inode);
9029+ break;
9030+ case AuLsc_DI_PARENT3:
9031+ ii_read_lock_parent3(inode);
9032+ break;
9033+ default:
9034+ BUG();
9035+ }
9036+}
9037+
9038+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
9039+{
5527c038
JR
9040+ struct inode *inode;
9041+
dece6358 9042+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
5527c038
JR
9043+ if (d_really_is_positive(d)) {
9044+ inode = d_inode(d);
1facf9fc 9045+ if (au_ftest_lock(flags, IW))
5527c038 9046+ do_ii_write_lock(inode, lsc);
1facf9fc 9047+ else if (au_ftest_lock(flags, IR))
5527c038 9048+ do_ii_read_lock(inode, lsc);
1facf9fc 9049+ }
9050+}
9051+
9052+void di_read_unlock(struct dentry *d, int flags)
9053+{
5527c038
JR
9054+ struct inode *inode;
9055+
9056+ if (d_really_is_positive(d)) {
9057+ inode = d_inode(d);
027c5e7a
AM
9058+ if (au_ftest_lock(flags, IW)) {
9059+ au_dbg_verify_dinode(d);
5527c038 9060+ ii_write_unlock(inode);
027c5e7a
AM
9061+ } else if (au_ftest_lock(flags, IR)) {
9062+ au_dbg_verify_dinode(d);
5527c038 9063+ ii_read_unlock(inode);
027c5e7a 9064+ }
1facf9fc 9065+ }
dece6358 9066+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 9067+}
9068+
9069+void di_downgrade_lock(struct dentry *d, int flags)
9070+{
5527c038
JR
9071+ if (d_really_is_positive(d) && au_ftest_lock(flags, IR))
9072+ ii_downgrade_lock(d_inode(d));
dece6358 9073+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 9074+}
9075+
9076+void di_write_lock(struct dentry *d, unsigned int lsc)
9077+{
dece6358 9078+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
5527c038
JR
9079+ if (d_really_is_positive(d))
9080+ do_ii_write_lock(d_inode(d), lsc);
1facf9fc 9081+}
9082+
9083+void di_write_unlock(struct dentry *d)
9084+{
027c5e7a 9085+ au_dbg_verify_dinode(d);
5527c038
JR
9086+ if (d_really_is_positive(d))
9087+ ii_write_unlock(d_inode(d));
dece6358 9088+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 9089+}
9090+
9091+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
9092+{
9093+ AuDebugOn(d1 == d2
5527c038 9094+ || d_inode(d1) == d_inode(d2)
1facf9fc 9095+ || d1->d_sb != d2->d_sb);
9096+
9097+ if (isdir && au_test_subdir(d1, d2)) {
9098+ di_write_lock_child(d1);
9099+ di_write_lock_child2(d2);
9100+ } else {
9101+ /* there should be no races */
9102+ di_write_lock_child(d2);
9103+ di_write_lock_child2(d1);
9104+ }
9105+}
9106+
9107+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
9108+{
9109+ AuDebugOn(d1 == d2
5527c038 9110+ || d_inode(d1) == d_inode(d2)
1facf9fc 9111+ || d1->d_sb != d2->d_sb);
9112+
9113+ if (isdir && au_test_subdir(d1, d2)) {
9114+ di_write_lock_parent(d1);
9115+ di_write_lock_parent2(d2);
9116+ } else {
9117+ /* there should be no races */
9118+ di_write_lock_parent(d2);
9119+ di_write_lock_parent2(d1);
9120+ }
9121+}
9122+
9123+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
9124+{
9125+ di_write_unlock(d1);
5527c038 9126+ if (d_inode(d1) == d_inode(d2))
dece6358 9127+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 9128+ else
9129+ di_write_unlock(d2);
9130+}
9131+
9132+/* ---------------------------------------------------------------------- */
9133+
9134+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
9135+{
9136+ struct dentry *d;
9137+
1308ab2a 9138+ DiMustAnyLock(dentry);
9139+
1facf9fc 9140+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
9141+ return NULL;
9142+ AuDebugOn(bindex < 0);
9143+ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
c1595e42 9144+ AuDebugOn(d && au_dcount(d) <= 0);
1facf9fc 9145+ return d;
9146+}
9147+
2cbb1c4b
JR
9148+/*
9149+ * extended version of au_h_dptr().
38d290e6
JR
9150+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
9151+ * error.
2cbb1c4b
JR
9152+ */
9153+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
9154+{
9155+ struct dentry *h_dentry;
9156+ struct inode *inode, *h_inode;
9157+
5527c038 9158+ AuDebugOn(d_really_is_negative(dentry));
2cbb1c4b
JR
9159+
9160+ h_dentry = NULL;
9161+ if (au_dbstart(dentry) <= bindex
9162+ && bindex <= au_dbend(dentry))
9163+ h_dentry = au_h_dptr(dentry, bindex);
38d290e6 9164+ if (h_dentry && !au_d_linkable(h_dentry)) {
2cbb1c4b
JR
9165+ dget(h_dentry);
9166+ goto out; /* success */
9167+ }
9168+
5527c038 9169+ inode = d_inode(dentry);
2cbb1c4b
JR
9170+ AuDebugOn(bindex < au_ibstart(inode));
9171+ AuDebugOn(au_ibend(inode) < bindex);
9172+ h_inode = au_h_iptr(inode, bindex);
9173+ h_dentry = d_find_alias(h_inode);
9174+ if (h_dentry) {
9175+ if (!IS_ERR(h_dentry)) {
38d290e6 9176+ if (!au_d_linkable(h_dentry))
2cbb1c4b
JR
9177+ goto out; /* success */
9178+ dput(h_dentry);
9179+ } else
9180+ goto out;
9181+ }
9182+
9183+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
9184+ h_dentry = au_plink_lkup(inode, bindex);
9185+ AuDebugOn(!h_dentry);
9186+ if (!IS_ERR(h_dentry)) {
9187+ if (!au_d_hashed_positive(h_dentry))
9188+ goto out; /* success */
9189+ dput(h_dentry);
9190+ h_dentry = NULL;
9191+ }
9192+ }
9193+
9194+out:
9195+ AuDbgDentry(h_dentry);
9196+ return h_dentry;
9197+}
9198+
1facf9fc 9199+aufs_bindex_t au_dbtail(struct dentry *dentry)
9200+{
9201+ aufs_bindex_t bend, bwh;
9202+
9203+ bend = au_dbend(dentry);
9204+ if (0 <= bend) {
9205+ bwh = au_dbwh(dentry);
9206+ if (!bwh)
9207+ return bwh;
9208+ if (0 < bwh && bwh < bend)
9209+ return bwh - 1;
9210+ }
9211+ return bend;
9212+}
9213+
9214+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
9215+{
9216+ aufs_bindex_t bend, bopq;
9217+
9218+ bend = au_dbtail(dentry);
9219+ if (0 <= bend) {
9220+ bopq = au_dbdiropq(dentry);
9221+ if (0 <= bopq && bopq < bend)
9222+ bend = bopq;
9223+ }
9224+ return bend;
9225+}
9226+
9227+/* ---------------------------------------------------------------------- */
9228+
9229+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9230+ struct dentry *h_dentry)
9231+{
9232+ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
027c5e7a 9233+ struct au_branch *br;
1facf9fc 9234+
1308ab2a 9235+ DiMustWriteLock(dentry);
9236+
4a4d8108 9237+ au_hdput(hd);
1facf9fc 9238+ hd->hd_dentry = h_dentry;
027c5e7a
AM
9239+ if (h_dentry) {
9240+ br = au_sbr(dentry->d_sb, bindex);
9241+ hd->hd_id = br->br_id;
9242+ }
9243+}
9244+
9245+int au_dbrange_test(struct dentry *dentry)
9246+{
9247+ int err;
9248+ aufs_bindex_t bstart, bend;
9249+
9250+ err = 0;
9251+ bstart = au_dbstart(dentry);
9252+ bend = au_dbend(dentry);
9253+ if (bstart >= 0)
9254+ AuDebugOn(bend < 0 && bstart > bend);
9255+ else {
9256+ err = -EIO;
9257+ AuDebugOn(bend >= 0);
9258+ }
9259+
9260+ return err;
9261+}
9262+
9263+int au_digen_test(struct dentry *dentry, unsigned int sigen)
9264+{
9265+ int err;
9266+
9267+ err = 0;
9268+ if (unlikely(au_digen(dentry) != sigen
5527c038 9269+ || au_iigen_test(d_inode(dentry), sigen)))
027c5e7a
AM
9270+ err = -EIO;
9271+
9272+ return err;
1facf9fc 9273+}
9274+
9275+void au_update_digen(struct dentry *dentry)
9276+{
9277+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
9278+ /* smp_mb(); */ /* atomic_set */
9279+}
9280+
9281+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
9282+{
9283+ struct au_dinfo *dinfo;
9284+ struct dentry *h_d;
4a4d8108 9285+ struct au_hdentry *hdp;
1facf9fc 9286+
1308ab2a 9287+ DiMustWriteLock(dentry);
9288+
1facf9fc 9289+ dinfo = au_di(dentry);
9290+ if (!dinfo || dinfo->di_bstart < 0)
9291+ return;
9292+
4a4d8108 9293+ hdp = dinfo->di_hdentry;
1facf9fc 9294+ if (do_put_zero) {
9295+ aufs_bindex_t bindex, bend;
9296+
9297+ bend = dinfo->di_bend;
9298+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
4a4d8108 9299+ h_d = hdp[0 + bindex].hd_dentry;
5527c038 9300+ if (h_d && d_is_negative(h_d))
1facf9fc 9301+ au_set_h_dptr(dentry, bindex, NULL);
9302+ }
9303+ }
9304+
9305+ dinfo->di_bstart = -1;
9306+ while (++dinfo->di_bstart <= dinfo->di_bend)
4a4d8108 9307+ if (hdp[0 + dinfo->di_bstart].hd_dentry)
1facf9fc 9308+ break;
9309+ if (dinfo->di_bstart > dinfo->di_bend) {
9310+ dinfo->di_bstart = -1;
9311+ dinfo->di_bend = -1;
9312+ return;
9313+ }
9314+
9315+ dinfo->di_bend++;
9316+ while (0 <= --dinfo->di_bend)
4a4d8108 9317+ if (hdp[0 + dinfo->di_bend].hd_dentry)
1facf9fc 9318+ break;
9319+ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
9320+}
9321+
9322+void au_update_dbstart(struct dentry *dentry)
9323+{
9324+ aufs_bindex_t bindex, bend;
9325+ struct dentry *h_dentry;
9326+
9327+ bend = au_dbend(dentry);
9328+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
9329+ h_dentry = au_h_dptr(dentry, bindex);
9330+ if (!h_dentry)
9331+ continue;
5527c038 9332+ if (d_is_positive(h_dentry)) {
1facf9fc 9333+ au_set_dbstart(dentry, bindex);
9334+ return;
9335+ }
9336+ au_set_h_dptr(dentry, bindex, NULL);
9337+ }
9338+}
9339+
9340+void au_update_dbend(struct dentry *dentry)
9341+{
9342+ aufs_bindex_t bindex, bstart;
9343+ struct dentry *h_dentry;
9344+
9345+ bstart = au_dbstart(dentry);
7f207e10 9346+ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
1facf9fc 9347+ h_dentry = au_h_dptr(dentry, bindex);
9348+ if (!h_dentry)
9349+ continue;
5527c038 9350+ if (d_is_positive(h_dentry)) {
1facf9fc 9351+ au_set_dbend(dentry, bindex);
9352+ return;
9353+ }
9354+ au_set_h_dptr(dentry, bindex, NULL);
9355+ }
9356+}
9357+
9358+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
9359+{
9360+ aufs_bindex_t bindex, bend;
9361+
9362+ bend = au_dbend(dentry);
9363+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
9364+ if (au_h_dptr(dentry, bindex) == h_dentry)
9365+ return bindex;
9366+ return -1;
9367+}
7f207e10
AM
9368diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
9369--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 9370+++ linux/fs/aufs/dir.c 2015-09-24 10:47:58.251386326 +0200
5527c038 9371@@ -0,0 +1,753 @@
1facf9fc 9372+/*
2000de60 9373+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 9374+ *
9375+ * This program, aufs is free software; you can redistribute it and/or modify
9376+ * it under the terms of the GNU General Public License as published by
9377+ * the Free Software Foundation; either version 2 of the License, or
9378+ * (at your option) any later version.
dece6358
AM
9379+ *
9380+ * This program is distributed in the hope that it will be useful,
9381+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9382+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9383+ * GNU General Public License for more details.
9384+ *
9385+ * You should have received a copy of the GNU General Public License
523b37e3 9386+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9387+ */
9388+
9389+/*
9390+ * directory operations
9391+ */
9392+
9393+#include <linux/fs_stack.h>
9394+#include "aufs.h"
9395+
9396+void au_add_nlink(struct inode *dir, struct inode *h_dir)
9397+{
9dbd164d
AM
9398+ unsigned int nlink;
9399+
1facf9fc 9400+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9401+
9dbd164d
AM
9402+ nlink = dir->i_nlink;
9403+ nlink += h_dir->i_nlink - 2;
1facf9fc 9404+ if (h_dir->i_nlink < 2)
9dbd164d 9405+ nlink += 2;
f6b6e03d 9406+ smp_mb(); /* for i_nlink */
7eafdf33 9407+ /* 0 can happen in revaliding */
92d182d2 9408+ set_nlink(dir, nlink);
1facf9fc 9409+}
9410+
9411+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
9412+{
9dbd164d
AM
9413+ unsigned int nlink;
9414+
1facf9fc 9415+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9416+
9dbd164d
AM
9417+ nlink = dir->i_nlink;
9418+ nlink -= h_dir->i_nlink - 2;
1facf9fc 9419+ if (h_dir->i_nlink < 2)
9dbd164d 9420+ nlink -= 2;
f6b6e03d 9421+ smp_mb(); /* for i_nlink */
92d182d2 9422+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 9423+ set_nlink(dir, nlink);
1facf9fc 9424+}
9425+
1308ab2a 9426+loff_t au_dir_size(struct file *file, struct dentry *dentry)
9427+{
9428+ loff_t sz;
9429+ aufs_bindex_t bindex, bend;
9430+ struct file *h_file;
9431+ struct dentry *h_dentry;
9432+
9433+ sz = 0;
9434+ if (file) {
2000de60 9435+ AuDebugOn(!d_is_dir(file->f_path.dentry));
1308ab2a 9436+
4a4d8108 9437+ bend = au_fbend_dir(file);
1308ab2a 9438+ for (bindex = au_fbstart(file);
9439+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
9440+ bindex++) {
4a4d8108 9441+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
9442+ if (h_file && file_inode(h_file))
9443+ sz += vfsub_f_size_read(h_file);
1308ab2a 9444+ }
9445+ } else {
9446+ AuDebugOn(!dentry);
2000de60 9447+ AuDebugOn(!d_is_dir(dentry));
1308ab2a 9448+
9449+ bend = au_dbtaildir(dentry);
9450+ for (bindex = au_dbstart(dentry);
9451+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
9452+ bindex++) {
9453+ h_dentry = au_h_dptr(dentry, bindex);
5527c038
JR
9454+ if (h_dentry && d_is_positive(h_dentry))
9455+ sz += i_size_read(d_inode(h_dentry));
1308ab2a 9456+ }
9457+ }
9458+ if (sz < KMALLOC_MAX_SIZE)
9459+ sz = roundup_pow_of_two(sz);
9460+ if (sz > KMALLOC_MAX_SIZE)
9461+ sz = KMALLOC_MAX_SIZE;
9462+ else if (sz < NAME_MAX) {
9463+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
9464+ sz = AUFS_RDBLK_DEF;
9465+ }
9466+ return sz;
9467+}
9468+
b912730e
AM
9469+struct au_dir_ts_arg {
9470+ struct dentry *dentry;
9471+ aufs_bindex_t brid;
9472+};
9473+
9474+static void au_do_dir_ts(void *arg)
9475+{
9476+ struct au_dir_ts_arg *a = arg;
9477+ struct au_dtime dt;
9478+ struct path h_path;
9479+ struct inode *dir, *h_dir;
9480+ struct super_block *sb;
9481+ struct au_branch *br;
9482+ struct au_hinode *hdir;
9483+ int err;
9484+ aufs_bindex_t bstart, bindex;
9485+
9486+ sb = a->dentry->d_sb;
5527c038 9487+ if (d_really_is_negative(a->dentry))
b912730e 9488+ goto out;
b912730e
AM
9489+ aufs_read_lock(a->dentry, AuLock_DW | AuLock_DIR); /* noflush */
9490+
5527c038
JR
9491+ /* no dir->i_mutex lock */
9492+ dir = d_inode(a->dentry);
b912730e
AM
9493+ bstart = au_ibstart(dir);
9494+ bindex = au_br_index(sb, a->brid);
9495+ if (bindex < bstart)
9496+ goto out_unlock;
9497+
9498+ br = au_sbr(sb, bindex);
9499+ h_path.dentry = au_h_dptr(a->dentry, bindex);
9500+ if (!h_path.dentry)
9501+ goto out_unlock;
9502+ h_path.mnt = au_br_mnt(br);
9503+ au_dtime_store(&dt, a->dentry, &h_path);
9504+
9505+ br = au_sbr(sb, bstart);
9506+ if (!au_br_writable(br->br_perm))
9507+ goto out_unlock;
9508+ h_path.dentry = au_h_dptr(a->dentry, bstart);
9509+ h_path.mnt = au_br_mnt(br);
9510+ err = vfsub_mnt_want_write(h_path.mnt);
9511+ if (err)
9512+ goto out_unlock;
9513+ hdir = au_hi(dir, bstart);
9514+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
9515+ h_dir = au_h_iptr(dir, bstart);
9516+ if (h_dir->i_nlink
9517+ && timespec_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) {
9518+ dt.dt_h_path = h_path;
9519+ au_dtime_revert(&dt);
9520+ }
9521+ au_hn_imtx_unlock(hdir);
9522+ vfsub_mnt_drop_write(h_path.mnt);
9523+ au_cpup_attr_timesizes(dir);
9524+
9525+out_unlock:
9526+ aufs_read_unlock(a->dentry, AuLock_DW);
9527+out:
9528+ dput(a->dentry);
9529+ au_nwt_done(&au_sbi(sb)->si_nowait);
9530+ kfree(arg);
9531+}
9532+
9533+void au_dir_ts(struct inode *dir, aufs_bindex_t bindex)
9534+{
9535+ int perm, wkq_err;
9536+ aufs_bindex_t bstart;
9537+ struct au_dir_ts_arg *arg;
9538+ struct dentry *dentry;
9539+ struct super_block *sb;
9540+
9541+ IMustLock(dir);
9542+
9543+ dentry = d_find_any_alias(dir);
9544+ AuDebugOn(!dentry);
9545+ sb = dentry->d_sb;
9546+ bstart = au_ibstart(dir);
9547+ if (bstart == bindex) {
9548+ au_cpup_attr_timesizes(dir);
9549+ goto out;
9550+ }
9551+
9552+ perm = au_sbr_perm(sb, bstart);
9553+ if (!au_br_writable(perm))
9554+ goto out;
9555+
9556+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
9557+ if (!arg)
9558+ goto out;
9559+
9560+ arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */
9561+ arg->brid = au_sbr_id(sb, bindex);
9562+ wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0);
9563+ if (unlikely(wkq_err)) {
9564+ pr_err("wkq %d\n", wkq_err);
9565+ dput(dentry);
9566+ kfree(arg);
9567+ }
9568+
9569+out:
9570+ dput(dentry);
9571+}
9572+
1facf9fc 9573+/* ---------------------------------------------------------------------- */
9574+
9575+static int reopen_dir(struct file *file)
9576+{
9577+ int err;
9578+ unsigned int flags;
9579+ aufs_bindex_t bindex, btail, bstart;
9580+ struct dentry *dentry, *h_dentry;
9581+ struct file *h_file;
9582+
9583+ /* open all lower dirs */
2000de60 9584+ dentry = file->f_path.dentry;
1facf9fc 9585+ bstart = au_dbstart(dentry);
9586+ for (bindex = au_fbstart(file); bindex < bstart; bindex++)
9587+ au_set_h_fptr(file, bindex, NULL);
9588+ au_set_fbstart(file, bstart);
9589+
9590+ btail = au_dbtaildir(dentry);
4a4d8108 9591+ for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
1facf9fc 9592+ au_set_h_fptr(file, bindex, NULL);
4a4d8108 9593+ au_set_fbend_dir(file, btail);
1facf9fc 9594+
4a4d8108 9595+ flags = vfsub_file_flags(file);
1facf9fc 9596+ for (bindex = bstart; bindex <= btail; bindex++) {
9597+ h_dentry = au_h_dptr(dentry, bindex);
9598+ if (!h_dentry)
9599+ continue;
4a4d8108 9600+ h_file = au_hf_dir(file, bindex);
1facf9fc 9601+ if (h_file)
9602+ continue;
9603+
392086de 9604+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9605+ err = PTR_ERR(h_file);
9606+ if (IS_ERR(h_file))
9607+ goto out; /* close all? */
9608+ au_set_h_fptr(file, bindex, h_file);
9609+ }
9610+ au_update_figen(file);
9611+ /* todo: necessary? */
9612+ /* file->f_ra = h_file->f_ra; */
9613+ err = 0;
9614+
4f0767ce 9615+out:
1facf9fc 9616+ return err;
9617+}
9618+
b912730e 9619+static int do_open_dir(struct file *file, int flags, struct file *h_file)
1facf9fc 9620+{
9621+ int err;
9622+ aufs_bindex_t bindex, btail;
9623+ struct dentry *dentry, *h_dentry;
1facf9fc 9624+
1308ab2a 9625+ FiMustWriteLock(file);
b912730e 9626+ AuDebugOn(h_file);
1308ab2a 9627+
523b37e3 9628+ err = 0;
2000de60 9629+ dentry = file->f_path.dentry;
5527c038 9630+ file->f_version = d_inode(dentry)->i_version;
1facf9fc 9631+ bindex = au_dbstart(dentry);
9632+ au_set_fbstart(file, bindex);
9633+ btail = au_dbtaildir(dentry);
4a4d8108 9634+ au_set_fbend_dir(file, btail);
1facf9fc 9635+ for (; !err && bindex <= btail; bindex++) {
9636+ h_dentry = au_h_dptr(dentry, bindex);
9637+ if (!h_dentry)
9638+ continue;
9639+
392086de 9640+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9641+ if (IS_ERR(h_file)) {
9642+ err = PTR_ERR(h_file);
9643+ break;
9644+ }
9645+ au_set_h_fptr(file, bindex, h_file);
9646+ }
9647+ au_update_figen(file);
9648+ /* todo: necessary? */
9649+ /* file->f_ra = h_file->f_ra; */
9650+ if (!err)
9651+ return 0; /* success */
9652+
9653+ /* close all */
9654+ for (bindex = au_fbstart(file); bindex <= btail; bindex++)
9655+ au_set_h_fptr(file, bindex, NULL);
9656+ au_set_fbstart(file, -1);
4a4d8108
AM
9657+ au_set_fbend_dir(file, -1);
9658+
1facf9fc 9659+ return err;
9660+}
9661+
9662+static int aufs_open_dir(struct inode *inode __maybe_unused,
9663+ struct file *file)
9664+{
4a4d8108
AM
9665+ int err;
9666+ struct super_block *sb;
9667+ struct au_fidir *fidir;
9668+
9669+ err = -ENOMEM;
2000de60 9670+ sb = file->f_path.dentry->d_sb;
4a4d8108 9671+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 9672+ fidir = au_fidir_alloc(sb);
4a4d8108 9673+ if (fidir) {
b912730e
AM
9674+ struct au_do_open_args args = {
9675+ .open = do_open_dir,
9676+ .fidir = fidir
9677+ };
9678+ err = au_do_open(file, &args);
4a4d8108
AM
9679+ if (unlikely(err))
9680+ kfree(fidir);
9681+ }
9682+ si_read_unlock(sb);
9683+ return err;
1facf9fc 9684+}
9685+
9686+static int aufs_release_dir(struct inode *inode __maybe_unused,
9687+ struct file *file)
9688+{
9689+ struct au_vdir *vdir_cache;
4a4d8108
AM
9690+ struct au_finfo *finfo;
9691+ struct au_fidir *fidir;
9692+ aufs_bindex_t bindex, bend;
1facf9fc 9693+
4a4d8108
AM
9694+ finfo = au_fi(file);
9695+ fidir = finfo->fi_hdir;
9696+ if (fidir) {
076b876e 9697+ au_sphl_del(&finfo->fi_hlist,
2000de60 9698+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108
AM
9699+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
9700+ if (vdir_cache)
9701+ au_vdir_free(vdir_cache);
9702+
9703+ bindex = finfo->fi_btop;
9704+ if (bindex >= 0) {
9705+ /*
9706+ * calls fput() instead of filp_close(),
9707+ * since no dnotify or lock for the lower file.
9708+ */
9709+ bend = fidir->fd_bbot;
9710+ for (; bindex <= bend; bindex++)
9711+ au_set_h_fptr(file, bindex, NULL);
9712+ }
9713+ kfree(fidir);
9714+ finfo->fi_hdir = NULL;
1facf9fc 9715+ }
1facf9fc 9716+ au_finfo_fin(file);
1facf9fc 9717+ return 0;
9718+}
9719+
9720+/* ---------------------------------------------------------------------- */
9721+
4a4d8108
AM
9722+static int au_do_flush_dir(struct file *file, fl_owner_t id)
9723+{
9724+ int err;
9725+ aufs_bindex_t bindex, bend;
9726+ struct file *h_file;
9727+
9728+ err = 0;
9729+ bend = au_fbend_dir(file);
9730+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
9731+ h_file = au_hf_dir(file, bindex);
9732+ if (h_file)
9733+ err = vfsub_flush(h_file, id);
9734+ }
9735+ return err;
9736+}
9737+
9738+static int aufs_flush_dir(struct file *file, fl_owner_t id)
9739+{
9740+ return au_do_flush(file, id, au_do_flush_dir);
9741+}
9742+
9743+/* ---------------------------------------------------------------------- */
9744+
1facf9fc 9745+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
9746+{
9747+ int err;
9748+ aufs_bindex_t bend, bindex;
9749+ struct inode *inode;
9750+ struct super_block *sb;
9751+
9752+ err = 0;
9753+ sb = dentry->d_sb;
5527c038 9754+ inode = d_inode(dentry);
1facf9fc 9755+ IMustLock(inode);
9756+ bend = au_dbend(dentry);
9757+ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
9758+ struct path h_path;
1facf9fc 9759+
9760+ if (au_test_ro(sb, bindex, inode))
9761+ continue;
9762+ h_path.dentry = au_h_dptr(dentry, bindex);
9763+ if (!h_path.dentry)
9764+ continue;
1facf9fc 9765+
1facf9fc 9766+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 9767+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 9768+ }
9769+
9770+ return err;
9771+}
9772+
9773+static int au_do_fsync_dir(struct file *file, int datasync)
9774+{
9775+ int err;
9776+ aufs_bindex_t bend, bindex;
9777+ struct file *h_file;
9778+ struct super_block *sb;
9779+ struct inode *inode;
1facf9fc 9780+
9781+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9782+ if (unlikely(err))
9783+ goto out;
9784+
c06a8ce3 9785+ inode = file_inode(file);
b912730e 9786+ sb = inode->i_sb;
4a4d8108 9787+ bend = au_fbend_dir(file);
1facf9fc 9788+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
4a4d8108 9789+ h_file = au_hf_dir(file, bindex);
1facf9fc 9790+ if (!h_file || au_test_ro(sb, bindex, inode))
9791+ continue;
9792+
53392da6 9793+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 9794+ }
9795+
4f0767ce 9796+out:
1facf9fc 9797+ return err;
9798+}
9799+
9800+/*
9801+ * @file may be NULL
9802+ */
1e00d052
AM
9803+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
9804+ int datasync)
1facf9fc 9805+{
9806+ int err;
b752ccd1 9807+ struct dentry *dentry;
5527c038 9808+ struct inode *inode;
1facf9fc 9809+ struct super_block *sb;
1e00d052 9810+ struct mutex *mtx;
1facf9fc 9811+
9812+ err = 0;
2000de60 9813+ dentry = file->f_path.dentry;
5527c038
JR
9814+ inode = d_inode(dentry);
9815+ mtx = &inode->i_mutex;
1e00d052 9816+ mutex_lock(mtx);
1facf9fc 9817+ sb = dentry->d_sb;
9818+ si_noflush_read_lock(sb);
9819+ if (file)
9820+ err = au_do_fsync_dir(file, datasync);
9821+ else {
9822+ di_write_lock_child(dentry);
9823+ err = au_do_fsync_dir_no_file(dentry, datasync);
9824+ }
5527c038 9825+ au_cpup_attr_timesizes(inode);
1facf9fc 9826+ di_write_unlock(dentry);
9827+ if (file)
9828+ fi_write_unlock(file);
9829+
9830+ si_read_unlock(sb);
1e00d052 9831+ mutex_unlock(mtx);
1facf9fc 9832+ return err;
9833+}
9834+
9835+/* ---------------------------------------------------------------------- */
9836+
392086de 9837+static int aufs_iterate(struct file *file, struct dir_context *ctx)
1facf9fc 9838+{
9839+ int err;
9840+ struct dentry *dentry;
9dbd164d 9841+ struct inode *inode, *h_inode;
1facf9fc 9842+ struct super_block *sb;
9843+
523b37e3 9844+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 9845+
2000de60 9846+ dentry = file->f_path.dentry;
5527c038 9847+ inode = d_inode(dentry);
1facf9fc 9848+ IMustLock(inode);
9849+
9850+ sb = dentry->d_sb;
9851+ si_read_lock(sb, AuLock_FLUSH);
9852+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9853+ if (unlikely(err))
9854+ goto out;
027c5e7a
AM
9855+ err = au_alive_dir(dentry);
9856+ if (!err)
9857+ err = au_vdir_init(file);
1facf9fc 9858+ di_downgrade_lock(dentry, AuLock_IR);
9859+ if (unlikely(err))
9860+ goto out_unlock;
9861+
9dbd164d 9862+ h_inode = au_h_iptr(inode, au_ibstart(inode));
b752ccd1 9863+ if (!au_test_nfsd()) {
392086de 9864+ err = au_vdir_fill_de(file, ctx);
9dbd164d 9865+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 9866+ } else {
9867+ /*
9868+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
9869+ * encode_fh() and others.
9870+ */
9dbd164d 9871+ atomic_inc(&h_inode->i_count);
1facf9fc 9872+ di_read_unlock(dentry, AuLock_IR);
9873+ si_read_unlock(sb);
392086de 9874+ err = au_vdir_fill_de(file, ctx);
1facf9fc 9875+ fsstack_copy_attr_atime(inode, h_inode);
9876+ fi_write_unlock(file);
9dbd164d 9877+ iput(h_inode);
1facf9fc 9878+
9879+ AuTraceErr(err);
9880+ return err;
9881+ }
9882+
4f0767ce 9883+out_unlock:
1facf9fc 9884+ di_read_unlock(dentry, AuLock_IR);
9885+ fi_write_unlock(file);
4f0767ce 9886+out:
1facf9fc 9887+ si_read_unlock(sb);
9888+ return err;
9889+}
9890+
9891+/* ---------------------------------------------------------------------- */
9892+
9893+#define AuTestEmpty_WHONLY 1
dece6358
AM
9894+#define AuTestEmpty_CALLED (1 << 1)
9895+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 9896+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
9897+#define au_fset_testempty(flags, name) \
9898+ do { (flags) |= AuTestEmpty_##name; } while (0)
9899+#define au_fclr_testempty(flags, name) \
9900+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 9901+
dece6358
AM
9902+#ifndef CONFIG_AUFS_SHWH
9903+#undef AuTestEmpty_SHWH
9904+#define AuTestEmpty_SHWH 0
9905+#endif
9906+
1facf9fc 9907+struct test_empty_arg {
392086de 9908+ struct dir_context ctx;
1308ab2a 9909+ struct au_nhash *whlist;
1facf9fc 9910+ unsigned int flags;
9911+ int err;
9912+ aufs_bindex_t bindex;
9913+};
9914+
392086de
AM
9915+static int test_empty_cb(struct dir_context *ctx, const char *__name,
9916+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 9917+ unsigned int d_type)
1facf9fc 9918+{
392086de
AM
9919+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
9920+ ctx);
1facf9fc 9921+ char *name = (void *)__name;
9922+
9923+ arg->err = 0;
9924+ au_fset_testempty(arg->flags, CALLED);
9925+ /* smp_mb(); */
9926+ if (name[0] == '.'
9927+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
9928+ goto out; /* success */
9929+
9930+ if (namelen <= AUFS_WH_PFX_LEN
9931+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
9932+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 9933+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9934+ arg->err = -ENOTEMPTY;
9935+ goto out;
9936+ }
9937+
9938+ name += AUFS_WH_PFX_LEN;
9939+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 9940+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9941+ arg->err = au_nhash_append_wh
1308ab2a 9942+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 9943+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 9944+
4f0767ce 9945+out:
1facf9fc 9946+ /* smp_mb(); */
9947+ AuTraceErr(arg->err);
9948+ return arg->err;
9949+}
9950+
9951+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9952+{
9953+ int err;
9954+ struct file *h_file;
9955+
9956+ h_file = au_h_open(dentry, arg->bindex,
9957+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 9958+ /*file*/NULL, /*force_wr*/0);
1facf9fc 9959+ err = PTR_ERR(h_file);
9960+ if (IS_ERR(h_file))
9961+ goto out;
9962+
9963+ err = 0;
9964+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 9965+ && !file_inode(h_file)->i_nlink)
1facf9fc 9966+ goto out_put;
9967+
9968+ do {
9969+ arg->err = 0;
9970+ au_fclr_testempty(arg->flags, CALLED);
9971+ /* smp_mb(); */
392086de 9972+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 9973+ if (err >= 0)
9974+ err = arg->err;
9975+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
9976+
4f0767ce 9977+out_put:
1facf9fc 9978+ fput(h_file);
9979+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 9980+out:
1facf9fc 9981+ return err;
9982+}
9983+
9984+struct do_test_empty_args {
9985+ int *errp;
9986+ struct dentry *dentry;
9987+ struct test_empty_arg *arg;
9988+};
9989+
9990+static void call_do_test_empty(void *args)
9991+{
9992+ struct do_test_empty_args *a = args;
9993+ *a->errp = do_test_empty(a->dentry, a->arg);
9994+}
9995+
9996+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9997+{
9998+ int err, wkq_err;
9999+ struct dentry *h_dentry;
10000+ struct inode *h_inode;
10001+
10002+ h_dentry = au_h_dptr(dentry, arg->bindex);
5527c038 10003+ h_inode = d_inode(h_dentry);
53392da6 10004+ /* todo: i_mode changes anytime? */
1facf9fc 10005+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
10006+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
10007+ mutex_unlock(&h_inode->i_mutex);
10008+ if (!err)
10009+ err = do_test_empty(dentry, arg);
10010+ else {
10011+ struct do_test_empty_args args = {
10012+ .errp = &err,
10013+ .dentry = dentry,
10014+ .arg = arg
10015+ };
10016+ unsigned int flags = arg->flags;
10017+
10018+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
10019+ if (unlikely(wkq_err))
10020+ err = wkq_err;
10021+ arg->flags = flags;
10022+ }
10023+
10024+ return err;
10025+}
10026+
10027+int au_test_empty_lower(struct dentry *dentry)
10028+{
10029+ int err;
1308ab2a 10030+ unsigned int rdhash;
1facf9fc 10031+ aufs_bindex_t bindex, bstart, btail;
1308ab2a 10032+ struct au_nhash whlist;
392086de
AM
10033+ struct test_empty_arg arg = {
10034+ .ctx = {
2000de60 10035+ .actor = test_empty_cb
392086de
AM
10036+ }
10037+ };
076b876e 10038+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
1facf9fc 10039+
dece6358
AM
10040+ SiMustAnyLock(dentry->d_sb);
10041+
1308ab2a 10042+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
10043+ if (!rdhash)
10044+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
10045+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 10046+ if (unlikely(err))
1facf9fc 10047+ goto out;
10048+
1facf9fc 10049+ arg.flags = 0;
1308ab2a 10050+ arg.whlist = &whlist;
10051+ bstart = au_dbstart(dentry);
dece6358
AM
10052+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10053+ au_fset_testempty(arg.flags, SHWH);
076b876e
AM
10054+ test_empty = do_test_empty;
10055+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
10056+ test_empty = sio_test_empty;
1facf9fc 10057+ arg.bindex = bstart;
076b876e 10058+ err = test_empty(dentry, &arg);
1facf9fc 10059+ if (unlikely(err))
10060+ goto out_whlist;
10061+
10062+ au_fset_testempty(arg.flags, WHONLY);
10063+ btail = au_dbtaildir(dentry);
10064+ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
10065+ struct dentry *h_dentry;
10066+
10067+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 10068+ if (h_dentry && d_is_positive(h_dentry)) {
1facf9fc 10069+ arg.bindex = bindex;
076b876e 10070+ err = test_empty(dentry, &arg);
1facf9fc 10071+ }
10072+ }
10073+
4f0767ce 10074+out_whlist:
1308ab2a 10075+ au_nhash_wh_free(&whlist);
4f0767ce 10076+out:
1facf9fc 10077+ return err;
10078+}
10079+
10080+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
10081+{
10082+ int err;
392086de
AM
10083+ struct test_empty_arg arg = {
10084+ .ctx = {
2000de60 10085+ .actor = test_empty_cb
392086de
AM
10086+ }
10087+ };
1facf9fc 10088+ aufs_bindex_t bindex, btail;
10089+
10090+ err = 0;
1308ab2a 10091+ arg.whlist = whlist;
1facf9fc 10092+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
10093+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
10094+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 10095+ btail = au_dbtaildir(dentry);
10096+ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
10097+ struct dentry *h_dentry;
10098+
10099+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 10100+ if (h_dentry && d_is_positive(h_dentry)) {
1facf9fc 10101+ arg.bindex = bindex;
10102+ err = sio_test_empty(dentry, &arg);
10103+ }
10104+ }
10105+
10106+ return err;
10107+}
10108+
10109+/* ---------------------------------------------------------------------- */
10110+
10111+const struct file_operations aufs_dir_fop = {
4a4d8108 10112+ .owner = THIS_MODULE,
027c5e7a 10113+ .llseek = default_llseek,
1facf9fc 10114+ .read = generic_read_dir,
392086de 10115+ .iterate = aufs_iterate,
1facf9fc 10116+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
10117+#ifdef CONFIG_COMPAT
10118+ .compat_ioctl = aufs_compat_ioctl_dir,
10119+#endif
1facf9fc 10120+ .open = aufs_open_dir,
10121+ .release = aufs_release_dir,
4a4d8108 10122+ .flush = aufs_flush_dir,
1facf9fc 10123+ .fsync = aufs_fsync_dir
10124+};
7f207e10
AM
10125diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
10126--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 10127+++ linux/fs/aufs/dir.h 2015-09-24 10:47:58.251386326 +0200
b912730e 10128@@ -0,0 +1,131 @@
1facf9fc 10129+/*
2000de60 10130+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 10131+ *
10132+ * This program, aufs is free software; you can redistribute it and/or modify
10133+ * it under the terms of the GNU General Public License as published by
10134+ * the Free Software Foundation; either version 2 of the License, or
10135+ * (at your option) any later version.
dece6358
AM
10136+ *
10137+ * This program is distributed in the hope that it will be useful,
10138+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10139+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10140+ * GNU General Public License for more details.
10141+ *
10142+ * You should have received a copy of the GNU General Public License
523b37e3 10143+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10144+ */
10145+
10146+/*
10147+ * directory operations
10148+ */
10149+
10150+#ifndef __AUFS_DIR_H__
10151+#define __AUFS_DIR_H__
10152+
10153+#ifdef __KERNEL__
10154+
10155+#include <linux/fs.h>
1facf9fc 10156+
10157+/* ---------------------------------------------------------------------- */
10158+
10159+/* need to be faster and smaller */
10160+
10161+struct au_nhash {
dece6358
AM
10162+ unsigned int nh_num;
10163+ struct hlist_head *nh_head;
1facf9fc 10164+};
10165+
10166+struct au_vdir_destr {
10167+ unsigned char len;
10168+ unsigned char name[0];
10169+} __packed;
10170+
10171+struct au_vdir_dehstr {
10172+ struct hlist_node hash;
10173+ struct au_vdir_destr *str;
4a4d8108 10174+} ____cacheline_aligned_in_smp;
1facf9fc 10175+
10176+struct au_vdir_de {
10177+ ino_t de_ino;
10178+ unsigned char de_type;
10179+ /* caution: packed */
10180+ struct au_vdir_destr de_str;
10181+} __packed;
10182+
10183+struct au_vdir_wh {
10184+ struct hlist_node wh_hash;
dece6358
AM
10185+#ifdef CONFIG_AUFS_SHWH
10186+ ino_t wh_ino;
1facf9fc 10187+ aufs_bindex_t wh_bindex;
dece6358
AM
10188+ unsigned char wh_type;
10189+#else
10190+ aufs_bindex_t wh_bindex;
10191+#endif
10192+ /* caution: packed */
1facf9fc 10193+ struct au_vdir_destr wh_str;
10194+} __packed;
10195+
10196+union au_vdir_deblk_p {
10197+ unsigned char *deblk;
10198+ struct au_vdir_de *de;
10199+};
10200+
10201+struct au_vdir {
10202+ unsigned char **vd_deblk;
10203+ unsigned long vd_nblk;
1facf9fc 10204+ struct {
10205+ unsigned long ul;
10206+ union au_vdir_deblk_p p;
10207+ } vd_last;
10208+
10209+ unsigned long vd_version;
dece6358 10210+ unsigned int vd_deblk_sz;
1facf9fc 10211+ unsigned long vd_jiffy;
4a4d8108 10212+} ____cacheline_aligned_in_smp;
1facf9fc 10213+
10214+/* ---------------------------------------------------------------------- */
10215+
10216+/* dir.c */
10217+extern const struct file_operations aufs_dir_fop;
10218+void au_add_nlink(struct inode *dir, struct inode *h_dir);
10219+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 10220+loff_t au_dir_size(struct file *file, struct dentry *dentry);
b912730e 10221+void au_dir_ts(struct inode *dir, aufs_bindex_t bsrc);
1facf9fc 10222+int au_test_empty_lower(struct dentry *dentry);
10223+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
10224+
10225+/* vdir.c */
1308ab2a 10226+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
10227+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
10228+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 10229+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
10230+ int limit);
dece6358
AM
10231+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
10232+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
10233+ unsigned int d_type, aufs_bindex_t bindex,
10234+ unsigned char shwh);
1facf9fc 10235+void au_vdir_free(struct au_vdir *vdir);
10236+int au_vdir_init(struct file *file);
392086de 10237+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 10238+
10239+/* ioctl.c */
10240+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
10241+
1308ab2a 10242+#ifdef CONFIG_AUFS_RDU
10243+/* rdu.c */
10244+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
10245+#ifdef CONFIG_COMPAT
10246+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
10247+ unsigned long arg);
10248+#endif
1308ab2a 10249+#else
c1595e42
JR
10250+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file,
10251+ unsigned int cmd, unsigned long arg)
b752ccd1 10252+#ifdef CONFIG_COMPAT
c1595e42
JR
10253+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file,
10254+ unsigned int cmd, unsigned long arg)
b752ccd1 10255+#endif
1308ab2a 10256+#endif
10257+
1facf9fc 10258+#endif /* __KERNEL__ */
10259+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
10260diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
10261--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 10262+++ linux/fs/aufs/dynop.c 2015-09-24 10:47:58.251386326 +0200
7e9cd9fe 10263@@ -0,0 +1,369 @@
1facf9fc 10264+/*
2000de60 10265+ * Copyright (C) 2010-2015 Junjiro R. Okajima
1facf9fc 10266+ *
10267+ * This program, aufs is free software; you can redistribute it and/or modify
10268+ * it under the terms of the GNU General Public License as published by
10269+ * the Free Software Foundation; either version 2 of the License, or
10270+ * (at your option) any later version.
dece6358
AM
10271+ *
10272+ * This program is distributed in the hope that it will be useful,
10273+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10274+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10275+ * GNU General Public License for more details.
10276+ *
10277+ * You should have received a copy of the GNU General Public License
523b37e3 10278+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10279+ */
10280+
10281+/*
4a4d8108 10282+ * dynamically customizable operations for regular files
1facf9fc 10283+ */
10284+
1facf9fc 10285+#include "aufs.h"
10286+
4a4d8108 10287+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 10288+
4a4d8108
AM
10289+/*
10290+ * How large will these lists be?
10291+ * Usually just a few elements, 20-30 at most for each, I guess.
10292+ */
10293+static struct au_splhead dynop[AuDyLast];
10294+
10295+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
1facf9fc 10296+{
4a4d8108
AM
10297+ struct au_dykey *key, *tmp;
10298+ struct list_head *head;
1facf9fc 10299+
4a4d8108
AM
10300+ key = NULL;
10301+ head = &spl->head;
10302+ rcu_read_lock();
10303+ list_for_each_entry_rcu(tmp, head, dk_list)
10304+ if (tmp->dk_op.dy_hop == h_op) {
10305+ key = tmp;
10306+ kref_get(&key->dk_kref);
10307+ break;
10308+ }
10309+ rcu_read_unlock();
10310+
10311+ return key;
1facf9fc 10312+}
10313+
4a4d8108 10314+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 10315+{
4a4d8108
AM
10316+ struct au_dykey **k, *found;
10317+ const void *h_op = key->dk_op.dy_hop;
10318+ int i;
1facf9fc 10319+
4a4d8108
AM
10320+ found = NULL;
10321+ k = br->br_dykey;
10322+ for (i = 0; i < AuBrDynOp; i++)
10323+ if (k[i]) {
10324+ if (k[i]->dk_op.dy_hop == h_op) {
10325+ found = k[i];
10326+ break;
10327+ }
10328+ } else
10329+ break;
10330+ if (!found) {
10331+ spin_lock(&br->br_dykey_lock);
10332+ for (; i < AuBrDynOp; i++)
10333+ if (k[i]) {
10334+ if (k[i]->dk_op.dy_hop == h_op) {
10335+ found = k[i];
10336+ break;
10337+ }
10338+ } else {
10339+ k[i] = key;
10340+ break;
10341+ }
10342+ spin_unlock(&br->br_dykey_lock);
10343+ BUG_ON(i == AuBrDynOp); /* expand the array */
10344+ }
10345+
10346+ return found;
1facf9fc 10347+}
10348+
4a4d8108
AM
10349+/* kref_get() if @key is already added */
10350+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
10351+{
10352+ struct au_dykey *tmp, *found;
10353+ struct list_head *head;
10354+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 10355+
4a4d8108
AM
10356+ found = NULL;
10357+ head = &spl->head;
10358+ spin_lock(&spl->spin);
10359+ list_for_each_entry(tmp, head, dk_list)
10360+ if (tmp->dk_op.dy_hop == h_op) {
10361+ kref_get(&tmp->dk_kref);
10362+ found = tmp;
10363+ break;
10364+ }
10365+ if (!found)
10366+ list_add_rcu(&key->dk_list, head);
10367+ spin_unlock(&spl->spin);
1facf9fc 10368+
4a4d8108
AM
10369+ if (!found)
10370+ DyPrSym(key);
10371+ return found;
10372+}
10373+
10374+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 10375+{
4a4d8108
AM
10376+ struct au_dykey *key;
10377+
10378+ key = container_of(rcu, struct au_dykey, dk_rcu);
10379+ DyPrSym(key);
10380+ kfree(key);
1facf9fc 10381+}
10382+
4a4d8108
AM
10383+static void dy_free(struct kref *kref)
10384+{
10385+ struct au_dykey *key;
10386+ struct au_splhead *spl;
1facf9fc 10387+
4a4d8108
AM
10388+ key = container_of(kref, struct au_dykey, dk_kref);
10389+ spl = dynop + key->dk_op.dy_type;
10390+ au_spl_del_rcu(&key->dk_list, spl);
10391+ call_rcu(&key->dk_rcu, dy_free_rcu);
10392+}
10393+
10394+void au_dy_put(struct au_dykey *key)
1facf9fc 10395+{
4a4d8108
AM
10396+ kref_put(&key->dk_kref, dy_free);
10397+}
1facf9fc 10398+
4a4d8108
AM
10399+/* ---------------------------------------------------------------------- */
10400+
10401+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
10402+
10403+#ifdef CONFIG_AUFS_DEBUG
10404+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 10405+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
10406+#else
10407+#define DyDbgDeclare(cnt) do {} while (0)
10408+#define DyDbgInc(cnt) do {} while (0)
10409+#endif
10410+
10411+#define DySet(func, dst, src, h_op, h_sb) do { \
10412+ DyDbgInc(cnt); \
10413+ if (h_op->func) { \
10414+ if (src.func) \
10415+ dst.func = src.func; \
10416+ else \
10417+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
10418+ } \
10419+} while (0)
10420+
10421+#define DySetForce(func, dst, src) do { \
10422+ AuDebugOn(!src.func); \
10423+ DyDbgInc(cnt); \
10424+ dst.func = src.func; \
10425+} while (0)
10426+
10427+#define DySetAop(func) \
10428+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
10429+#define DySetAopForce(func) \
10430+ DySetForce(func, dyaop->da_op, aufs_aop)
10431+
10432+static void dy_aop(struct au_dykey *key, const void *h_op,
10433+ struct super_block *h_sb __maybe_unused)
10434+{
10435+ struct au_dyaop *dyaop = (void *)key;
10436+ const struct address_space_operations *h_aop = h_op;
10437+ DyDbgDeclare(cnt);
10438+
10439+ AuDbg("%s\n", au_sbtype(h_sb));
10440+
10441+ DySetAop(writepage);
10442+ DySetAopForce(readpage); /* force */
4a4d8108
AM
10443+ DySetAop(writepages);
10444+ DySetAop(set_page_dirty);
10445+ DySetAop(readpages);
10446+ DySetAop(write_begin);
10447+ DySetAop(write_end);
10448+ DySetAop(bmap);
10449+ DySetAop(invalidatepage);
10450+ DySetAop(releasepage);
027c5e7a 10451+ DySetAop(freepage);
7e9cd9fe 10452+ /* this one will be changed according to an aufs mount option */
4a4d8108 10453+ DySetAop(direct_IO);
4a4d8108
AM
10454+ DySetAop(migratepage);
10455+ DySetAop(launder_page);
10456+ DySetAop(is_partially_uptodate);
392086de 10457+ DySetAop(is_dirty_writeback);
4a4d8108 10458+ DySetAop(error_remove_page);
b4510431
AM
10459+ DySetAop(swap_activate);
10460+ DySetAop(swap_deactivate);
4a4d8108
AM
10461+
10462+ DyDbgSize(cnt, *h_aop);
4a4d8108
AM
10463+}
10464+
4a4d8108
AM
10465+/* ---------------------------------------------------------------------- */
10466+
10467+static void dy_bug(struct kref *kref)
10468+{
10469+ BUG();
10470+}
10471+
10472+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
10473+{
10474+ struct au_dykey *key, *old;
10475+ struct au_splhead *spl;
b752ccd1 10476+ struct op {
4a4d8108 10477+ unsigned int sz;
b752ccd1
AM
10478+ void (*set)(struct au_dykey *key, const void *h_op,
10479+ struct super_block *h_sb __maybe_unused);
10480+ };
10481+ static const struct op a[] = {
4a4d8108
AM
10482+ [AuDy_AOP] = {
10483+ .sz = sizeof(struct au_dyaop),
b752ccd1 10484+ .set = dy_aop
4a4d8108 10485+ }
b752ccd1
AM
10486+ };
10487+ const struct op *p;
4a4d8108
AM
10488+
10489+ spl = dynop + op->dy_type;
10490+ key = dy_gfind_get(spl, op->dy_hop);
10491+ if (key)
10492+ goto out_add; /* success */
10493+
10494+ p = a + op->dy_type;
10495+ key = kzalloc(p->sz, GFP_NOFS);
10496+ if (unlikely(!key)) {
10497+ key = ERR_PTR(-ENOMEM);
10498+ goto out;
10499+ }
10500+
10501+ key->dk_op.dy_hop = op->dy_hop;
10502+ kref_init(&key->dk_kref);
86dc4139 10503+ p->set(key, op->dy_hop, au_br_sb(br));
4a4d8108
AM
10504+ old = dy_gadd(spl, key);
10505+ if (old) {
10506+ kfree(key);
10507+ key = old;
10508+ }
10509+
10510+out_add:
10511+ old = dy_bradd(br, key);
10512+ if (old)
10513+ /* its ref-count should never be zero here */
10514+ kref_put(&key->dk_kref, dy_bug);
10515+out:
10516+ return key;
10517+}
10518+
10519+/* ---------------------------------------------------------------------- */
10520+/*
10521+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
c1595e42 10522+ * This behaviour is necessary to return an error from open(O_DIRECT) instead
4a4d8108
AM
10523+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
10524+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
10525+ * See the aufs manual in detail.
4a4d8108
AM
10526+ */
10527+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
10528+{
7e9cd9fe 10529+ if (!do_dx)
4a4d8108 10530+ dyaop->da_op.direct_IO = NULL;
7e9cd9fe 10531+ else
4a4d8108 10532+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
4a4d8108
AM
10533+}
10534+
10535+static struct au_dyaop *dy_aget(struct au_branch *br,
10536+ const struct address_space_operations *h_aop,
10537+ int do_dx)
10538+{
10539+ struct au_dyaop *dyaop;
10540+ struct au_dynop op;
10541+
10542+ op.dy_type = AuDy_AOP;
10543+ op.dy_haop = h_aop;
10544+ dyaop = (void *)dy_get(&op, br);
10545+ if (IS_ERR(dyaop))
10546+ goto out;
10547+ dy_adx(dyaop, do_dx);
10548+
10549+out:
10550+ return dyaop;
10551+}
10552+
10553+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10554+ struct inode *h_inode)
10555+{
10556+ int err, do_dx;
10557+ struct super_block *sb;
10558+ struct au_branch *br;
10559+ struct au_dyaop *dyaop;
10560+
10561+ AuDebugOn(!S_ISREG(h_inode->i_mode));
10562+ IiMustWriteLock(inode);
10563+
10564+ sb = inode->i_sb;
10565+ br = au_sbr(sb, bindex);
10566+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
10567+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
10568+ err = PTR_ERR(dyaop);
10569+ if (IS_ERR(dyaop))
10570+ /* unnecessary to call dy_fput() */
10571+ goto out;
10572+
10573+ err = 0;
10574+ inode->i_mapping->a_ops = &dyaop->da_op;
10575+
10576+out:
10577+ return err;
10578+}
10579+
b752ccd1
AM
10580+/*
10581+ * Is it safe to replace a_ops during the inode/file is in operation?
10582+ * Yes, I hope so.
10583+ */
10584+int au_dy_irefresh(struct inode *inode)
10585+{
10586+ int err;
10587+ aufs_bindex_t bstart;
10588+ struct inode *h_inode;
10589+
10590+ err = 0;
10591+ if (S_ISREG(inode->i_mode)) {
10592+ bstart = au_ibstart(inode);
10593+ h_inode = au_h_iptr(inode, bstart);
10594+ err = au_dy_iaop(inode, bstart, h_inode);
10595+ }
10596+ return err;
10597+}
10598+
4a4d8108
AM
10599+void au_dy_arefresh(int do_dx)
10600+{
10601+ struct au_splhead *spl;
10602+ struct list_head *head;
10603+ struct au_dykey *key;
10604+
10605+ spl = dynop + AuDy_AOP;
10606+ head = &spl->head;
10607+ spin_lock(&spl->spin);
10608+ list_for_each_entry(key, head, dk_list)
10609+ dy_adx((void *)key, do_dx);
10610+ spin_unlock(&spl->spin);
10611+}
10612+
4a4d8108
AM
10613+/* ---------------------------------------------------------------------- */
10614+
10615+void __init au_dy_init(void)
10616+{
10617+ int i;
10618+
10619+ /* make sure that 'struct au_dykey *' can be any type */
10620+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
10621+
10622+ for (i = 0; i < AuDyLast; i++)
10623+ au_spl_init(dynop + i);
10624+}
10625+
10626+void au_dy_fin(void)
10627+{
10628+ int i;
10629+
10630+ for (i = 0; i < AuDyLast; i++)
10631+ WARN_ON(!list_empty(&dynop[i].head));
10632+}
7f207e10
AM
10633diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
10634--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 10635+++ linux/fs/aufs/dynop.h 2015-09-24 10:47:58.251386326 +0200
7e9cd9fe 10636@@ -0,0 +1,74 @@
4a4d8108 10637+/*
2000de60 10638+ * Copyright (C) 2010-2015 Junjiro R. Okajima
4a4d8108
AM
10639+ *
10640+ * This program, aufs is free software; you can redistribute it and/or modify
10641+ * it under the terms of the GNU General Public License as published by
10642+ * the Free Software Foundation; either version 2 of the License, or
10643+ * (at your option) any later version.
10644+ *
10645+ * This program is distributed in the hope that it will be useful,
10646+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10647+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10648+ * GNU General Public License for more details.
10649+ *
10650+ * You should have received a copy of the GNU General Public License
523b37e3 10651+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10652+ */
10653+
10654+/*
10655+ * dynamically customizable operations (for regular files only)
10656+ */
10657+
10658+#ifndef __AUFS_DYNOP_H__
10659+#define __AUFS_DYNOP_H__
10660+
10661+#ifdef __KERNEL__
10662+
7e9cd9fe
AM
10663+#include <linux/fs.h>
10664+#include <linux/kref.h>
4a4d8108 10665+
2cbb1c4b 10666+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
10667+
10668+struct au_dynop {
10669+ int dy_type;
10670+ union {
10671+ const void *dy_hop;
10672+ const struct address_space_operations *dy_haop;
4a4d8108
AM
10673+ };
10674+};
10675+
10676+struct au_dykey {
10677+ union {
10678+ struct list_head dk_list;
10679+ struct rcu_head dk_rcu;
10680+ };
10681+ struct au_dynop dk_op;
10682+
10683+ /*
10684+ * during I am in the branch local array, kref is gotten. when the
10685+ * branch is removed, kref is put.
10686+ */
10687+ struct kref dk_kref;
10688+};
10689+
10690+/* stop unioning since their sizes are very different from each other */
10691+struct au_dyaop {
10692+ struct au_dykey da_key;
10693+ struct address_space_operations da_op; /* not const */
4a4d8108
AM
10694+};
10695+
4a4d8108
AM
10696+/* ---------------------------------------------------------------------- */
10697+
10698+/* dynop.c */
10699+struct au_branch;
10700+void au_dy_put(struct au_dykey *key);
10701+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10702+ struct inode *h_inode);
b752ccd1 10703+int au_dy_irefresh(struct inode *inode);
4a4d8108 10704+void au_dy_arefresh(int do_dio);
4a4d8108
AM
10705+
10706+void __init au_dy_init(void);
10707+void au_dy_fin(void);
10708+
4a4d8108
AM
10709+#endif /* __KERNEL__ */
10710+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
10711diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
10712--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 10713+++ linux/fs/aufs/export.c 2015-09-24 10:47:58.251386326 +0200
5527c038 10714@@ -0,0 +1,832 @@
4a4d8108 10715+/*
2000de60 10716+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
10717+ *
10718+ * This program, aufs is free software; you can redistribute it and/or modify
10719+ * it under the terms of the GNU General Public License as published by
10720+ * the Free Software Foundation; either version 2 of the License, or
10721+ * (at your option) any later version.
10722+ *
10723+ * This program is distributed in the hope that it will be useful,
10724+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10725+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10726+ * GNU General Public License for more details.
10727+ *
10728+ * You should have received a copy of the GNU General Public License
523b37e3 10729+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10730+ */
10731+
10732+/*
10733+ * export via nfs
10734+ */
10735+
10736+#include <linux/exportfs.h>
7eafdf33 10737+#include <linux/fs_struct.h>
4a4d8108
AM
10738+#include <linux/namei.h>
10739+#include <linux/nsproxy.h>
10740+#include <linux/random.h>
10741+#include <linux/writeback.h>
7eafdf33 10742+#include "../fs/mount.h"
4a4d8108
AM
10743+#include "aufs.h"
10744+
10745+union conv {
10746+#ifdef CONFIG_AUFS_INO_T_64
10747+ __u32 a[2];
10748+#else
10749+ __u32 a[1];
10750+#endif
10751+ ino_t ino;
10752+};
10753+
10754+static ino_t decode_ino(__u32 *a)
10755+{
10756+ union conv u;
10757+
10758+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
10759+ u.a[0] = a[0];
10760+#ifdef CONFIG_AUFS_INO_T_64
10761+ u.a[1] = a[1];
10762+#endif
10763+ return u.ino;
10764+}
10765+
10766+static void encode_ino(__u32 *a, ino_t ino)
10767+{
10768+ union conv u;
10769+
10770+ u.ino = ino;
10771+ a[0] = u.a[0];
10772+#ifdef CONFIG_AUFS_INO_T_64
10773+ a[1] = u.a[1];
10774+#endif
10775+}
10776+
10777+/* NFS file handle */
10778+enum {
10779+ Fh_br_id,
10780+ Fh_sigen,
10781+#ifdef CONFIG_AUFS_INO_T_64
10782+ /* support 64bit inode number */
10783+ Fh_ino1,
10784+ Fh_ino2,
10785+ Fh_dir_ino1,
10786+ Fh_dir_ino2,
10787+#else
10788+ Fh_ino1,
10789+ Fh_dir_ino1,
10790+#endif
10791+ Fh_igen,
10792+ Fh_h_type,
10793+ Fh_tail,
10794+
10795+ Fh_ino = Fh_ino1,
10796+ Fh_dir_ino = Fh_dir_ino1
10797+};
10798+
10799+static int au_test_anon(struct dentry *dentry)
10800+{
027c5e7a 10801+ /* note: read d_flags without d_lock */
4a4d8108
AM
10802+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
10803+}
10804+
a2a7ad62
AM
10805+int au_test_nfsd(void)
10806+{
10807+ int ret;
10808+ struct task_struct *tsk = current;
10809+ char comm[sizeof(tsk->comm)];
10810+
10811+ ret = 0;
10812+ if (tsk->flags & PF_KTHREAD) {
10813+ get_task_comm(comm, tsk);
10814+ ret = !strcmp(comm, "nfsd");
10815+ }
10816+
10817+ return ret;
10818+}
10819+
4a4d8108
AM
10820+/* ---------------------------------------------------------------------- */
10821+/* inode generation external table */
10822+
b752ccd1 10823+void au_xigen_inc(struct inode *inode)
4a4d8108 10824+{
4a4d8108
AM
10825+ loff_t pos;
10826+ ssize_t sz;
10827+ __u32 igen;
10828+ struct super_block *sb;
10829+ struct au_sbinfo *sbinfo;
10830+
4a4d8108 10831+ sb = inode->i_sb;
b752ccd1 10832+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 10833+
b752ccd1 10834+ sbinfo = au_sbi(sb);
1facf9fc 10835+ pos = inode->i_ino;
10836+ pos *= sizeof(igen);
10837+ igen = inode->i_generation + 1;
1facf9fc 10838+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
10839+ sizeof(igen), &pos);
10840+ if (sz == sizeof(igen))
b752ccd1 10841+ return; /* success */
1facf9fc 10842+
b752ccd1 10843+ if (unlikely(sz >= 0))
1facf9fc 10844+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 10845+}
10846+
10847+int au_xigen_new(struct inode *inode)
10848+{
10849+ int err;
10850+ loff_t pos;
10851+ ssize_t sz;
10852+ struct super_block *sb;
10853+ struct au_sbinfo *sbinfo;
10854+ struct file *file;
10855+
10856+ err = 0;
10857+ /* todo: dirty, at mount time */
10858+ if (inode->i_ino == AUFS_ROOT_INO)
10859+ goto out;
10860+ sb = inode->i_sb;
dece6358 10861+ SiMustAnyLock(sb);
1facf9fc 10862+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10863+ goto out;
10864+
10865+ err = -EFBIG;
10866+ pos = inode->i_ino;
10867+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
10868+ AuIOErr1("too large i%lld\n", pos);
10869+ goto out;
10870+ }
10871+ pos *= sizeof(inode->i_generation);
10872+
10873+ err = 0;
10874+ sbinfo = au_sbi(sb);
10875+ file = sbinfo->si_xigen;
10876+ BUG_ON(!file);
10877+
c06a8ce3 10878+ if (vfsub_f_size_read(file)
1facf9fc 10879+ < pos + sizeof(inode->i_generation)) {
10880+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
10881+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
10882+ sizeof(inode->i_generation), &pos);
10883+ } else
10884+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
10885+ sizeof(inode->i_generation), &pos);
10886+ if (sz == sizeof(inode->i_generation))
10887+ goto out; /* success */
10888+
10889+ err = sz;
10890+ if (unlikely(sz >= 0)) {
10891+ err = -EIO;
10892+ AuIOErr("xigen error (%zd)\n", sz);
10893+ }
10894+
4f0767ce 10895+out:
1facf9fc 10896+ return err;
10897+}
10898+
10899+int au_xigen_set(struct super_block *sb, struct file *base)
10900+{
10901+ int err;
10902+ struct au_sbinfo *sbinfo;
10903+ struct file *file;
10904+
dece6358
AM
10905+ SiMustWriteLock(sb);
10906+
1facf9fc 10907+ sbinfo = au_sbi(sb);
10908+ file = au_xino_create2(base, sbinfo->si_xigen);
10909+ err = PTR_ERR(file);
10910+ if (IS_ERR(file))
10911+ goto out;
10912+ err = 0;
10913+ if (sbinfo->si_xigen)
10914+ fput(sbinfo->si_xigen);
10915+ sbinfo->si_xigen = file;
10916+
4f0767ce 10917+out:
1facf9fc 10918+ return err;
10919+}
10920+
10921+void au_xigen_clr(struct super_block *sb)
10922+{
10923+ struct au_sbinfo *sbinfo;
10924+
dece6358
AM
10925+ SiMustWriteLock(sb);
10926+
1facf9fc 10927+ sbinfo = au_sbi(sb);
10928+ if (sbinfo->si_xigen) {
10929+ fput(sbinfo->si_xigen);
10930+ sbinfo->si_xigen = NULL;
10931+ }
10932+}
10933+
10934+/* ---------------------------------------------------------------------- */
10935+
10936+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
10937+ ino_t dir_ino)
10938+{
10939+ struct dentry *dentry, *d;
10940+ struct inode *inode;
10941+ unsigned int sigen;
10942+
10943+ dentry = NULL;
10944+ inode = ilookup(sb, ino);
10945+ if (!inode)
10946+ goto out;
10947+
10948+ dentry = ERR_PTR(-ESTALE);
10949+ sigen = au_sigen(sb);
10950+ if (unlikely(is_bad_inode(inode)
10951+ || IS_DEADDIR(inode)
537831f9 10952+ || sigen != au_iigen(inode, NULL)))
1facf9fc 10953+ goto out_iput;
10954+
10955+ dentry = NULL;
10956+ if (!dir_ino || S_ISDIR(inode->i_mode))
10957+ dentry = d_find_alias(inode);
10958+ else {
027c5e7a 10959+ spin_lock(&inode->i_lock);
c1595e42 10960+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 10961+ spin_lock(&d->d_lock);
1facf9fc 10962+ if (!au_test_anon(d)
5527c038 10963+ && d_inode(d->d_parent)->i_ino == dir_ino) {
027c5e7a
AM
10964+ dentry = dget_dlock(d);
10965+ spin_unlock(&d->d_lock);
1facf9fc 10966+ break;
10967+ }
027c5e7a
AM
10968+ spin_unlock(&d->d_lock);
10969+ }
10970+ spin_unlock(&inode->i_lock);
1facf9fc 10971+ }
027c5e7a 10972+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 10973+ /* need to refresh */
1facf9fc 10974+ dput(dentry);
2cbb1c4b 10975+ dentry = NULL;
1facf9fc 10976+ }
10977+
4f0767ce 10978+out_iput:
1facf9fc 10979+ iput(inode);
4f0767ce 10980+out:
2cbb1c4b 10981+ AuTraceErrPtr(dentry);
1facf9fc 10982+ return dentry;
10983+}
10984+
10985+/* ---------------------------------------------------------------------- */
10986+
10987+/* todo: dirty? */
10988+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
10989+
10990+struct au_compare_mnt_args {
10991+ /* input */
10992+ struct super_block *sb;
10993+
10994+ /* output */
10995+ struct vfsmount *mnt;
10996+};
10997+
10998+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
10999+{
11000+ struct au_compare_mnt_args *a = arg;
11001+
11002+ if (mnt->mnt_sb != a->sb)
11003+ return 0;
11004+ a->mnt = mntget(mnt);
11005+ return 1;
11006+}
11007+
1facf9fc 11008+static struct vfsmount *au_mnt_get(struct super_block *sb)
11009+{
4a4d8108 11010+ int err;
7eafdf33 11011+ struct path root;
4a4d8108
AM
11012+ struct au_compare_mnt_args args = {
11013+ .sb = sb
11014+ };
1facf9fc 11015+
7eafdf33 11016+ get_fs_root(current->fs, &root);
523b37e3 11017+ rcu_read_lock();
7eafdf33 11018+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 11019+ rcu_read_unlock();
7eafdf33 11020+ path_put(&root);
4a4d8108
AM
11021+ AuDebugOn(!err);
11022+ AuDebugOn(!args.mnt);
11023+ return args.mnt;
1facf9fc 11024+}
11025+
11026+struct au_nfsd_si_lock {
4a4d8108 11027+ unsigned int sigen;
027c5e7a 11028+ aufs_bindex_t bindex, br_id;
1facf9fc 11029+ unsigned char force_lock;
11030+};
11031+
027c5e7a
AM
11032+static int si_nfsd_read_lock(struct super_block *sb,
11033+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 11034+{
027c5e7a 11035+ int err;
1facf9fc 11036+ aufs_bindex_t bindex;
11037+
11038+ si_read_lock(sb, AuLock_FLUSH);
11039+
11040+ /* branch id may be wrapped around */
027c5e7a 11041+ err = 0;
1facf9fc 11042+ bindex = au_br_index(sb, nsi_lock->br_id);
11043+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
11044+ goto out; /* success */
11045+
027c5e7a
AM
11046+ err = -ESTALE;
11047+ bindex = -1;
1facf9fc 11048+ if (!nsi_lock->force_lock)
11049+ si_read_unlock(sb);
1facf9fc 11050+
4f0767ce 11051+out:
027c5e7a
AM
11052+ nsi_lock->bindex = bindex;
11053+ return err;
1facf9fc 11054+}
11055+
11056+struct find_name_by_ino {
392086de 11057+ struct dir_context ctx;
1facf9fc 11058+ int called, found;
11059+ ino_t ino;
11060+ char *name;
11061+ int namelen;
11062+};
11063+
11064+static int
392086de
AM
11065+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
11066+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 11067+{
392086de
AM
11068+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
11069+ ctx);
1facf9fc 11070+
11071+ a->called++;
11072+ if (a->ino != ino)
11073+ return 0;
11074+
11075+ memcpy(a->name, name, namelen);
11076+ a->namelen = namelen;
11077+ a->found = 1;
11078+ return 1;
11079+}
11080+
11081+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
11082+ struct au_nfsd_si_lock *nsi_lock)
11083+{
11084+ struct dentry *dentry, *parent;
11085+ struct file *file;
11086+ struct inode *dir;
392086de
AM
11087+ struct find_name_by_ino arg = {
11088+ .ctx = {
2000de60 11089+ .actor = find_name_by_ino
392086de
AM
11090+ }
11091+ };
1facf9fc 11092+ int err;
11093+
11094+ parent = path->dentry;
11095+ if (nsi_lock)
11096+ si_read_unlock(parent->d_sb);
4a4d8108 11097+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 11098+ dentry = (void *)file;
11099+ if (IS_ERR(file))
11100+ goto out;
11101+
11102+ dentry = ERR_PTR(-ENOMEM);
537831f9 11103+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 11104+ if (unlikely(!arg.name))
11105+ goto out_file;
11106+ arg.ino = ino;
11107+ arg.found = 0;
11108+ do {
11109+ arg.called = 0;
11110+ /* smp_mb(); */
392086de 11111+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 11112+ } while (!err && !arg.found && arg.called);
11113+ dentry = ERR_PTR(err);
11114+ if (unlikely(err))
11115+ goto out_name;
1716fcea
AM
11116+ /* instead of ENOENT */
11117+ dentry = ERR_PTR(-ESTALE);
1facf9fc 11118+ if (!arg.found)
11119+ goto out_name;
11120+
b4510431 11121+ /* do not call vfsub_lkup_one() */
5527c038 11122+ dir = d_inode(parent);
1facf9fc 11123+ mutex_lock(&dir->i_mutex);
11124+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
11125+ mutex_unlock(&dir->i_mutex);
11126+ AuTraceErrPtr(dentry);
11127+ if (IS_ERR(dentry))
11128+ goto out_name;
11129+ AuDebugOn(au_test_anon(dentry));
5527c038 11130+ if (unlikely(d_really_is_negative(dentry))) {
1facf9fc 11131+ dput(dentry);
11132+ dentry = ERR_PTR(-ENOENT);
11133+ }
11134+
4f0767ce 11135+out_name:
537831f9 11136+ free_page((unsigned long)arg.name);
4f0767ce 11137+out_file:
1facf9fc 11138+ fput(file);
4f0767ce 11139+out:
1facf9fc 11140+ if (unlikely(nsi_lock
11141+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
11142+ if (!IS_ERR(dentry)) {
11143+ dput(dentry);
11144+ dentry = ERR_PTR(-ESTALE);
11145+ }
11146+ AuTraceErrPtr(dentry);
11147+ return dentry;
11148+}
11149+
11150+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
11151+ ino_t dir_ino,
11152+ struct au_nfsd_si_lock *nsi_lock)
11153+{
11154+ struct dentry *dentry;
11155+ struct path path;
11156+
11157+ if (dir_ino != AUFS_ROOT_INO) {
11158+ path.dentry = decode_by_ino(sb, dir_ino, 0);
11159+ dentry = path.dentry;
11160+ if (!path.dentry || IS_ERR(path.dentry))
11161+ goto out;
11162+ AuDebugOn(au_test_anon(path.dentry));
11163+ } else
11164+ path.dentry = dget(sb->s_root);
11165+
11166+ path.mnt = au_mnt_get(sb);
11167+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
11168+ path_put(&path);
11169+
4f0767ce 11170+out:
1facf9fc 11171+ AuTraceErrPtr(dentry);
11172+ return dentry;
11173+}
11174+
11175+/* ---------------------------------------------------------------------- */
11176+
11177+static int h_acceptable(void *expv, struct dentry *dentry)
11178+{
11179+ return 1;
11180+}
11181+
11182+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
11183+ char *buf, int len, struct super_block *sb)
11184+{
11185+ char *p;
11186+ int n;
11187+ struct path path;
11188+
11189+ p = d_path(h_rootpath, buf, len);
11190+ if (IS_ERR(p))
11191+ goto out;
11192+ n = strlen(p);
11193+
11194+ path.mnt = h_rootpath->mnt;
11195+ path.dentry = h_parent;
11196+ p = d_path(&path, buf, len);
11197+ if (IS_ERR(p))
11198+ goto out;
11199+ if (n != 1)
11200+ p += n;
11201+
11202+ path.mnt = au_mnt_get(sb);
11203+ path.dentry = sb->s_root;
11204+ p = d_path(&path, buf, len - strlen(p));
11205+ mntput(path.mnt);
11206+ if (IS_ERR(p))
11207+ goto out;
11208+ if (n != 1)
11209+ p[strlen(p)] = '/';
11210+
4f0767ce 11211+out:
1facf9fc 11212+ AuTraceErrPtr(p);
11213+ return p;
11214+}
11215+
11216+static
027c5e7a
AM
11217+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
11218+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 11219+{
11220+ struct dentry *dentry, *h_parent, *root;
11221+ struct super_block *h_sb;
11222+ char *pathname, *p;
11223+ struct vfsmount *h_mnt;
11224+ struct au_branch *br;
11225+ int err;
11226+ struct path path;
11227+
027c5e7a 11228+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 11229+ h_mnt = au_br_mnt(br);
1facf9fc 11230+ h_sb = h_mnt->mnt_sb;
11231+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
11232+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
11233+ fh_len - Fh_tail, fh[Fh_h_type],
11234+ h_acceptable, /*context*/NULL);
11235+ dentry = h_parent;
11236+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
11237+ AuWarn1("%s decode_fh failed, %ld\n",
11238+ au_sbtype(h_sb), PTR_ERR(h_parent));
11239+ goto out;
11240+ }
11241+ dentry = NULL;
11242+ if (unlikely(au_test_anon(h_parent))) {
11243+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
11244+ au_sbtype(h_sb));
11245+ goto out_h_parent;
11246+ }
11247+
11248+ dentry = ERR_PTR(-ENOMEM);
11249+ pathname = (void *)__get_free_page(GFP_NOFS);
11250+ if (unlikely(!pathname))
11251+ goto out_h_parent;
11252+
11253+ root = sb->s_root;
11254+ path.mnt = h_mnt;
11255+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 11256+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 11257+ di_read_unlock(root, !AuLock_IR);
11258+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
11259+ dentry = (void *)p;
11260+ if (IS_ERR(p))
11261+ goto out_pathname;
11262+
11263+ si_read_unlock(sb);
11264+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
11265+ dentry = ERR_PTR(err);
11266+ if (unlikely(err))
11267+ goto out_relock;
11268+
11269+ dentry = ERR_PTR(-ENOENT);
11270+ AuDebugOn(au_test_anon(path.dentry));
5527c038 11271+ if (unlikely(d_really_is_negative(path.dentry)))
1facf9fc 11272+ goto out_path;
11273+
5527c038 11274+ if (ino != d_inode(path.dentry)->i_ino)
1facf9fc 11275+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
11276+ else
11277+ dentry = dget(path.dentry);
11278+
4f0767ce 11279+out_path:
1facf9fc 11280+ path_put(&path);
4f0767ce 11281+out_relock:
1facf9fc 11282+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
11283+ if (!IS_ERR(dentry)) {
11284+ dput(dentry);
11285+ dentry = ERR_PTR(-ESTALE);
11286+ }
4f0767ce 11287+out_pathname:
1facf9fc 11288+ free_page((unsigned long)pathname);
4f0767ce 11289+out_h_parent:
1facf9fc 11290+ dput(h_parent);
4f0767ce 11291+out:
1facf9fc 11292+ AuTraceErrPtr(dentry);
11293+ return dentry;
11294+}
11295+
11296+/* ---------------------------------------------------------------------- */
11297+
11298+static struct dentry *
11299+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
11300+ int fh_type)
11301+{
11302+ struct dentry *dentry;
11303+ __u32 *fh = fid->raw;
027c5e7a 11304+ struct au_branch *br;
1facf9fc 11305+ ino_t ino, dir_ino;
1facf9fc 11306+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 11307+ .force_lock = 0
11308+ };
11309+
1facf9fc 11310+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
11311+ /* it should never happen, but the file handle is unreliable */
11312+ if (unlikely(fh_len < Fh_tail))
11313+ goto out;
11314+ nsi_lock.sigen = fh[Fh_sigen];
11315+ nsi_lock.br_id = fh[Fh_br_id];
11316+
1facf9fc 11317+ /* branch id may be wrapped around */
027c5e7a
AM
11318+ br = NULL;
11319+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 11320+ goto out;
11321+ nsi_lock.force_lock = 1;
11322+
11323+ /* is this inode still cached? */
11324+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
11325+ /* it should never happen */
11326+ if (unlikely(ino == AUFS_ROOT_INO))
11327+ goto out;
11328+
1facf9fc 11329+ dir_ino = decode_ino(fh + Fh_dir_ino);
11330+ dentry = decode_by_ino(sb, ino, dir_ino);
11331+ if (IS_ERR(dentry))
11332+ goto out_unlock;
11333+ if (dentry)
11334+ goto accept;
11335+
11336+ /* is the parent dir cached? */
027c5e7a
AM
11337+ br = au_sbr(sb, nsi_lock.bindex);
11338+ atomic_inc(&br->br_count);
1facf9fc 11339+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
11340+ if (IS_ERR(dentry))
11341+ goto out_unlock;
11342+ if (dentry)
11343+ goto accept;
11344+
11345+ /* lookup path */
027c5e7a 11346+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 11347+ if (IS_ERR(dentry))
11348+ goto out_unlock;
11349+ if (unlikely(!dentry))
11350+ /* todo?: make it ESTALE */
11351+ goto out_unlock;
11352+
4f0767ce 11353+accept:
027c5e7a 11354+ if (!au_digen_test(dentry, au_sigen(sb))
5527c038 11355+ && d_inode(dentry)->i_generation == fh[Fh_igen])
1facf9fc 11356+ goto out_unlock; /* success */
11357+
11358+ dput(dentry);
11359+ dentry = ERR_PTR(-ESTALE);
4f0767ce 11360+out_unlock:
027c5e7a
AM
11361+ if (br)
11362+ atomic_dec(&br->br_count);
1facf9fc 11363+ si_read_unlock(sb);
4f0767ce 11364+out:
1facf9fc 11365+ AuTraceErrPtr(dentry);
11366+ return dentry;
11367+}
11368+
11369+#if 0 /* reserved for future use */
11370+/* support subtreecheck option */
11371+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
11372+ int fh_len, int fh_type)
11373+{
11374+ struct dentry *parent;
11375+ __u32 *fh = fid->raw;
11376+ ino_t dir_ino;
11377+
11378+ dir_ino = decode_ino(fh + Fh_dir_ino);
11379+ parent = decode_by_ino(sb, dir_ino, 0);
11380+ if (IS_ERR(parent))
11381+ goto out;
11382+ if (!parent)
11383+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
11384+ dir_ino, fh, fh_len);
11385+
4f0767ce 11386+out:
1facf9fc 11387+ AuTraceErrPtr(parent);
11388+ return parent;
11389+}
11390+#endif
11391+
11392+/* ---------------------------------------------------------------------- */
11393+
0c3ec466
AM
11394+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
11395+ struct inode *dir)
1facf9fc 11396+{
11397+ int err;
0c3ec466 11398+ aufs_bindex_t bindex;
1facf9fc 11399+ struct super_block *sb, *h_sb;
0c3ec466
AM
11400+ struct dentry *dentry, *parent, *h_parent;
11401+ struct inode *h_dir;
1facf9fc 11402+ struct au_branch *br;
11403+
1facf9fc 11404+ err = -ENOSPC;
11405+ if (unlikely(*max_len <= Fh_tail)) {
11406+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
11407+ goto out;
11408+ }
11409+
11410+ err = FILEID_ROOT;
0c3ec466
AM
11411+ if (inode->i_ino == AUFS_ROOT_INO) {
11412+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 11413+ goto out;
11414+ }
11415+
1facf9fc 11416+ h_parent = NULL;
0c3ec466
AM
11417+ sb = inode->i_sb;
11418+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
11419+ if (unlikely(err))
11420+ goto out;
11421+
1facf9fc 11422+#ifdef CONFIG_AUFS_DEBUG
11423+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
11424+ AuWarn1("NFS-exporting requires xino\n");
11425+#endif
027c5e7a 11426+ err = -EIO;
0c3ec466
AM
11427+ parent = NULL;
11428+ ii_read_lock_child(inode);
11429+ bindex = au_ibstart(inode);
11430+ if (!dir) {
c1595e42 11431+ dentry = d_find_any_alias(inode);
0c3ec466
AM
11432+ if (unlikely(!dentry))
11433+ goto out_unlock;
11434+ AuDebugOn(au_test_anon(dentry));
11435+ parent = dget_parent(dentry);
11436+ dput(dentry);
11437+ if (unlikely(!parent))
11438+ goto out_unlock;
5527c038
JR
11439+ if (d_really_is_positive(parent))
11440+ dir = d_inode(parent);
1facf9fc 11441+ }
0c3ec466
AM
11442+
11443+ ii_read_lock_parent(dir);
11444+ h_dir = au_h_iptr(dir, bindex);
11445+ ii_read_unlock(dir);
11446+ if (unlikely(!h_dir))
11447+ goto out_parent;
c1595e42 11448+ h_parent = d_find_any_alias(h_dir);
1facf9fc 11449+ if (unlikely(!h_parent))
0c3ec466 11450+ goto out_hparent;
1facf9fc 11451+
11452+ err = -EPERM;
11453+ br = au_sbr(sb, bindex);
86dc4139 11454+ h_sb = au_br_sb(br);
1facf9fc 11455+ if (unlikely(!h_sb->s_export_op)) {
11456+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 11457+ goto out_hparent;
1facf9fc 11458+ }
11459+
11460+ fh[Fh_br_id] = br->br_id;
11461+ fh[Fh_sigen] = au_sigen(sb);
11462+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 11463+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 11464+ fh[Fh_igen] = inode->i_generation;
11465+
11466+ *max_len -= Fh_tail;
11467+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
11468+ max_len,
11469+ /*connectable or subtreecheck*/0);
11470+ err = fh[Fh_h_type];
11471+ *max_len += Fh_tail;
11472+ /* todo: macros? */
1716fcea 11473+ if (err != FILEID_INVALID)
1facf9fc 11474+ err = 99;
11475+ else
11476+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
11477+
0c3ec466 11478+out_hparent:
1facf9fc 11479+ dput(h_parent);
0c3ec466 11480+out_parent:
1facf9fc 11481+ dput(parent);
0c3ec466
AM
11482+out_unlock:
11483+ ii_read_unlock(inode);
11484+ si_read_unlock(sb);
4f0767ce 11485+out:
1facf9fc 11486+ if (unlikely(err < 0))
1716fcea 11487+ err = FILEID_INVALID;
1facf9fc 11488+ return err;
11489+}
11490+
11491+/* ---------------------------------------------------------------------- */
11492+
4a4d8108
AM
11493+static int aufs_commit_metadata(struct inode *inode)
11494+{
11495+ int err;
11496+ aufs_bindex_t bindex;
11497+ struct super_block *sb;
11498+ struct inode *h_inode;
11499+ int (*f)(struct inode *inode);
11500+
11501+ sb = inode->i_sb;
e49829fe 11502+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11503+ ii_write_lock_child(inode);
11504+ bindex = au_ibstart(inode);
11505+ AuDebugOn(bindex < 0);
11506+ h_inode = au_h_iptr(inode, bindex);
11507+
11508+ f = h_inode->i_sb->s_export_op->commit_metadata;
11509+ if (f)
11510+ err = f(h_inode);
11511+ else {
11512+ struct writeback_control wbc = {
11513+ .sync_mode = WB_SYNC_ALL,
11514+ .nr_to_write = 0 /* metadata only */
11515+ };
11516+
11517+ err = sync_inode(h_inode, &wbc);
11518+ }
11519+
11520+ au_cpup_attr_timesizes(inode);
11521+ ii_write_unlock(inode);
11522+ si_read_unlock(sb);
11523+ return err;
11524+}
11525+
11526+/* ---------------------------------------------------------------------- */
11527+
1facf9fc 11528+static struct export_operations aufs_export_op = {
4a4d8108 11529+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 11530+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
11531+ .encode_fh = aufs_encode_fh,
11532+ .commit_metadata = aufs_commit_metadata
1facf9fc 11533+};
11534+
11535+void au_export_init(struct super_block *sb)
11536+{
11537+ struct au_sbinfo *sbinfo;
11538+ __u32 u;
11539+
11540+ sb->s_export_op = &aufs_export_op;
11541+ sbinfo = au_sbi(sb);
11542+ sbinfo->si_xigen = NULL;
11543+ get_random_bytes(&u, sizeof(u));
11544+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
11545+ atomic_set(&sbinfo->si_xigen_next, u);
11546+}
076b876e
AM
11547diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
11548--- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 11549+++ linux/fs/aufs/fhsm.c 2015-09-24 10:47:58.251386326 +0200
c1595e42 11550@@ -0,0 +1,426 @@
076b876e 11551+/*
2000de60 11552+ * Copyright (C) 2011-2015 Junjiro R. Okajima
076b876e
AM
11553+ *
11554+ * This program, aufs is free software; you can redistribute it and/or modify
11555+ * it under the terms of the GNU General Public License as published by
11556+ * the Free Software Foundation; either version 2 of the License, or
11557+ * (at your option) any later version.
11558+ *
11559+ * This program is distributed in the hope that it will be useful,
11560+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11561+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11562+ * GNU General Public License for more details.
11563+ *
11564+ * You should have received a copy of the GNU General Public License
11565+ * along with this program; if not, write to the Free Software
11566+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11567+ */
11568+
11569+/*
11570+ * File-based Hierarchy Storage Management
11571+ */
11572+
11573+#include <linux/anon_inodes.h>
11574+#include <linux/poll.h>
11575+#include <linux/seq_file.h>
11576+#include <linux/statfs.h>
11577+#include "aufs.h"
11578+
c1595e42
JR
11579+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb)
11580+{
11581+ struct au_sbinfo *sbinfo;
11582+ struct au_fhsm *fhsm;
11583+
11584+ SiMustAnyLock(sb);
11585+
11586+ sbinfo = au_sbi(sb);
11587+ fhsm = &sbinfo->si_fhsm;
11588+ AuDebugOn(!fhsm);
11589+ return fhsm->fhsm_bottom;
11590+}
11591+
11592+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex)
11593+{
11594+ struct au_sbinfo *sbinfo;
11595+ struct au_fhsm *fhsm;
11596+
11597+ SiMustWriteLock(sb);
11598+
11599+ sbinfo = au_sbi(sb);
11600+ fhsm = &sbinfo->si_fhsm;
11601+ AuDebugOn(!fhsm);
11602+ fhsm->fhsm_bottom = bindex;
11603+}
11604+
11605+/* ---------------------------------------------------------------------- */
11606+
076b876e
AM
11607+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
11608+{
11609+ struct au_br_fhsm *bf;
11610+
11611+ bf = br->br_fhsm;
11612+ MtxMustLock(&bf->bf_lock);
11613+
11614+ return !bf->bf_readable
11615+ || time_after(jiffies,
11616+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
11617+}
11618+
11619+/* ---------------------------------------------------------------------- */
11620+
11621+static void au_fhsm_notify(struct super_block *sb, int val)
11622+{
11623+ struct au_sbinfo *sbinfo;
11624+ struct au_fhsm *fhsm;
11625+
11626+ SiMustAnyLock(sb);
11627+
11628+ sbinfo = au_sbi(sb);
11629+ fhsm = &sbinfo->si_fhsm;
11630+ if (au_fhsm_pid(fhsm)
11631+ && atomic_read(&fhsm->fhsm_readable) != -1) {
11632+ atomic_set(&fhsm->fhsm_readable, val);
11633+ if (val)
11634+ wake_up(&fhsm->fhsm_wqh);
11635+ }
11636+}
11637+
11638+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
11639+ struct aufs_stfs *rstfs, int do_lock, int do_notify)
11640+{
11641+ int err;
11642+ struct au_branch *br;
11643+ struct au_br_fhsm *bf;
11644+
11645+ br = au_sbr(sb, bindex);
11646+ AuDebugOn(au_br_rdonly(br));
11647+ bf = br->br_fhsm;
11648+ AuDebugOn(!bf);
11649+
11650+ if (do_lock)
11651+ mutex_lock(&bf->bf_lock);
11652+ else
11653+ MtxMustLock(&bf->bf_lock);
11654+
11655+ /* sb->s_root for NFS is unreliable */
11656+ err = au_br_stfs(br, &bf->bf_stfs);
11657+ if (unlikely(err)) {
11658+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
11659+ goto out;
11660+ }
11661+
11662+ bf->bf_jiffy = jiffies;
11663+ bf->bf_readable = 1;
11664+ if (do_notify)
11665+ au_fhsm_notify(sb, /*val*/1);
11666+ if (rstfs)
11667+ *rstfs = bf->bf_stfs;
11668+
11669+out:
11670+ if (do_lock)
11671+ mutex_unlock(&bf->bf_lock);
11672+ au_fhsm_notify(sb, /*val*/1);
11673+
11674+ return err;
11675+}
11676+
11677+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
11678+{
11679+ int err;
076b876e
AM
11680+ struct au_sbinfo *sbinfo;
11681+ struct au_fhsm *fhsm;
11682+ struct au_branch *br;
11683+ struct au_br_fhsm *bf;
11684+
11685+ AuDbg("b%d, force %d\n", bindex, force);
11686+ SiMustAnyLock(sb);
11687+
11688+ sbinfo = au_sbi(sb);
11689+ fhsm = &sbinfo->si_fhsm;
c1595e42
JR
11690+ if (!au_ftest_si(sbinfo, FHSM)
11691+ || fhsm->fhsm_bottom == bindex)
076b876e
AM
11692+ return;
11693+
11694+ br = au_sbr(sb, bindex);
11695+ bf = br->br_fhsm;
11696+ AuDebugOn(!bf);
11697+ mutex_lock(&bf->bf_lock);
11698+ if (force
11699+ || au_fhsm_pid(fhsm)
11700+ || au_fhsm_test_jiffy(sbinfo, br))
11701+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
11702+ /*do_notify*/1);
11703+ mutex_unlock(&bf->bf_lock);
11704+}
11705+
11706+void au_fhsm_wrote_all(struct super_block *sb, int force)
11707+{
11708+ aufs_bindex_t bindex, bend;
11709+ struct au_branch *br;
11710+
11711+ /* exclude the bottom */
c1595e42 11712+ bend = au_fhsm_bottom(sb);
076b876e
AM
11713+ for (bindex = 0; bindex < bend; bindex++) {
11714+ br = au_sbr(sb, bindex);
11715+ if (au_br_fhsm(br->br_perm))
11716+ au_fhsm_wrote(sb, bindex, force);
11717+ }
11718+}
11719+
11720+/* ---------------------------------------------------------------------- */
11721+
11722+static unsigned int au_fhsm_poll(struct file *file,
11723+ struct poll_table_struct *wait)
11724+{
11725+ unsigned int mask;
11726+ struct au_sbinfo *sbinfo;
11727+ struct au_fhsm *fhsm;
11728+
11729+ mask = 0;
11730+ sbinfo = file->private_data;
11731+ fhsm = &sbinfo->si_fhsm;
11732+ poll_wait(file, &fhsm->fhsm_wqh, wait);
11733+ if (atomic_read(&fhsm->fhsm_readable))
11734+ mask = POLLIN /* | POLLRDNORM */;
11735+
11736+ AuTraceErr((int)mask);
11737+ return mask;
11738+}
11739+
11740+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
11741+ struct aufs_stfs *stfs, __s16 brid)
11742+{
11743+ int err;
11744+
11745+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
11746+ if (!err)
11747+ err = __put_user(brid, &stbr->brid);
11748+ if (unlikely(err))
11749+ err = -EFAULT;
11750+
11751+ return err;
11752+}
11753+
11754+static ssize_t au_fhsm_do_read(struct super_block *sb,
11755+ struct aufs_stbr __user *stbr, size_t count)
11756+{
11757+ ssize_t err;
11758+ int nstbr;
11759+ aufs_bindex_t bindex, bend;
11760+ struct au_branch *br;
11761+ struct au_br_fhsm *bf;
11762+
11763+ /* except the bottom branch */
11764+ err = 0;
11765+ nstbr = 0;
c1595e42 11766+ bend = au_fhsm_bottom(sb);
076b876e
AM
11767+ for (bindex = 0; !err && bindex < bend; bindex++) {
11768+ br = au_sbr(sb, bindex);
11769+ if (!au_br_fhsm(br->br_perm))
11770+ continue;
11771+
11772+ bf = br->br_fhsm;
11773+ mutex_lock(&bf->bf_lock);
11774+ if (bf->bf_readable) {
11775+ err = -EFAULT;
11776+ if (count >= sizeof(*stbr))
11777+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
11778+ br->br_id);
11779+ if (!err) {
11780+ bf->bf_readable = 0;
11781+ count -= sizeof(*stbr);
11782+ nstbr++;
11783+ }
11784+ }
11785+ mutex_unlock(&bf->bf_lock);
11786+ }
11787+ if (!err)
11788+ err = sizeof(*stbr) * nstbr;
11789+
11790+ return err;
11791+}
11792+
11793+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
11794+ loff_t *pos)
11795+{
11796+ ssize_t err;
11797+ int readable;
11798+ aufs_bindex_t nfhsm, bindex, bend;
11799+ struct au_sbinfo *sbinfo;
11800+ struct au_fhsm *fhsm;
11801+ struct au_branch *br;
11802+ struct super_block *sb;
11803+
11804+ err = 0;
11805+ sbinfo = file->private_data;
11806+ fhsm = &sbinfo->si_fhsm;
11807+need_data:
11808+ spin_lock_irq(&fhsm->fhsm_wqh.lock);
11809+ if (!atomic_read(&fhsm->fhsm_readable)) {
11810+ if (vfsub_file_flags(file) & O_NONBLOCK)
11811+ err = -EAGAIN;
11812+ else
11813+ err = wait_event_interruptible_locked_irq
11814+ (fhsm->fhsm_wqh,
11815+ atomic_read(&fhsm->fhsm_readable));
11816+ }
11817+ spin_unlock_irq(&fhsm->fhsm_wqh.lock);
11818+ if (unlikely(err))
11819+ goto out;
11820+
11821+ /* sb may already be dead */
11822+ au_rw_read_lock(&sbinfo->si_rwsem);
11823+ readable = atomic_read(&fhsm->fhsm_readable);
11824+ if (readable > 0) {
11825+ sb = sbinfo->si_sb;
11826+ AuDebugOn(!sb);
11827+ /* exclude the bottom branch */
11828+ nfhsm = 0;
c1595e42 11829+ bend = au_fhsm_bottom(sb);
076b876e
AM
11830+ for (bindex = 0; bindex < bend; bindex++) {
11831+ br = au_sbr(sb, bindex);
11832+ if (au_br_fhsm(br->br_perm))
11833+ nfhsm++;
11834+ }
11835+ err = -EMSGSIZE;
11836+ if (nfhsm * sizeof(struct aufs_stbr) <= count) {
11837+ atomic_set(&fhsm->fhsm_readable, 0);
11838+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
11839+ count);
11840+ }
11841+ }
11842+ au_rw_read_unlock(&sbinfo->si_rwsem);
11843+ if (!readable)
11844+ goto need_data;
11845+
11846+out:
11847+ return err;
11848+}
11849+
11850+static int au_fhsm_release(struct inode *inode, struct file *file)
11851+{
11852+ struct au_sbinfo *sbinfo;
11853+ struct au_fhsm *fhsm;
11854+
11855+ /* sb may already be dead */
11856+ sbinfo = file->private_data;
11857+ fhsm = &sbinfo->si_fhsm;
11858+ spin_lock(&fhsm->fhsm_spin);
11859+ fhsm->fhsm_pid = 0;
11860+ spin_unlock(&fhsm->fhsm_spin);
11861+ kobject_put(&sbinfo->si_kobj);
11862+
11863+ return 0;
11864+}
11865+
11866+static const struct file_operations au_fhsm_fops = {
11867+ .owner = THIS_MODULE,
11868+ .llseek = noop_llseek,
11869+ .read = au_fhsm_read,
11870+ .poll = au_fhsm_poll,
11871+ .release = au_fhsm_release
11872+};
11873+
11874+int au_fhsm_fd(struct super_block *sb, int oflags)
11875+{
11876+ int err, fd;
11877+ struct au_sbinfo *sbinfo;
11878+ struct au_fhsm *fhsm;
11879+
11880+ err = -EPERM;
11881+ if (unlikely(!capable(CAP_SYS_ADMIN)))
11882+ goto out;
11883+
11884+ err = -EINVAL;
11885+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
11886+ goto out;
11887+
11888+ err = 0;
11889+ sbinfo = au_sbi(sb);
11890+ fhsm = &sbinfo->si_fhsm;
11891+ spin_lock(&fhsm->fhsm_spin);
11892+ if (!fhsm->fhsm_pid)
11893+ fhsm->fhsm_pid = current->pid;
11894+ else
11895+ err = -EBUSY;
11896+ spin_unlock(&fhsm->fhsm_spin);
11897+ if (unlikely(err))
11898+ goto out;
11899+
11900+ oflags |= O_RDONLY;
11901+ /* oflags |= FMODE_NONOTIFY; */
11902+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
11903+ err = fd;
11904+ if (unlikely(fd < 0))
11905+ goto out_pid;
11906+
11907+ /* succeed reglardless 'fhsm' status */
11908+ kobject_get(&sbinfo->si_kobj);
11909+ si_noflush_read_lock(sb);
11910+ if (au_ftest_si(sbinfo, FHSM))
11911+ au_fhsm_wrote_all(sb, /*force*/0);
11912+ si_read_unlock(sb);
11913+ goto out; /* success */
11914+
11915+out_pid:
11916+ spin_lock(&fhsm->fhsm_spin);
11917+ fhsm->fhsm_pid = 0;
11918+ spin_unlock(&fhsm->fhsm_spin);
11919+out:
11920+ AuTraceErr(err);
11921+ return err;
11922+}
11923+
11924+/* ---------------------------------------------------------------------- */
11925+
11926+int au_fhsm_br_alloc(struct au_branch *br)
11927+{
11928+ int err;
11929+
11930+ err = 0;
11931+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
11932+ if (br->br_fhsm)
11933+ au_br_fhsm_init(br->br_fhsm);
11934+ else
11935+ err = -ENOMEM;
11936+
11937+ return err;
11938+}
11939+
11940+/* ---------------------------------------------------------------------- */
11941+
11942+void au_fhsm_fin(struct super_block *sb)
11943+{
11944+ au_fhsm_notify(sb, /*val*/-1);
11945+}
11946+
11947+void au_fhsm_init(struct au_sbinfo *sbinfo)
11948+{
11949+ struct au_fhsm *fhsm;
11950+
11951+ fhsm = &sbinfo->si_fhsm;
11952+ spin_lock_init(&fhsm->fhsm_spin);
11953+ init_waitqueue_head(&fhsm->fhsm_wqh);
11954+ atomic_set(&fhsm->fhsm_readable, 0);
11955+ fhsm->fhsm_expire
11956+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
c1595e42 11957+ fhsm->fhsm_bottom = -1;
076b876e
AM
11958+}
11959+
11960+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
11961+{
11962+ sbinfo->si_fhsm.fhsm_expire
11963+ = msecs_to_jiffies(sec * MSEC_PER_SEC);
11964+}
11965+
11966+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
11967+{
11968+ unsigned int u;
11969+
11970+ if (!au_ftest_si(sbinfo, FHSM))
11971+ return;
11972+
11973+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
11974+ if (u != AUFS_FHSM_CACHE_DEF_SEC)
11975+ seq_printf(seq, ",fhsm_sec=%u", u);
11976+}
7f207e10
AM
11977diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
11978--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
11979+++ linux/fs/aufs/file.c 2015-11-11 17:21:46.918863802 +0100
11980@@ -0,0 +1,844 @@
1facf9fc 11981+/*
2000de60 11982+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 11983+ *
11984+ * This program, aufs is free software; you can redistribute it and/or modify
11985+ * it under the terms of the GNU General Public License as published by
11986+ * the Free Software Foundation; either version 2 of the License, or
11987+ * (at your option) any later version.
dece6358
AM
11988+ *
11989+ * This program is distributed in the hope that it will be useful,
11990+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11991+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11992+ * GNU General Public License for more details.
11993+ *
11994+ * You should have received a copy of the GNU General Public License
523b37e3 11995+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 11996+ */
11997+
11998+/*
4a4d8108 11999+ * handling file/dir, and address_space operation
1facf9fc 12000+ */
12001+
7eafdf33
AM
12002+#ifdef CONFIG_AUFS_DEBUG
12003+#include <linux/migrate.h>
12004+#endif
4a4d8108 12005+#include <linux/pagemap.h>
1facf9fc 12006+#include "aufs.h"
12007+
4a4d8108
AM
12008+/* drop flags for writing */
12009+unsigned int au_file_roflags(unsigned int flags)
12010+{
12011+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
12012+ flags |= O_RDONLY | O_NOATIME;
12013+ return flags;
12014+}
12015+
12016+/* common functions to regular file and dir */
12017+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 12018+ struct file *file, int force_wr)
1facf9fc 12019+{
1308ab2a 12020+ struct file *h_file;
4a4d8108
AM
12021+ struct dentry *h_dentry;
12022+ struct inode *h_inode;
12023+ struct super_block *sb;
12024+ struct au_branch *br;
12025+ struct path h_path;
b912730e 12026+ int err;
1facf9fc 12027+
4a4d8108
AM
12028+ /* a race condition can happen between open and unlink/rmdir */
12029+ h_file = ERR_PTR(-ENOENT);
12030+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 12031+ if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry)))
4a4d8108 12032+ goto out;
5527c038 12033+ h_inode = d_inode(h_dentry);
027c5e7a
AM
12034+ spin_lock(&h_dentry->d_lock);
12035+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
5527c038 12036+ /* || !d_inode(dentry)->i_nlink */
027c5e7a
AM
12037+ ;
12038+ spin_unlock(&h_dentry->d_lock);
12039+ if (unlikely(err))
4a4d8108 12040+ goto out;
1facf9fc 12041+
4a4d8108
AM
12042+ sb = dentry->d_sb;
12043+ br = au_sbr(sb, bindex);
b912730e
AM
12044+ err = au_br_test_oflag(flags, br);
12045+ h_file = ERR_PTR(err);
12046+ if (unlikely(err))
027c5e7a 12047+ goto out;
1facf9fc 12048+
4a4d8108 12049+ /* drop flags for writing */
5527c038 12050+ if (au_test_ro(sb, bindex, d_inode(dentry))) {
392086de
AM
12051+ if (force_wr && !(flags & O_WRONLY))
12052+ force_wr = 0;
4a4d8108 12053+ flags = au_file_roflags(flags);
392086de
AM
12054+ if (force_wr) {
12055+ h_file = ERR_PTR(-EROFS);
12056+ flags = au_file_roflags(flags);
12057+ if (unlikely(vfsub_native_ro(h_inode)
12058+ || IS_APPEND(h_inode)))
12059+ goto out;
12060+ flags &= ~O_ACCMODE;
12061+ flags |= O_WRONLY;
12062+ }
12063+ }
4a4d8108
AM
12064+ flags &= ~O_CREAT;
12065+ atomic_inc(&br->br_count);
12066+ h_path.dentry = h_dentry;
86dc4139 12067+ h_path.mnt = au_br_mnt(br);
38d290e6 12068+ h_file = vfsub_dentry_open(&h_path, flags);
4a4d8108
AM
12069+ if (IS_ERR(h_file))
12070+ goto out_br;
dece6358 12071+
b912730e 12072+ if (flags & __FMODE_EXEC) {
4a4d8108
AM
12073+ err = deny_write_access(h_file);
12074+ if (unlikely(err)) {
12075+ fput(h_file);
12076+ h_file = ERR_PTR(err);
12077+ goto out_br;
12078+ }
12079+ }
953406b4 12080+ fsnotify_open(h_file);
4a4d8108 12081+ goto out; /* success */
1facf9fc 12082+
4f0767ce 12083+out_br:
4a4d8108 12084+ atomic_dec(&br->br_count);
4f0767ce 12085+out:
4a4d8108
AM
12086+ return h_file;
12087+}
1308ab2a 12088+
076b876e
AM
12089+static int au_cmoo(struct dentry *dentry)
12090+{
12091+ int err, cmoo;
12092+ unsigned int udba;
12093+ struct path h_path;
12094+ struct au_pin pin;
12095+ struct au_cp_generic cpg = {
12096+ .dentry = dentry,
12097+ .bdst = -1,
12098+ .bsrc = -1,
12099+ .len = -1,
12100+ .pin = &pin,
12101+ .flags = AuCpup_DTIME | AuCpup_HOPEN
12102+ };
7e9cd9fe 12103+ struct inode *delegated;
076b876e
AM
12104+ struct super_block *sb;
12105+ struct au_sbinfo *sbinfo;
12106+ struct au_fhsm *fhsm;
12107+ pid_t pid;
12108+ struct au_branch *br;
12109+ struct dentry *parent;
12110+ struct au_hinode *hdir;
12111+
12112+ DiMustWriteLock(dentry);
5527c038 12113+ IiMustWriteLock(d_inode(dentry));
076b876e
AM
12114+
12115+ err = 0;
12116+ if (IS_ROOT(dentry))
12117+ goto out;
12118+ cpg.bsrc = au_dbstart(dentry);
12119+ if (!cpg.bsrc)
12120+ goto out;
12121+
12122+ sb = dentry->d_sb;
12123+ sbinfo = au_sbi(sb);
12124+ fhsm = &sbinfo->si_fhsm;
12125+ pid = au_fhsm_pid(fhsm);
12126+ if (pid
12127+ && (current->pid == pid
12128+ || current->real_parent->pid == pid))
12129+ goto out;
12130+
12131+ br = au_sbr(sb, cpg.bsrc);
12132+ cmoo = au_br_cmoo(br->br_perm);
12133+ if (!cmoo)
12134+ goto out;
7e9cd9fe 12135+ if (!d_is_reg(dentry))
076b876e
AM
12136+ cmoo &= AuBrAttr_COO_ALL;
12137+ if (!cmoo)
12138+ goto out;
12139+
12140+ parent = dget_parent(dentry);
12141+ di_write_lock_parent(parent);
12142+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
12143+ cpg.bdst = err;
12144+ if (unlikely(err < 0)) {
12145+ err = 0; /* there is no upper writable branch */
12146+ goto out_dgrade;
12147+ }
12148+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
12149+
12150+ /* do not respect the coo attrib for the target branch */
12151+ err = au_cpup_dirs(dentry, cpg.bdst);
12152+ if (unlikely(err))
12153+ goto out_dgrade;
12154+
12155+ di_downgrade_lock(parent, AuLock_IR);
12156+ udba = au_opt_udba(sb);
12157+ err = au_pin(&pin, dentry, cpg.bdst, udba,
12158+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12159+ if (unlikely(err))
12160+ goto out_parent;
12161+
12162+ err = au_sio_cpup_simple(&cpg);
12163+ au_unpin(&pin);
12164+ if (unlikely(err))
12165+ goto out_parent;
12166+ if (!(cmoo & AuBrWAttr_MOO))
12167+ goto out_parent; /* success */
12168+
12169+ err = au_pin(&pin, dentry, cpg.bsrc, udba,
12170+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12171+ if (unlikely(err))
12172+ goto out_parent;
12173+
12174+ h_path.mnt = au_br_mnt(br);
12175+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
5527c038 12176+ hdir = au_hi(d_inode(parent), cpg.bsrc);
076b876e
AM
12177+ delegated = NULL;
12178+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
12179+ au_unpin(&pin);
12180+ /* todo: keep h_dentry or not? */
12181+ if (unlikely(err == -EWOULDBLOCK)) {
12182+ pr_warn("cannot retry for NFSv4 delegation"
12183+ " for an internal unlink\n");
12184+ iput(delegated);
12185+ }
12186+ if (unlikely(err)) {
12187+ pr_err("unlink %pd after coo failed (%d), ignored\n",
12188+ dentry, err);
12189+ err = 0;
12190+ }
12191+ goto out_parent; /* success */
12192+
12193+out_dgrade:
12194+ di_downgrade_lock(parent, AuLock_IR);
12195+out_parent:
12196+ di_read_unlock(parent, AuLock_IR);
12197+ dput(parent);
12198+out:
12199+ AuTraceErr(err);
12200+ return err;
12201+}
12202+
b912730e 12203+int au_do_open(struct file *file, struct au_do_open_args *args)
1facf9fc 12204+{
b912730e 12205+ int err, no_lock = args->no_lock;
1facf9fc 12206+ struct dentry *dentry;
076b876e 12207+ struct au_finfo *finfo;
1308ab2a 12208+
b912730e
AM
12209+ if (!no_lock)
12210+ err = au_finfo_init(file, args->fidir);
12211+ else {
12212+ lockdep_off();
12213+ err = au_finfo_init(file, args->fidir);
12214+ lockdep_on();
12215+ }
4a4d8108
AM
12216+ if (unlikely(err))
12217+ goto out;
1facf9fc 12218+
2000de60 12219+ dentry = file->f_path.dentry;
b912730e
AM
12220+ AuDebugOn(IS_ERR_OR_NULL(dentry));
12221+ if (!no_lock) {
12222+ di_write_lock_child(dentry);
12223+ err = au_cmoo(dentry);
12224+ di_downgrade_lock(dentry, AuLock_IR);
12225+ if (!err)
12226+ err = args->open(file, vfsub_file_flags(file), NULL);
12227+ di_read_unlock(dentry, AuLock_IR);
12228+ } else {
12229+ err = au_cmoo(dentry);
12230+ if (!err)
12231+ err = args->open(file, vfsub_file_flags(file),
12232+ args->h_file);
12233+ if (!err && au_fbstart(file) != au_dbstart(dentry))
12234+ /*
12235+ * cmoo happens after h_file was opened.
12236+ * need to refresh file later.
12237+ */
12238+ atomic_dec(&au_fi(file)->fi_generation);
12239+ }
1facf9fc 12240+
076b876e
AM
12241+ finfo = au_fi(file);
12242+ if (!err) {
12243+ finfo->fi_file = file;
12244+ au_sphl_add(&finfo->fi_hlist,
2000de60 12245+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
076b876e 12246+ }
b912730e
AM
12247+ if (!no_lock)
12248+ fi_write_unlock(file);
12249+ else {
12250+ lockdep_off();
12251+ fi_write_unlock(file);
12252+ lockdep_on();
12253+ }
4a4d8108 12254+ if (unlikely(err)) {
076b876e 12255+ finfo->fi_hdir = NULL;
4a4d8108 12256+ au_finfo_fin(file);
1308ab2a 12257+ }
4a4d8108 12258+
4f0767ce 12259+out:
1308ab2a 12260+ return err;
12261+}
dece6358 12262+
4a4d8108 12263+int au_reopen_nondir(struct file *file)
1308ab2a 12264+{
4a4d8108
AM
12265+ int err;
12266+ aufs_bindex_t bstart;
12267+ struct dentry *dentry;
12268+ struct file *h_file, *h_file_tmp;
1308ab2a 12269+
2000de60 12270+ dentry = file->f_path.dentry;
4a4d8108
AM
12271+ bstart = au_dbstart(dentry);
12272+ h_file_tmp = NULL;
12273+ if (au_fbstart(file) == bstart) {
12274+ h_file = au_hf_top(file);
12275+ if (file->f_mode == h_file->f_mode)
12276+ return 0; /* success */
12277+ h_file_tmp = h_file;
12278+ get_file(h_file_tmp);
12279+ au_set_h_fptr(file, bstart, NULL);
12280+ }
12281+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
12282+ /*
12283+ * it can happen
12284+ * file exists on both of rw and ro
12285+ * open --> dbstart and fbstart are both 0
12286+ * prepend a branch as rw, "rw" become ro
12287+ * remove rw/file
12288+ * delete the top branch, "rw" becomes rw again
12289+ * --> dbstart is 1, fbstart is still 0
12290+ * write --> fbstart is 0 but dbstart is 1
12291+ */
12292+ /* AuDebugOn(au_fbstart(file) < bstart); */
1308ab2a 12293+
4a4d8108 12294+ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
392086de 12295+ file, /*force_wr*/0);
4a4d8108 12296+ err = PTR_ERR(h_file);
86dc4139
AM
12297+ if (IS_ERR(h_file)) {
12298+ if (h_file_tmp) {
12299+ atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
12300+ au_set_h_fptr(file, bstart, h_file_tmp);
12301+ h_file_tmp = NULL;
12302+ }
4a4d8108 12303+ goto out; /* todo: close all? */
86dc4139 12304+ }
4a4d8108
AM
12305+
12306+ err = 0;
12307+ au_set_fbstart(file, bstart);
12308+ au_set_h_fptr(file, bstart, h_file);
12309+ au_update_figen(file);
12310+ /* todo: necessary? */
12311+ /* file->f_ra = h_file->f_ra; */
12312+
4f0767ce 12313+out:
4a4d8108
AM
12314+ if (h_file_tmp)
12315+ fput(h_file_tmp);
12316+ return err;
1facf9fc 12317+}
12318+
1308ab2a 12319+/* ---------------------------------------------------------------------- */
12320+
4a4d8108
AM
12321+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
12322+ struct dentry *hi_wh)
1facf9fc 12323+{
4a4d8108
AM
12324+ int err;
12325+ aufs_bindex_t bstart;
12326+ struct au_dinfo *dinfo;
12327+ struct dentry *h_dentry;
12328+ struct au_hdentry *hdp;
1facf9fc 12329+
2000de60 12330+ dinfo = au_di(file->f_path.dentry);
4a4d8108 12331+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 12332+
4a4d8108
AM
12333+ bstart = dinfo->di_bstart;
12334+ dinfo->di_bstart = btgt;
12335+ hdp = dinfo->di_hdentry;
12336+ h_dentry = hdp[0 + btgt].hd_dentry;
12337+ hdp[0 + btgt].hd_dentry = hi_wh;
12338+ err = au_reopen_nondir(file);
12339+ hdp[0 + btgt].hd_dentry = h_dentry;
12340+ dinfo->di_bstart = bstart;
1facf9fc 12341+
1facf9fc 12342+ return err;
12343+}
12344+
4a4d8108 12345+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 12346+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 12347+{
4a4d8108 12348+ int err;
027c5e7a 12349+ struct inode *inode, *h_inode;
c2b27bf2
AM
12350+ struct dentry *h_dentry, *hi_wh;
12351+ struct au_cp_generic cpg = {
2000de60 12352+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12353+ .bdst = bcpup,
12354+ .bsrc = -1,
12355+ .len = len,
12356+ .pin = pin
12357+ };
1facf9fc 12358+
c2b27bf2 12359+ au_update_dbstart(cpg.dentry);
5527c038 12360+ inode = d_inode(cpg.dentry);
027c5e7a 12361+ h_inode = NULL;
c2b27bf2
AM
12362+ if (au_dbstart(cpg.dentry) <= bcpup
12363+ && au_dbend(cpg.dentry) >= bcpup) {
12364+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
5527c038
JR
12365+ if (h_dentry && d_is_positive(h_dentry))
12366+ h_inode = d_inode(h_dentry);
027c5e7a 12367+ }
4a4d8108 12368+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 12369+ if (!hi_wh && !h_inode)
c2b27bf2 12370+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
12371+ else
12372+ /* already copied-up after unlink */
12373+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 12374+
4a4d8108 12375+ if (!err
38d290e6
JR
12376+ && (inode->i_nlink > 1
12377+ || (inode->i_state & I_LINKABLE))
c2b27bf2
AM
12378+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
12379+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 12380+
dece6358 12381+ return err;
1facf9fc 12382+}
12383+
4a4d8108
AM
12384+/*
12385+ * prepare the @file for writing.
12386+ */
12387+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 12388+{
4a4d8108 12389+ int err;
c2b27bf2 12390+ aufs_bindex_t dbstart;
c1595e42 12391+ struct dentry *parent;
86dc4139 12392+ struct inode *inode;
1facf9fc 12393+ struct super_block *sb;
4a4d8108 12394+ struct file *h_file;
c2b27bf2 12395+ struct au_cp_generic cpg = {
2000de60 12396+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12397+ .bdst = -1,
12398+ .bsrc = -1,
12399+ .len = len,
12400+ .pin = pin,
12401+ .flags = AuCpup_DTIME
12402+ };
1facf9fc 12403+
c2b27bf2 12404+ sb = cpg.dentry->d_sb;
5527c038 12405+ inode = d_inode(cpg.dentry);
c2b27bf2
AM
12406+ cpg.bsrc = au_fbstart(file);
12407+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 12408+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
12409+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
12410+ /*flags*/0);
1facf9fc 12411+ goto out;
4a4d8108 12412+ }
1facf9fc 12413+
027c5e7a 12414+ /* need to cpup or reopen */
c2b27bf2 12415+ parent = dget_parent(cpg.dentry);
4a4d8108 12416+ di_write_lock_parent(parent);
c2b27bf2
AM
12417+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12418+ cpg.bdst = err;
4a4d8108
AM
12419+ if (unlikely(err < 0))
12420+ goto out_dgrade;
12421+ err = 0;
12422+
c2b27bf2
AM
12423+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
12424+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 12425+ if (unlikely(err))
4a4d8108
AM
12426+ goto out_dgrade;
12427+ }
12428+
c2b27bf2 12429+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
12430+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12431+ if (unlikely(err))
12432+ goto out_dgrade;
12433+
c2b27bf2 12434+ dbstart = au_dbstart(cpg.dentry);
c1595e42 12435+ if (dbstart <= cpg.bdst)
c2b27bf2 12436+ cpg.bsrc = cpg.bdst;
027c5e7a 12437+
c2b27bf2
AM
12438+ if (dbstart <= cpg.bdst /* just reopen */
12439+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 12440+ ) {
392086de 12441+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 12442+ if (IS_ERR(h_file))
027c5e7a 12443+ err = PTR_ERR(h_file);
86dc4139 12444+ else {
027c5e7a 12445+ di_downgrade_lock(parent, AuLock_IR);
c2b27bf2
AM
12446+ if (dbstart > cpg.bdst)
12447+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
12448+ if (!err)
12449+ err = au_reopen_nondir(file);
c2b27bf2 12450+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 12451+ }
027c5e7a
AM
12452+ } else { /* copyup as wh and reopen */
12453+ /*
12454+ * since writable hfsplus branch is not supported,
12455+ * h_open_pre/post() are unnecessary.
12456+ */
c2b27bf2 12457+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 12458+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 12459+ }
4a4d8108
AM
12460+
12461+ if (!err) {
12462+ au_pin_set_parent_lflag(pin, /*lflag*/0);
12463+ goto out_dput; /* success */
12464+ }
12465+ au_unpin(pin);
12466+ goto out_unlock;
1facf9fc 12467+
4f0767ce 12468+out_dgrade:
4a4d8108 12469+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 12470+out_unlock:
4a4d8108 12471+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12472+out_dput:
4a4d8108 12473+ dput(parent);
4f0767ce 12474+out:
1facf9fc 12475+ return err;
12476+}
12477+
4a4d8108
AM
12478+/* ---------------------------------------------------------------------- */
12479+
12480+int au_do_flush(struct file *file, fl_owner_t id,
12481+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 12482+{
4a4d8108 12483+ int err;
1facf9fc 12484+ struct super_block *sb;
4a4d8108 12485+ struct inode *inode;
1facf9fc 12486+
c06a8ce3
AM
12487+ inode = file_inode(file);
12488+ sb = inode->i_sb;
4a4d8108
AM
12489+ si_noflush_read_lock(sb);
12490+ fi_read_lock(file);
b752ccd1 12491+ ii_read_lock_child(inode);
1facf9fc 12492+
4a4d8108
AM
12493+ err = flush(file, id);
12494+ au_cpup_attr_timesizes(inode);
1facf9fc 12495+
b752ccd1 12496+ ii_read_unlock(inode);
4a4d8108 12497+ fi_read_unlock(file);
1308ab2a 12498+ si_read_unlock(sb);
dece6358 12499+ return err;
1facf9fc 12500+}
12501+
4a4d8108
AM
12502+/* ---------------------------------------------------------------------- */
12503+
12504+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 12505+{
4a4d8108 12506+ int err;
4a4d8108
AM
12507+ struct au_pin pin;
12508+ struct au_finfo *finfo;
c2b27bf2 12509+ struct dentry *parent, *hi_wh;
4a4d8108 12510+ struct inode *inode;
1facf9fc 12511+ struct super_block *sb;
c2b27bf2 12512+ struct au_cp_generic cpg = {
2000de60 12513+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12514+ .bdst = -1,
12515+ .bsrc = -1,
12516+ .len = -1,
12517+ .pin = &pin,
12518+ .flags = AuCpup_DTIME
12519+ };
1facf9fc 12520+
4a4d8108
AM
12521+ FiMustWriteLock(file);
12522+
12523+ err = 0;
12524+ finfo = au_fi(file);
c2b27bf2 12525+ sb = cpg.dentry->d_sb;
5527c038 12526+ inode = d_inode(cpg.dentry);
c2b27bf2
AM
12527+ cpg.bdst = au_ibstart(inode);
12528+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 12529+ goto out;
dece6358 12530+
c2b27bf2
AM
12531+ parent = dget_parent(cpg.dentry);
12532+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 12533+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
12534+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12535+ cpg.bdst = err;
4a4d8108
AM
12536+ di_read_unlock(parent, !AuLock_IR);
12537+ if (unlikely(err < 0))
12538+ goto out_parent;
12539+ err = 0;
1facf9fc 12540+ }
1facf9fc 12541+
4a4d8108 12542+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 12543+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
12544+ if (!S_ISDIR(inode->i_mode)
12545+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 12546+ && au_plink_test(inode)
c2b27bf2
AM
12547+ && !d_unhashed(cpg.dentry)
12548+ && cpg.bdst < au_dbstart(cpg.dentry)) {
12549+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
12550+ if (unlikely(err))
12551+ goto out_unlock;
12552+
12553+ /* always superio. */
c2b27bf2 12554+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 12555+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 12556+ if (!err) {
c2b27bf2 12557+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
12558+ au_unpin(&pin);
12559+ }
4a4d8108
AM
12560+ } else if (hi_wh) {
12561+ /* already copied-up after unlink */
c2b27bf2 12562+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
12563+ *need_reopen = 0;
12564+ }
1facf9fc 12565+
4f0767ce 12566+out_unlock:
4a4d8108 12567+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12568+out_parent:
4a4d8108 12569+ dput(parent);
4f0767ce 12570+out:
1308ab2a 12571+ return err;
dece6358 12572+}
1facf9fc 12573+
4a4d8108 12574+static void au_do_refresh_dir(struct file *file)
dece6358 12575+{
4a4d8108
AM
12576+ aufs_bindex_t bindex, bend, new_bindex, brid;
12577+ struct au_hfile *p, tmp, *q;
12578+ struct au_finfo *finfo;
1308ab2a 12579+ struct super_block *sb;
4a4d8108 12580+ struct au_fidir *fidir;
1facf9fc 12581+
4a4d8108 12582+ FiMustWriteLock(file);
1facf9fc 12583+
2000de60 12584+ sb = file->f_path.dentry->d_sb;
4a4d8108
AM
12585+ finfo = au_fi(file);
12586+ fidir = finfo->fi_hdir;
12587+ AuDebugOn(!fidir);
12588+ p = fidir->fd_hfile + finfo->fi_btop;
12589+ brid = p->hf_br->br_id;
12590+ bend = fidir->fd_bbot;
12591+ for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
12592+ if (!p->hf_file)
12593+ continue;
1308ab2a 12594+
4a4d8108
AM
12595+ new_bindex = au_br_index(sb, p->hf_br->br_id);
12596+ if (new_bindex == bindex)
12597+ continue;
12598+ if (new_bindex < 0) {
12599+ au_set_h_fptr(file, bindex, NULL);
12600+ continue;
12601+ }
1308ab2a 12602+
4a4d8108
AM
12603+ /* swap two lower inode, and loop again */
12604+ q = fidir->fd_hfile + new_bindex;
12605+ tmp = *q;
12606+ *q = *p;
12607+ *p = tmp;
12608+ if (tmp.hf_file) {
12609+ bindex--;
12610+ p--;
12611+ }
12612+ }
1308ab2a 12613+
4a4d8108 12614+ p = fidir->fd_hfile;
2000de60 12615+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) {
4a4d8108
AM
12616+ bend = au_sbend(sb);
12617+ for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
12618+ finfo->fi_btop++, p++)
12619+ if (p->hf_file) {
c06a8ce3 12620+ if (file_inode(p->hf_file))
4a4d8108 12621+ break;
c1595e42 12622+ au_hfput(p, file);
4a4d8108
AM
12623+ }
12624+ } else {
12625+ bend = au_br_index(sb, brid);
12626+ for (finfo->fi_btop = 0; finfo->fi_btop < bend;
12627+ finfo->fi_btop++, p++)
12628+ if (p->hf_file)
12629+ au_hfput(p, file);
12630+ bend = au_sbend(sb);
12631+ }
1308ab2a 12632+
4a4d8108
AM
12633+ p = fidir->fd_hfile + bend;
12634+ for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
12635+ fidir->fd_bbot--, p--)
12636+ if (p->hf_file) {
c06a8ce3 12637+ if (file_inode(p->hf_file))
4a4d8108 12638+ break;
c1595e42 12639+ au_hfput(p, file);
4a4d8108
AM
12640+ }
12641+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 12642+}
12643+
4a4d8108
AM
12644+/*
12645+ * after branch manipulating, refresh the file.
12646+ */
12647+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 12648+{
4a4d8108
AM
12649+ int err, need_reopen;
12650+ aufs_bindex_t bend, bindex;
12651+ struct dentry *dentry;
1308ab2a 12652+ struct au_finfo *finfo;
4a4d8108 12653+ struct au_hfile *hfile;
1facf9fc 12654+
2000de60 12655+ dentry = file->f_path.dentry;
1308ab2a 12656+ finfo = au_fi(file);
4a4d8108
AM
12657+ if (!finfo->fi_hdir) {
12658+ hfile = &finfo->fi_htop;
12659+ AuDebugOn(!hfile->hf_file);
12660+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
12661+ AuDebugOn(bindex < 0);
12662+ if (bindex != finfo->fi_btop)
12663+ au_set_fbstart(file, bindex);
12664+ } else {
12665+ err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
12666+ if (unlikely(err))
12667+ goto out;
12668+ au_do_refresh_dir(file);
12669+ }
1facf9fc 12670+
4a4d8108
AM
12671+ err = 0;
12672+ need_reopen = 1;
12673+ if (!au_test_mmapped(file))
12674+ err = au_file_refresh_by_inode(file, &need_reopen);
027c5e7a 12675+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
12676+ err = reopen(file);
12677+ if (!err) {
12678+ au_update_figen(file);
12679+ goto out; /* success */
12680+ }
12681+
12682+ /* error, close all lower files */
12683+ if (finfo->fi_hdir) {
12684+ bend = au_fbend_dir(file);
12685+ for (bindex = au_fbstart(file); bindex <= bend; bindex++)
12686+ au_set_h_fptr(file, bindex, NULL);
12687+ }
1facf9fc 12688+
4f0767ce 12689+out:
1facf9fc 12690+ return err;
12691+}
12692+
4a4d8108
AM
12693+/* common function to regular file and dir */
12694+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
12695+ int wlock)
dece6358 12696+{
1308ab2a 12697+ int err;
4a4d8108
AM
12698+ unsigned int sigen, figen;
12699+ aufs_bindex_t bstart;
12700+ unsigned char pseudo_link;
12701+ struct dentry *dentry;
12702+ struct inode *inode;
1facf9fc 12703+
4a4d8108 12704+ err = 0;
2000de60 12705+ dentry = file->f_path.dentry;
5527c038 12706+ inode = d_inode(dentry);
4a4d8108
AM
12707+ sigen = au_sigen(dentry->d_sb);
12708+ fi_write_lock(file);
12709+ figen = au_figen(file);
12710+ di_write_lock_child(dentry);
12711+ bstart = au_dbstart(dentry);
12712+ pseudo_link = (bstart != au_ibstart(inode));
12713+ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
12714+ if (!wlock) {
12715+ di_downgrade_lock(dentry, AuLock_IR);
12716+ fi_downgrade_lock(file);
12717+ }
12718+ goto out; /* success */
12719+ }
dece6358 12720+
4a4d8108 12721+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 12722+ if (au_digen_test(dentry, sigen)) {
4a4d8108 12723+ err = au_reval_dpath(dentry, sigen);
027c5e7a 12724+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 12725+ }
dece6358 12726+
027c5e7a
AM
12727+ if (!err)
12728+ err = refresh_file(file, reopen);
4a4d8108
AM
12729+ if (!err) {
12730+ if (!wlock) {
12731+ di_downgrade_lock(dentry, AuLock_IR);
12732+ fi_downgrade_lock(file);
12733+ }
12734+ } else {
12735+ di_write_unlock(dentry);
12736+ fi_write_unlock(file);
12737+ }
1facf9fc 12738+
4f0767ce 12739+out:
1308ab2a 12740+ return err;
12741+}
1facf9fc 12742+
4a4d8108
AM
12743+/* ---------------------------------------------------------------------- */
12744+
12745+/* cf. aufs_nopage() */
12746+/* for madvise(2) */
12747+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 12748+{
4a4d8108
AM
12749+ unlock_page(page);
12750+ return 0;
12751+}
1facf9fc 12752+
4a4d8108 12753+/* it will never be called, but necessary to support O_DIRECT */
5527c038
JR
12754+static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
12755+ loff_t offset)
4a4d8108 12756+{ BUG(); return 0; }
1facf9fc 12757+
4a4d8108
AM
12758+/* they will never be called. */
12759+#ifdef CONFIG_AUFS_DEBUG
12760+static int aufs_write_begin(struct file *file, struct address_space *mapping,
12761+ loff_t pos, unsigned len, unsigned flags,
12762+ struct page **pagep, void **fsdata)
12763+{ AuUnsupport(); return 0; }
12764+static int aufs_write_end(struct file *file, struct address_space *mapping,
12765+ loff_t pos, unsigned len, unsigned copied,
12766+ struct page *page, void *fsdata)
12767+{ AuUnsupport(); return 0; }
12768+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
12769+{ AuUnsupport(); return 0; }
1308ab2a 12770+
4a4d8108
AM
12771+static int aufs_set_page_dirty(struct page *page)
12772+{ AuUnsupport(); return 0; }
392086de
AM
12773+static void aufs_invalidatepage(struct page *page, unsigned int offset,
12774+ unsigned int length)
4a4d8108
AM
12775+{ AuUnsupport(); }
12776+static int aufs_releasepage(struct page *page, gfp_t gfp)
12777+{ AuUnsupport(); return 0; }
79b8bda9 12778+#if 0 /* called by memory compaction regardless file */
4a4d8108 12779+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 12780+ struct page *page, enum migrate_mode mode)
4a4d8108 12781+{ AuUnsupport(); return 0; }
79b8bda9 12782+#endif
4a4d8108
AM
12783+static int aufs_launder_page(struct page *page)
12784+{ AuUnsupport(); return 0; }
12785+static int aufs_is_partially_uptodate(struct page *page,
38d290e6
JR
12786+ unsigned long from,
12787+ unsigned long count)
4a4d8108 12788+{ AuUnsupport(); return 0; }
392086de
AM
12789+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
12790+ bool *writeback)
12791+{ AuUnsupport(); }
4a4d8108
AM
12792+static int aufs_error_remove_page(struct address_space *mapping,
12793+ struct page *page)
12794+{ AuUnsupport(); return 0; }
b4510431
AM
12795+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
12796+ sector_t *span)
12797+{ AuUnsupport(); return 0; }
12798+static void aufs_swap_deactivate(struct file *file)
12799+{ AuUnsupport(); }
4a4d8108
AM
12800+#endif /* CONFIG_AUFS_DEBUG */
12801+
12802+const struct address_space_operations aufs_aop = {
12803+ .readpage = aufs_readpage,
12804+ .direct_IO = aufs_direct_IO,
4a4d8108
AM
12805+#ifdef CONFIG_AUFS_DEBUG
12806+ .writepage = aufs_writepage,
4a4d8108
AM
12807+ /* no writepages, because of writepage */
12808+ .set_page_dirty = aufs_set_page_dirty,
12809+ /* no readpages, because of readpage */
12810+ .write_begin = aufs_write_begin,
12811+ .write_end = aufs_write_end,
12812+ /* no bmap, no block device */
12813+ .invalidatepage = aufs_invalidatepage,
12814+ .releasepage = aufs_releasepage,
79b8bda9
AM
12815+ /* is fallback_migrate_page ok? */
12816+ /* .migratepage = aufs_migratepage, */
4a4d8108
AM
12817+ .launder_page = aufs_launder_page,
12818+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 12819+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
12820+ .error_remove_page = aufs_error_remove_page,
12821+ .swap_activate = aufs_swap_activate,
12822+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 12823+#endif /* CONFIG_AUFS_DEBUG */
dece6358 12824+};
7f207e10
AM
12825diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
12826--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 12827+++ linux/fs/aufs/file.h 2015-09-24 10:47:58.251386326 +0200
b912730e 12828@@ -0,0 +1,291 @@
4a4d8108 12829+/*
2000de60 12830+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
12831+ *
12832+ * This program, aufs is free software; you can redistribute it and/or modify
12833+ * it under the terms of the GNU General Public License as published by
12834+ * the Free Software Foundation; either version 2 of the License, or
12835+ * (at your option) any later version.
12836+ *
12837+ * This program is distributed in the hope that it will be useful,
12838+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12839+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12840+ * GNU General Public License for more details.
12841+ *
12842+ * You should have received a copy of the GNU General Public License
523b37e3 12843+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 12844+ */
1facf9fc 12845+
4a4d8108
AM
12846+/*
12847+ * file operations
12848+ */
1facf9fc 12849+
4a4d8108
AM
12850+#ifndef __AUFS_FILE_H__
12851+#define __AUFS_FILE_H__
1facf9fc 12852+
4a4d8108 12853+#ifdef __KERNEL__
1facf9fc 12854+
2cbb1c4b 12855+#include <linux/file.h>
4a4d8108
AM
12856+#include <linux/fs.h>
12857+#include <linux/poll.h>
4a4d8108 12858+#include "rwsem.h"
1facf9fc 12859+
4a4d8108
AM
12860+struct au_branch;
12861+struct au_hfile {
12862+ struct file *hf_file;
12863+ struct au_branch *hf_br;
12864+};
1facf9fc 12865+
4a4d8108
AM
12866+struct au_vdir;
12867+struct au_fidir {
12868+ aufs_bindex_t fd_bbot;
12869+ aufs_bindex_t fd_nent;
12870+ struct au_vdir *fd_vdir_cache;
12871+ struct au_hfile fd_hfile[];
12872+};
1facf9fc 12873+
4a4d8108 12874+static inline int au_fidir_sz(int nent)
dece6358 12875+{
4f0767ce
JR
12876+ AuDebugOn(nent < 0);
12877+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 12878+}
1facf9fc 12879+
4a4d8108
AM
12880+struct au_finfo {
12881+ atomic_t fi_generation;
dece6358 12882+
4a4d8108
AM
12883+ struct au_rwsem fi_rwsem;
12884+ aufs_bindex_t fi_btop;
12885+
12886+ /* do not union them */
12887+ struct { /* for non-dir */
12888+ struct au_hfile fi_htop;
2cbb1c4b 12889+ atomic_t fi_mmapped;
4a4d8108
AM
12890+ };
12891+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3
AM
12892+
12893+ struct hlist_node fi_hlist;
12894+ struct file *fi_file; /* very ugly */
4a4d8108 12895+} ____cacheline_aligned_in_smp;
1facf9fc 12896+
4a4d8108 12897+/* ---------------------------------------------------------------------- */
1facf9fc 12898+
4a4d8108
AM
12899+/* file.c */
12900+extern const struct address_space_operations aufs_aop;
12901+unsigned int au_file_roflags(unsigned int flags);
12902+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 12903+ struct file *file, int force_wr);
b912730e
AM
12904+struct au_do_open_args {
12905+ int no_lock;
12906+ int (*open)(struct file *file, int flags,
12907+ struct file *h_file);
12908+ struct au_fidir *fidir;
12909+ struct file *h_file;
12910+};
12911+int au_do_open(struct file *file, struct au_do_open_args *args);
4a4d8108
AM
12912+int au_reopen_nondir(struct file *file);
12913+struct au_pin;
12914+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
12915+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
12916+ int wlock);
12917+int au_do_flush(struct file *file, fl_owner_t id,
12918+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 12919+
4a4d8108
AM
12920+/* poll.c */
12921+#ifdef CONFIG_AUFS_POLL
12922+unsigned int aufs_poll(struct file *file, poll_table *wait);
12923+#endif
1facf9fc 12924+
4a4d8108
AM
12925+#ifdef CONFIG_AUFS_BR_HFSPLUS
12926+/* hfsplus.c */
392086de
AM
12927+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
12928+ int force_wr);
4a4d8108
AM
12929+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
12930+ struct file *h_file);
12931+#else
c1595e42
JR
12932+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
12933+ aufs_bindex_t bindex, int force_wr)
4a4d8108
AM
12934+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
12935+ struct file *h_file);
12936+#endif
1facf9fc 12937+
4a4d8108
AM
12938+/* f_op.c */
12939+extern const struct file_operations aufs_file_fop;
b912730e 12940+int au_do_open_nondir(struct file *file, int flags, struct file *h_file);
4a4d8108 12941+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
b912730e 12942+struct file *au_read_pre(struct file *file, int keep_fi);
4a4d8108 12943+
4a4d8108
AM
12944+/* finfo.c */
12945+void au_hfput(struct au_hfile *hf, struct file *file);
12946+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
12947+ struct file *h_file);
1facf9fc 12948+
4a4d8108 12949+void au_update_figen(struct file *file);
4a4d8108
AM
12950+struct au_fidir *au_fidir_alloc(struct super_block *sb);
12951+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
1facf9fc 12952+
4a4d8108
AM
12953+void au_fi_init_once(void *_fi);
12954+void au_finfo_fin(struct file *file);
12955+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 12956+
4a4d8108
AM
12957+/* ioctl.c */
12958+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
12959+#ifdef CONFIG_COMPAT
12960+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
12961+ unsigned long arg);
c2b27bf2
AM
12962+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
12963+ unsigned long arg);
b752ccd1 12964+#endif
1facf9fc 12965+
4a4d8108 12966+/* ---------------------------------------------------------------------- */
1facf9fc 12967+
4a4d8108
AM
12968+static inline struct au_finfo *au_fi(struct file *file)
12969+{
38d290e6 12970+ return file->private_data;
4a4d8108 12971+}
1facf9fc 12972+
4a4d8108 12973+/* ---------------------------------------------------------------------- */
1facf9fc 12974+
4a4d8108
AM
12975+/*
12976+ * fi_read_lock, fi_write_lock,
12977+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
12978+ */
12979+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 12980+
4a4d8108
AM
12981+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
12982+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
12983+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 12984+
1308ab2a 12985+/* ---------------------------------------------------------------------- */
12986+
4a4d8108
AM
12987+/* todo: hard/soft set? */
12988+static inline aufs_bindex_t au_fbstart(struct file *file)
dece6358 12989+{
4a4d8108
AM
12990+ FiMustAnyLock(file);
12991+ return au_fi(file)->fi_btop;
12992+}
dece6358 12993+
4a4d8108
AM
12994+static inline aufs_bindex_t au_fbend_dir(struct file *file)
12995+{
12996+ FiMustAnyLock(file);
12997+ AuDebugOn(!au_fi(file)->fi_hdir);
12998+ return au_fi(file)->fi_hdir->fd_bbot;
12999+}
1facf9fc 13000+
4a4d8108
AM
13001+static inline struct au_vdir *au_fvdir_cache(struct file *file)
13002+{
13003+ FiMustAnyLock(file);
13004+ AuDebugOn(!au_fi(file)->fi_hdir);
13005+ return au_fi(file)->fi_hdir->fd_vdir_cache;
13006+}
1facf9fc 13007+
4a4d8108
AM
13008+static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
13009+{
13010+ FiMustWriteLock(file);
13011+ au_fi(file)->fi_btop = bindex;
13012+}
1facf9fc 13013+
4a4d8108
AM
13014+static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
13015+{
13016+ FiMustWriteLock(file);
13017+ AuDebugOn(!au_fi(file)->fi_hdir);
13018+ au_fi(file)->fi_hdir->fd_bbot = bindex;
13019+}
1308ab2a 13020+
4a4d8108
AM
13021+static inline void au_set_fvdir_cache(struct file *file,
13022+ struct au_vdir *vdir_cache)
13023+{
13024+ FiMustWriteLock(file);
13025+ AuDebugOn(!au_fi(file)->fi_hdir);
13026+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
13027+}
dece6358 13028+
4a4d8108
AM
13029+static inline struct file *au_hf_top(struct file *file)
13030+{
13031+ FiMustAnyLock(file);
13032+ AuDebugOn(au_fi(file)->fi_hdir);
13033+ return au_fi(file)->fi_htop.hf_file;
13034+}
1facf9fc 13035+
4a4d8108
AM
13036+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
13037+{
13038+ FiMustAnyLock(file);
13039+ AuDebugOn(!au_fi(file)->fi_hdir);
13040+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
13041+}
13042+
4a4d8108
AM
13043+/* todo: memory barrier? */
13044+static inline unsigned int au_figen(struct file *f)
dece6358 13045+{
4a4d8108
AM
13046+ return atomic_read(&au_fi(f)->fi_generation);
13047+}
dece6358 13048+
2cbb1c4b
JR
13049+static inline void au_set_mmapped(struct file *f)
13050+{
13051+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
13052+ return;
0c3ec466 13053+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
13054+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
13055+ ;
13056+}
13057+
13058+static inline void au_unset_mmapped(struct file *f)
13059+{
13060+ atomic_dec(&au_fi(f)->fi_mmapped);
13061+}
13062+
4a4d8108
AM
13063+static inline int au_test_mmapped(struct file *f)
13064+{
2cbb1c4b
JR
13065+ return atomic_read(&au_fi(f)->fi_mmapped);
13066+}
13067+
13068+/* customize vma->vm_file */
13069+
13070+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
13071+ struct file *file)
13072+{
53392da6
AM
13073+ struct file *f;
13074+
13075+ f = vma->vm_file;
2cbb1c4b
JR
13076+ get_file(file);
13077+ vma->vm_file = file;
53392da6 13078+ fput(f);
2cbb1c4b
JR
13079+}
13080+
13081+#ifdef CONFIG_MMU
13082+#define AuDbgVmRegion(file, vma) do {} while (0)
13083+
13084+static inline void au_vm_file_reset(struct vm_area_struct *vma,
13085+ struct file *file)
13086+{
13087+ au_do_vm_file_reset(vma, file);
13088+}
13089+#else
13090+#define AuDbgVmRegion(file, vma) \
13091+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
13092+
13093+static inline void au_vm_file_reset(struct vm_area_struct *vma,
13094+ struct file *file)
13095+{
53392da6
AM
13096+ struct file *f;
13097+
2cbb1c4b 13098+ au_do_vm_file_reset(vma, file);
53392da6 13099+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
13100+ get_file(file);
13101+ vma->vm_region->vm_file = file;
53392da6 13102+ fput(f);
2cbb1c4b
JR
13103+}
13104+#endif /* CONFIG_MMU */
13105+
13106+/* handle vma->vm_prfile */
fb47a38f 13107+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
13108+ struct file *file)
13109+{
2cbb1c4b
JR
13110+ get_file(file);
13111+ vma->vm_prfile = file;
13112+#ifndef CONFIG_MMU
13113+ get_file(file);
13114+ vma->vm_region->vm_prfile = file;
13115+#endif
fb47a38f 13116+}
1308ab2a 13117+
4a4d8108
AM
13118+#endif /* __KERNEL__ */
13119+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
13120diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
13121--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 13122+++ linux/fs/aufs/finfo.c 2015-09-24 10:47:58.251386326 +0200
b912730e 13123@@ -0,0 +1,157 @@
4a4d8108 13124+/*
2000de60 13125+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
13126+ *
13127+ * This program, aufs is free software; you can redistribute it and/or modify
13128+ * it under the terms of the GNU General Public License as published by
13129+ * the Free Software Foundation; either version 2 of the License, or
13130+ * (at your option) any later version.
13131+ *
13132+ * This program is distributed in the hope that it will be useful,
13133+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13134+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13135+ * GNU General Public License for more details.
13136+ *
13137+ * You should have received a copy of the GNU General Public License
523b37e3 13138+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 13139+ */
1308ab2a 13140+
4a4d8108
AM
13141+/*
13142+ * file private data
13143+ */
1facf9fc 13144+
4a4d8108 13145+#include "aufs.h"
1facf9fc 13146+
4a4d8108
AM
13147+void au_hfput(struct au_hfile *hf, struct file *file)
13148+{
13149+ /* todo: direct access f_flags */
2cbb1c4b 13150+ if (vfsub_file_flags(file) & __FMODE_EXEC)
4a4d8108
AM
13151+ allow_write_access(hf->hf_file);
13152+ fput(hf->hf_file);
13153+ hf->hf_file = NULL;
e49829fe 13154+ atomic_dec(&hf->hf_br->br_count);
4a4d8108
AM
13155+ hf->hf_br = NULL;
13156+}
1facf9fc 13157+
4a4d8108
AM
13158+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
13159+{
13160+ struct au_finfo *finfo = au_fi(file);
13161+ struct au_hfile *hf;
13162+ struct au_fidir *fidir;
13163+
13164+ fidir = finfo->fi_hdir;
13165+ if (!fidir) {
13166+ AuDebugOn(finfo->fi_btop != bindex);
13167+ hf = &finfo->fi_htop;
13168+ } else
13169+ hf = fidir->fd_hfile + bindex;
13170+
13171+ if (hf && hf->hf_file)
13172+ au_hfput(hf, file);
13173+ if (val) {
13174+ FiMustWriteLock(file);
b912730e 13175+ AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry));
4a4d8108 13176+ hf->hf_file = val;
2000de60 13177+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex);
1308ab2a 13178+ }
4a4d8108 13179+}
1facf9fc 13180+
4a4d8108
AM
13181+void au_update_figen(struct file *file)
13182+{
2000de60 13183+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry));
4a4d8108 13184+ /* smp_mb(); */ /* atomic_set */
1facf9fc 13185+}
13186+
4a4d8108
AM
13187+/* ---------------------------------------------------------------------- */
13188+
4a4d8108
AM
13189+struct au_fidir *au_fidir_alloc(struct super_block *sb)
13190+{
13191+ struct au_fidir *fidir;
13192+ int nbr;
13193+
13194+ nbr = au_sbend(sb) + 1;
13195+ if (nbr < 2)
13196+ nbr = 2; /* initial allocate for 2 branches */
13197+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
13198+ if (fidir) {
13199+ fidir->fd_bbot = -1;
13200+ fidir->fd_nent = nbr;
13201+ fidir->fd_vdir_cache = NULL;
13202+ }
13203+
13204+ return fidir;
13205+}
13206+
13207+int au_fidir_realloc(struct au_finfo *finfo, int nbr)
13208+{
13209+ int err;
13210+ struct au_fidir *fidir, *p;
13211+
13212+ AuRwMustWriteLock(&finfo->fi_rwsem);
13213+ fidir = finfo->fi_hdir;
13214+ AuDebugOn(!fidir);
13215+
13216+ err = -ENOMEM;
13217+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
13218+ GFP_NOFS);
13219+ if (p) {
13220+ p->fd_nent = nbr;
13221+ finfo->fi_hdir = p;
13222+ err = 0;
13223+ }
1facf9fc 13224+
dece6358 13225+ return err;
1facf9fc 13226+}
1308ab2a 13227+
13228+/* ---------------------------------------------------------------------- */
13229+
4a4d8108 13230+void au_finfo_fin(struct file *file)
1308ab2a 13231+{
4a4d8108
AM
13232+ struct au_finfo *finfo;
13233+
2000de60 13234+ au_nfiles_dec(file->f_path.dentry->d_sb);
7f207e10 13235+
4a4d8108
AM
13236+ finfo = au_fi(file);
13237+ AuDebugOn(finfo->fi_hdir);
13238+ AuRwDestroy(&finfo->fi_rwsem);
13239+ au_cache_free_finfo(finfo);
1308ab2a 13240+}
1308ab2a 13241+
e49829fe 13242+void au_fi_init_once(void *_finfo)
4a4d8108 13243+{
e49829fe 13244+ struct au_finfo *finfo = _finfo;
2cbb1c4b 13245+ static struct lock_class_key aufs_fi;
1308ab2a 13246+
e49829fe
JR
13247+ au_rw_init(&finfo->fi_rwsem);
13248+ au_rw_class(&finfo->fi_rwsem, &aufs_fi);
4a4d8108 13249+}
1308ab2a 13250+
4a4d8108
AM
13251+int au_finfo_init(struct file *file, struct au_fidir *fidir)
13252+{
1716fcea 13253+ int err;
4a4d8108
AM
13254+ struct au_finfo *finfo;
13255+ struct dentry *dentry;
13256+
13257+ err = -ENOMEM;
2000de60 13258+ dentry = file->f_path.dentry;
4a4d8108
AM
13259+ finfo = au_cache_alloc_finfo();
13260+ if (unlikely(!finfo))
13261+ goto out;
13262+
13263+ err = 0;
7f207e10 13264+ au_nfiles_inc(dentry->d_sb);
1716fcea
AM
13265+ /* verbose coding for lock class name */
13266+ if (!fidir)
13267+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
13268+ else
13269+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
4a4d8108
AM
13270+ au_rw_write_lock(&finfo->fi_rwsem);
13271+ finfo->fi_btop = -1;
13272+ finfo->fi_hdir = fidir;
13273+ atomic_set(&finfo->fi_generation, au_digen(dentry));
13274+ /* smp_mb(); */ /* atomic_set */
13275+
13276+ file->private_data = finfo;
13277+
13278+out:
13279+ return err;
13280+}
7f207e10
AM
13281diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
13282--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 13283+++ linux/fs/aufs/f_op.c 2015-09-24 10:47:58.251386326 +0200
5527c038 13284@@ -0,0 +1,738 @@
dece6358 13285+/*
2000de60 13286+ * Copyright (C) 2005-2015 Junjiro R. Okajima
dece6358
AM
13287+ *
13288+ * This program, aufs is free software; you can redistribute it and/or modify
13289+ * it under the terms of the GNU General Public License as published by
13290+ * the Free Software Foundation; either version 2 of the License, or
13291+ * (at your option) any later version.
13292+ *
13293+ * This program is distributed in the hope that it will be useful,
13294+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13295+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13296+ * GNU General Public License for more details.
13297+ *
13298+ * You should have received a copy of the GNU General Public License
523b37e3 13299+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 13300+ */
1facf9fc 13301+
13302+/*
4a4d8108 13303+ * file and vm operations
1facf9fc 13304+ */
dece6358 13305+
86dc4139 13306+#include <linux/aio.h>
4a4d8108
AM
13307+#include <linux/fs_stack.h>
13308+#include <linux/mman.h>
4a4d8108 13309+#include <linux/security.h>
dece6358
AM
13310+#include "aufs.h"
13311+
b912730e 13312+int au_do_open_nondir(struct file *file, int flags, struct file *h_file)
1facf9fc 13313+{
4a4d8108
AM
13314+ int err;
13315+ aufs_bindex_t bindex;
4a4d8108
AM
13316+ struct dentry *dentry;
13317+ struct au_finfo *finfo;
38d290e6 13318+ struct inode *h_inode;
4a4d8108
AM
13319+
13320+ FiMustWriteLock(file);
13321+
523b37e3 13322+ err = 0;
2000de60 13323+ dentry = file->f_path.dentry;
b912730e 13324+ AuDebugOn(IS_ERR_OR_NULL(dentry));
4a4d8108
AM
13325+ finfo = au_fi(file);
13326+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 13327+ atomic_set(&finfo->fi_mmapped, 0);
4a4d8108 13328+ bindex = au_dbstart(dentry);
b912730e
AM
13329+ if (!h_file)
13330+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
13331+ else
13332+ get_file(h_file);
4a4d8108
AM
13333+ if (IS_ERR(h_file))
13334+ err = PTR_ERR(h_file);
13335+ else {
38d290e6
JR
13336+ if ((flags & __O_TMPFILE)
13337+ && !(flags & O_EXCL)) {
13338+ h_inode = file_inode(h_file);
13339+ spin_lock(&h_inode->i_lock);
13340+ h_inode->i_state |= I_LINKABLE;
13341+ spin_unlock(&h_inode->i_lock);
13342+ }
4a4d8108
AM
13343+ au_set_fbstart(file, bindex);
13344+ au_set_h_fptr(file, bindex, h_file);
13345+ au_update_figen(file);
13346+ /* todo: necessary? */
13347+ /* file->f_ra = h_file->f_ra; */
13348+ }
027c5e7a 13349+
4a4d8108 13350+ return err;
1facf9fc 13351+}
13352+
4a4d8108
AM
13353+static int aufs_open_nondir(struct inode *inode __maybe_unused,
13354+ struct file *file)
1facf9fc 13355+{
4a4d8108 13356+ int err;
1308ab2a 13357+ struct super_block *sb;
b912730e
AM
13358+ struct au_do_open_args args = {
13359+ .open = au_do_open_nondir
13360+ };
1facf9fc 13361+
523b37e3
AM
13362+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
13363+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 13364+
2000de60 13365+ sb = file->f_path.dentry->d_sb;
4a4d8108 13366+ si_read_lock(sb, AuLock_FLUSH);
b912730e 13367+ err = au_do_open(file, &args);
4a4d8108
AM
13368+ si_read_unlock(sb);
13369+ return err;
13370+}
1facf9fc 13371+
4a4d8108
AM
13372+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
13373+{
13374+ struct au_finfo *finfo;
13375+ aufs_bindex_t bindex;
1facf9fc 13376+
4a4d8108 13377+ finfo = au_fi(file);
2000de60
JR
13378+ au_sphl_del(&finfo->fi_hlist,
13379+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108 13380+ bindex = finfo->fi_btop;
b4510431 13381+ if (bindex >= 0)
4a4d8108 13382+ au_set_h_fptr(file, bindex, NULL);
7f207e10 13383+
4a4d8108
AM
13384+ au_finfo_fin(file);
13385+ return 0;
1facf9fc 13386+}
13387+
4a4d8108
AM
13388+/* ---------------------------------------------------------------------- */
13389+
13390+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 13391+{
1308ab2a 13392+ int err;
4a4d8108
AM
13393+ struct file *h_file;
13394+
13395+ err = 0;
13396+ h_file = au_hf_top(file);
13397+ if (h_file)
13398+ err = vfsub_flush(h_file, id);
13399+ return err;
13400+}
13401+
13402+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
13403+{
13404+ return au_do_flush(file, id, au_do_flush_nondir);
13405+}
13406+
13407+/* ---------------------------------------------------------------------- */
9dbd164d
AM
13408+/*
13409+ * read and write functions acquire [fdi]_rwsem once, but release before
13410+ * mmap_sem. This is because to stop a race condition between mmap(2).
13411+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
13412+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
13413+ * read functions after [fdi]_rwsem are released, but it should be harmless.
13414+ */
4a4d8108 13415+
b912730e
AM
13416+/* Callers should call au_read_post() or fput() in the end */
13417+struct file *au_read_pre(struct file *file, int keep_fi)
4a4d8108 13418+{
4a4d8108 13419+ struct file *h_file;
b912730e 13420+ int err;
1facf9fc 13421+
4a4d8108 13422+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
b912730e
AM
13423+ if (!err) {
13424+ di_read_unlock(file->f_path.dentry, AuLock_IR);
13425+ h_file = au_hf_top(file);
13426+ get_file(h_file);
13427+ if (!keep_fi)
13428+ fi_read_unlock(file);
13429+ } else
13430+ h_file = ERR_PTR(err);
13431+
13432+ return h_file;
13433+}
13434+
13435+static void au_read_post(struct inode *inode, struct file *h_file)
13436+{
13437+ /* update without lock, I don't think it a problem */
13438+ fsstack_copy_attr_atime(inode, file_inode(h_file));
13439+ fput(h_file);
13440+}
13441+
13442+struct au_write_pre {
13443+ blkcnt_t blks;
13444+ aufs_bindex_t bstart;
13445+};
13446+
13447+/*
13448+ * return with iinfo is write-locked
13449+ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the
13450+ * end
13451+ */
13452+static struct file *au_write_pre(struct file *file, int do_ready,
13453+ struct au_write_pre *wpre)
13454+{
13455+ struct file *h_file;
13456+ struct dentry *dentry;
13457+ int err;
13458+ struct au_pin pin;
13459+
13460+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13461+ h_file = ERR_PTR(err);
dece6358
AM
13462+ if (unlikely(err))
13463+ goto out;
1facf9fc 13464+
b912730e
AM
13465+ dentry = file->f_path.dentry;
13466+ if (do_ready) {
13467+ err = au_ready_to_write(file, -1, &pin);
13468+ if (unlikely(err)) {
13469+ h_file = ERR_PTR(err);
13470+ di_write_unlock(dentry);
13471+ goto out_fi;
13472+ }
13473+ }
13474+
13475+ di_downgrade_lock(dentry, /*flags*/0);
13476+ if (wpre)
13477+ wpre->bstart = au_fbstart(file);
4a4d8108 13478+ h_file = au_hf_top(file);
9dbd164d 13479+ get_file(h_file);
b912730e
AM
13480+ if (wpre)
13481+ wpre->blks = file_inode(h_file)->i_blocks;
13482+ if (do_ready)
13483+ au_unpin(&pin);
13484+ di_read_unlock(dentry, /*flags*/0);
13485+
13486+out_fi:
13487+ fi_write_unlock(file);
13488+out:
13489+ return h_file;
13490+}
13491+
13492+static void au_write_post(struct inode *inode, struct file *h_file,
13493+ struct au_write_pre *wpre, ssize_t written)
13494+{
13495+ struct inode *h_inode;
13496+
13497+ au_cpup_attr_timesizes(inode);
13498+ AuDebugOn(au_ibstart(inode) != wpre->bstart);
13499+ h_inode = file_inode(h_file);
13500+ inode->i_mode = h_inode->i_mode;
13501+ ii_write_unlock(inode);
13502+ fput(h_file);
13503+
13504+ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */
13505+ if (written > 0)
13506+ au_fhsm_wrote(inode->i_sb, wpre->bstart,
13507+ /*force*/h_inode->i_blocks > wpre->blks);
13508+}
13509+
13510+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
13511+ loff_t *ppos)
13512+{
13513+ ssize_t err;
13514+ struct inode *inode;
13515+ struct file *h_file;
13516+ struct super_block *sb;
13517+
13518+ inode = file_inode(file);
13519+ sb = inode->i_sb;
13520+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
13521+
13522+ h_file = au_read_pre(file, /*keep_fi*/0);
13523+ err = PTR_ERR(h_file);
13524+ if (IS_ERR(h_file))
13525+ goto out;
9dbd164d
AM
13526+
13527+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
13528+ err = vfsub_read_u(h_file, buf, count, ppos);
13529+ /* todo: necessary? */
13530+ /* file->f_ra = h_file->f_ra; */
b912730e 13531+ au_read_post(inode, h_file);
1308ab2a 13532+
4f0767ce 13533+out:
dece6358
AM
13534+ si_read_unlock(sb);
13535+ return err;
13536+}
1facf9fc 13537+
e49829fe
JR
13538+/*
13539+ * todo: very ugly
13540+ * it locks both of i_mutex and si_rwsem for read in safe.
13541+ * if the plink maintenance mode continues forever (that is the problem),
13542+ * may loop forever.
13543+ */
13544+static void au_mtx_and_read_lock(struct inode *inode)
13545+{
13546+ int err;
13547+ struct super_block *sb = inode->i_sb;
13548+
13549+ while (1) {
13550+ mutex_lock(&inode->i_mutex);
13551+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
13552+ if (!err)
13553+ break;
13554+ mutex_unlock(&inode->i_mutex);
13555+ si_read_lock(sb, AuLock_NOPLMW);
13556+ si_read_unlock(sb);
13557+ }
13558+}
13559+
4a4d8108
AM
13560+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
13561+ size_t count, loff_t *ppos)
dece6358 13562+{
4a4d8108 13563+ ssize_t err;
b912730e
AM
13564+ struct au_write_pre wpre;
13565+ struct inode *inode;
4a4d8108
AM
13566+ struct file *h_file;
13567+ char __user *buf = (char __user *)ubuf;
1facf9fc 13568+
b912730e 13569+ inode = file_inode(file);
e49829fe 13570+ au_mtx_and_read_lock(inode);
1facf9fc 13571+
b912730e
AM
13572+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
13573+ err = PTR_ERR(h_file);
13574+ if (IS_ERR(h_file))
9dbd164d 13575+ goto out;
9dbd164d 13576+
4a4d8108 13577+ err = vfsub_write_u(h_file, buf, count, ppos);
b912730e 13578+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 13579+
4f0767ce 13580+out:
b912730e 13581+ si_read_unlock(inode->i_sb);
4a4d8108 13582+ mutex_unlock(&inode->i_mutex);
dece6358
AM
13583+ return err;
13584+}
1facf9fc 13585+
076b876e
AM
13586+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
13587+ struct iov_iter *iov_iter)
dece6358 13588+{
4a4d8108
AM
13589+ ssize_t err;
13590+ struct file *file;
076b876e 13591+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
1facf9fc 13592+
4a4d8108
AM
13593+ err = security_file_permission(h_file, rw);
13594+ if (unlikely(err))
13595+ goto out;
1facf9fc 13596+
4a4d8108 13597+ err = -ENOSYS;
076b876e 13598+ iter = NULL;
5527c038 13599+ if (rw == MAY_READ)
076b876e 13600+ iter = h_file->f_op->read_iter;
5527c038 13601+ else if (rw == MAY_WRITE)
076b876e 13602+ iter = h_file->f_op->write_iter;
076b876e
AM
13603+
13604+ file = kio->ki_filp;
13605+ kio->ki_filp = h_file;
13606+ if (iter) {
2cbb1c4b 13607+ lockdep_off();
076b876e
AM
13608+ err = iter(kio, iov_iter);
13609+ lockdep_on();
4a4d8108
AM
13610+ } else
13611+ /* currently there is no such fs */
13612+ WARN_ON_ONCE(1);
076b876e 13613+ kio->ki_filp = file;
1facf9fc 13614+
4f0767ce 13615+out:
dece6358
AM
13616+ return err;
13617+}
1facf9fc 13618+
076b876e 13619+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1facf9fc 13620+{
4a4d8108
AM
13621+ ssize_t err;
13622+ struct file *file, *h_file;
b912730e 13623+ struct inode *inode;
dece6358 13624+ struct super_block *sb;
1facf9fc 13625+
4a4d8108 13626+ file = kio->ki_filp;
b912730e
AM
13627+ inode = file_inode(file);
13628+ sb = inode->i_sb;
e49829fe 13629+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 13630+
b912730e
AM
13631+ h_file = au_read_pre(file, /*keep_fi*/0);
13632+ err = PTR_ERR(h_file);
13633+ if (IS_ERR(h_file))
13634+ goto out;
9dbd164d 13635+
076b876e 13636+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
4a4d8108
AM
13637+ /* todo: necessary? */
13638+ /* file->f_ra = h_file->f_ra; */
b912730e 13639+ au_read_post(inode, h_file);
1facf9fc 13640+
4f0767ce 13641+out:
4a4d8108 13642+ si_read_unlock(sb);
1308ab2a 13643+ return err;
13644+}
1facf9fc 13645+
076b876e 13646+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1308ab2a 13647+{
4a4d8108 13648+ ssize_t err;
b912730e
AM
13649+ struct au_write_pre wpre;
13650+ struct inode *inode;
4a4d8108 13651+ struct file *file, *h_file;
1308ab2a 13652+
4a4d8108 13653+ file = kio->ki_filp;
b912730e 13654+ inode = file_inode(file);
e49829fe
JR
13655+ au_mtx_and_read_lock(inode);
13656+
b912730e
AM
13657+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
13658+ err = PTR_ERR(h_file);
13659+ if (IS_ERR(h_file))
9dbd164d 13660+ goto out;
9dbd164d 13661+
076b876e 13662+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
b912730e 13663+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 13664+
4f0767ce 13665+out:
b912730e 13666+ si_read_unlock(inode->i_sb);
4a4d8108 13667+ mutex_unlock(&inode->i_mutex);
dece6358 13668+ return err;
1facf9fc 13669+}
13670+
4a4d8108
AM
13671+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
13672+ struct pipe_inode_info *pipe, size_t len,
13673+ unsigned int flags)
1facf9fc 13674+{
4a4d8108
AM
13675+ ssize_t err;
13676+ struct file *h_file;
b912730e 13677+ struct inode *inode;
dece6358 13678+ struct super_block *sb;
1facf9fc 13679+
b912730e
AM
13680+ inode = file_inode(file);
13681+ sb = inode->i_sb;
e49829fe 13682+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e
AM
13683+
13684+ h_file = au_read_pre(file, /*keep_fi*/1);
13685+ err = PTR_ERR(h_file);
13686+ if (IS_ERR(h_file))
dece6358 13687+ goto out;
1facf9fc 13688+
4a4d8108 13689+ if (au_test_loopback_kthread()) {
2000de60 13690+ au_warn_loopback(h_file->f_path.dentry->d_sb);
87a755f4
AM
13691+ if (file->f_mapping != h_file->f_mapping) {
13692+ file->f_mapping = h_file->f_mapping;
13693+ smp_mb(); /* unnecessary? */
13694+ }
1308ab2a 13695+ }
9dbd164d
AM
13696+ fi_read_unlock(file);
13697+
4a4d8108
AM
13698+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
13699+ /* todo: necessasry? */
13700+ /* file->f_ra = h_file->f_ra; */
b912730e 13701+ au_read_post(inode, h_file);
1facf9fc 13702+
4f0767ce 13703+out:
4a4d8108 13704+ si_read_unlock(sb);
dece6358 13705+ return err;
1facf9fc 13706+}
13707+
4a4d8108
AM
13708+static ssize_t
13709+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
13710+ size_t len, unsigned int flags)
1facf9fc 13711+{
4a4d8108 13712+ ssize_t err;
b912730e
AM
13713+ struct au_write_pre wpre;
13714+ struct inode *inode;
076b876e 13715+ struct file *h_file;
1facf9fc 13716+
b912730e 13717+ inode = file_inode(file);
e49829fe 13718+ au_mtx_and_read_lock(inode);
9dbd164d 13719+
b912730e
AM
13720+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
13721+ err = PTR_ERR(h_file);
13722+ if (IS_ERR(h_file))
9dbd164d 13723+ goto out;
9dbd164d 13724+
4a4d8108 13725+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
b912730e 13726+ au_write_post(inode, h_file, &wpre, err);
1facf9fc 13727+
4f0767ce 13728+out:
b912730e 13729+ si_read_unlock(inode->i_sb);
4a4d8108
AM
13730+ mutex_unlock(&inode->i_mutex);
13731+ return err;
13732+}
1facf9fc 13733+
38d290e6
JR
13734+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
13735+ loff_t len)
13736+{
13737+ long err;
b912730e 13738+ struct au_write_pre wpre;
38d290e6
JR
13739+ struct inode *inode;
13740+ struct file *h_file;
13741+
b912730e 13742+ inode = file_inode(file);
38d290e6
JR
13743+ au_mtx_and_read_lock(inode);
13744+
b912730e
AM
13745+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
13746+ err = PTR_ERR(h_file);
13747+ if (IS_ERR(h_file))
38d290e6 13748+ goto out;
38d290e6
JR
13749+
13750+ lockdep_off();
03673fb0 13751+ err = vfs_fallocate(h_file, mode, offset, len);
38d290e6 13752+ lockdep_on();
b912730e 13753+ au_write_post(inode, h_file, &wpre, /*written*/1);
38d290e6
JR
13754+
13755+out:
b912730e 13756+ si_read_unlock(inode->i_sb);
38d290e6
JR
13757+ mutex_unlock(&inode->i_mutex);
13758+ return err;
13759+}
13760+
4a4d8108
AM
13761+/* ---------------------------------------------------------------------- */
13762+
9dbd164d
AM
13763+/*
13764+ * The locking order around current->mmap_sem.
13765+ * - in most and regular cases
13766+ * file I/O syscall -- aufs_read() or something
13767+ * -- si_rwsem for read -- mmap_sem
13768+ * (Note that [fdi]i_rwsem are released before mmap_sem).
13769+ * - in mmap case
13770+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
13771+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
13772+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
13773+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
13774+ * It means that when aufs acquires si_rwsem for write, the process should never
13775+ * acquire mmap_sem.
13776+ *
392086de 13777+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
13778+ * problem either since any directory is not able to be mmap-ed.
13779+ * The similar scenario is applied to aufs_readlink() too.
13780+ */
13781+
38d290e6 13782+#if 0 /* stop calling security_file_mmap() */
2dfbb274
AM
13783+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
13784+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
13785+
13786+static unsigned long au_arch_prot_conv(unsigned long flags)
13787+{
13788+ /* currently ppc64 only */
13789+#ifdef CONFIG_PPC64
13790+ /* cf. linux/arch/powerpc/include/asm/mman.h */
13791+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
13792+ return AuConv_VM_PROT(flags, SAO);
13793+#else
13794+ AuDebugOn(arch_calc_vm_prot_bits(-1));
13795+ return 0;
13796+#endif
13797+}
13798+
13799+static unsigned long au_prot_conv(unsigned long flags)
13800+{
13801+ return AuConv_VM_PROT(flags, READ)
13802+ | AuConv_VM_PROT(flags, WRITE)
13803+ | AuConv_VM_PROT(flags, EXEC)
13804+ | au_arch_prot_conv(flags);
13805+}
13806+
13807+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
13808+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
13809+
13810+static unsigned long au_flag_conv(unsigned long flags)
13811+{
13812+ return AuConv_VM_MAP(flags, GROWSDOWN)
13813+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
13814+ | AuConv_VM_MAP(flags, LOCKED);
13815+}
38d290e6 13816+#endif
2dfbb274 13817+
9dbd164d 13818+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 13819+{
4a4d8108 13820+ int err;
4a4d8108 13821+ const unsigned char wlock
9dbd164d 13822+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108 13823+ struct super_block *sb;
9dbd164d 13824+ struct file *h_file;
b912730e 13825+ struct inode *inode;
9dbd164d
AM
13826+
13827+ AuDbgVmRegion(file, vma);
1308ab2a 13828+
b912730e
AM
13829+ inode = file_inode(file);
13830+ sb = inode->i_sb;
9dbd164d 13831+ lockdep_off();
e49829fe 13832+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108 13833+
b912730e 13834+ h_file = au_write_pre(file, wlock, /*wpre*/NULL);
9dbd164d 13835+ lockdep_on();
b912730e
AM
13836+ err = PTR_ERR(h_file);
13837+ if (IS_ERR(h_file))
13838+ goto out;
1308ab2a 13839+
b912730e
AM
13840+ err = 0;
13841+ au_set_mmapped(file);
9dbd164d 13842+ au_vm_file_reset(vma, h_file);
38d290e6
JR
13843+ /*
13844+ * we cannot call security_mmap_file() here since it may acquire
13845+ * mmap_sem or i_mutex.
13846+ *
13847+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
13848+ * au_flag_conv(vma->vm_flags));
13849+ */
9dbd164d
AM
13850+ if (!err)
13851+ err = h_file->f_op->mmap(h_file, vma);
b912730e
AM
13852+ if (!err) {
13853+ au_vm_prfile_set(vma, file);
13854+ fsstack_copy_attr_atime(inode, file_inode(h_file));
13855+ goto out_fput; /* success */
13856+ }
2cbb1c4b
JR
13857+ au_unset_mmapped(file);
13858+ au_vm_file_reset(vma, file);
b912730e 13859+
2cbb1c4b 13860+out_fput:
9dbd164d 13861+ lockdep_off();
b912730e
AM
13862+ ii_write_unlock(inode);
13863+ lockdep_on();
13864+ fput(h_file);
4f0767ce 13865+out:
b912730e 13866+ lockdep_off();
9dbd164d
AM
13867+ si_read_unlock(sb);
13868+ lockdep_on();
13869+ AuTraceErr(err);
4a4d8108
AM
13870+ return err;
13871+}
13872+
13873+/* ---------------------------------------------------------------------- */
13874+
1e00d052
AM
13875+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
13876+ int datasync)
4a4d8108
AM
13877+{
13878+ int err;
b912730e 13879+ struct au_write_pre wpre;
4a4d8108
AM
13880+ struct inode *inode;
13881+ struct file *h_file;
4a4d8108
AM
13882+
13883+ err = 0; /* -EBADF; */ /* posix? */
13884+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
b912730e 13885+ goto out;
4a4d8108 13886+
b912730e
AM
13887+ inode = file_inode(file);
13888+ au_mtx_and_read_lock(inode);
13889+
13890+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
13891+ err = PTR_ERR(h_file);
13892+ if (IS_ERR(h_file))
4a4d8108 13893+ goto out_unlock;
4a4d8108 13894+
53392da6 13895+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
b912730e 13896+ au_write_post(inode, h_file, &wpre, /*written*/0);
4a4d8108 13897+
4f0767ce 13898+out_unlock:
b912730e 13899+ si_read_unlock(inode->i_sb);
1e00d052 13900+ mutex_unlock(&inode->i_mutex);
b912730e 13901+out:
4a4d8108 13902+ return err;
dece6358
AM
13903+}
13904+
4a4d8108
AM
13905+/* no one supports this operation, currently */
13906+#if 0
13907+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
dece6358 13908+{
4a4d8108 13909+ int err;
b912730e 13910+ struct au_write_pre wpre;
4a4d8108
AM
13911+ struct inode *inode;
13912+ struct file *file, *h_file;
1308ab2a 13913+
4a4d8108
AM
13914+ err = 0; /* -EBADF; */ /* posix? */
13915+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
13916+ goto out;
1308ab2a 13917+
b912730e
AM
13918+ file = kio->ki_filp;
13919+ inode = file_inode(file);
13920+ au_mtx_and_read_lock(inode);
13921+
13922+ h_file = au_write_pre(file, /*do_ready*/1, &wpre);
13923+ err = PTR_ERR(h_file);
13924+ if (IS_ERR(h_file))
4a4d8108 13925+ goto out_unlock;
1308ab2a 13926+
4a4d8108
AM
13927+ err = -ENOSYS;
13928+ h_file = au_hf_top(file);
523b37e3 13929+ if (h_file->f_op->aio_fsync) {
4a4d8108 13930+ struct mutex *h_mtx;
1308ab2a 13931+
c06a8ce3 13932+ h_mtx = &file_inode(h_file)->i_mutex;
4a4d8108
AM
13933+ if (!is_sync_kiocb(kio)) {
13934+ get_file(h_file);
13935+ fput(file);
13936+ }
13937+ kio->ki_filp = h_file;
13938+ err = h_file->f_op->aio_fsync(kio, datasync);
13939+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
13940+ if (!err)
13941+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
13942+ /*ignore*/
4a4d8108
AM
13943+ mutex_unlock(h_mtx);
13944+ }
b912730e 13945+ au_write_post(inode, h_file, &wpre, /*written*/0);
1308ab2a 13946+
4f0767ce 13947+out_unlock:
e49829fe 13948+ si_read_unlock(inode->sb);
4a4d8108 13949+ mutex_unlock(&inode->i_mutex);
b912730e 13950+out:
4a4d8108 13951+ return err;
dece6358 13952+}
4a4d8108 13953+#endif
dece6358 13954+
4a4d8108 13955+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 13956+{
4a4d8108
AM
13957+ int err;
13958+ struct file *h_file;
4a4d8108 13959+ struct super_block *sb;
1308ab2a 13960+
b912730e 13961+ sb = file->f_path.dentry->d_sb;
e49829fe 13962+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e
AM
13963+
13964+ h_file = au_read_pre(file, /*keep_fi*/0);
13965+ err = PTR_ERR(h_file);
13966+ if (IS_ERR(h_file))
4a4d8108
AM
13967+ goto out;
13968+
523b37e3 13969+ if (h_file->f_op->fasync)
4a4d8108 13970+ err = h_file->f_op->fasync(fd, h_file, flag);
b912730e 13971+ fput(h_file); /* instead of au_read_post() */
1308ab2a 13972+
4f0767ce 13973+out:
4a4d8108 13974+ si_read_unlock(sb);
1308ab2a 13975+ return err;
dece6358 13976+}
4a4d8108
AM
13977+
13978+/* ---------------------------------------------------------------------- */
13979+
13980+/* no one supports this operation, currently */
13981+#if 0
13982+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
2000de60 13983+ size_t len, loff_t *pos, int more)
4a4d8108
AM
13984+{
13985+}
13986+#endif
13987+
13988+/* ---------------------------------------------------------------------- */
13989+
13990+const struct file_operations aufs_file_fop = {
13991+ .owner = THIS_MODULE,
2cbb1c4b 13992+
027c5e7a 13993+ .llseek = default_llseek,
4a4d8108
AM
13994+
13995+ .read = aufs_read,
13996+ .write = aufs_write,
076b876e
AM
13997+ .read_iter = aufs_read_iter,
13998+ .write_iter = aufs_write_iter,
13999+
4a4d8108
AM
14000+#ifdef CONFIG_AUFS_POLL
14001+ .poll = aufs_poll,
14002+#endif
14003+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 14004+#ifdef CONFIG_COMPAT
c2b27bf2 14005+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 14006+#endif
4a4d8108
AM
14007+ .mmap = aufs_mmap,
14008+ .open = aufs_open_nondir,
14009+ .flush = aufs_flush_nondir,
14010+ .release = aufs_release_nondir,
14011+ .fsync = aufs_fsync_nondir,
14012+ /* .aio_fsync = aufs_aio_fsync_nondir, */
14013+ .fasync = aufs_fasync,
14014+ /* .sendpage = aufs_sendpage, */
14015+ .splice_write = aufs_splice_write,
14016+ .splice_read = aufs_splice_read,
14017+#if 0
14018+ .aio_splice_write = aufs_aio_splice_write,
38d290e6 14019+ .aio_splice_read = aufs_aio_splice_read,
4a4d8108 14020+#endif
38d290e6 14021+ .fallocate = aufs_fallocate
4a4d8108 14022+};
7f207e10
AM
14023diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
14024--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 14025+++ linux/fs/aufs/fstype.h 2015-09-24 10:47:58.254719746 +0200
b912730e 14026@@ -0,0 +1,400 @@
4a4d8108 14027+/*
2000de60 14028+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
14029+ *
14030+ * This program, aufs is free software; you can redistribute it and/or modify
14031+ * it under the terms of the GNU General Public License as published by
14032+ * the Free Software Foundation; either version 2 of the License, or
14033+ * (at your option) any later version.
14034+ *
14035+ * This program is distributed in the hope that it will be useful,
14036+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14037+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14038+ * GNU General Public License for more details.
14039+ *
14040+ * You should have received a copy of the GNU General Public License
523b37e3 14041+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
14042+ */
14043+
14044+/*
14045+ * judging filesystem type
14046+ */
14047+
14048+#ifndef __AUFS_FSTYPE_H__
14049+#define __AUFS_FSTYPE_H__
14050+
14051+#ifdef __KERNEL__
14052+
14053+#include <linux/fs.h>
14054+#include <linux/magic.h>
14055+#include <linux/romfs_fs.h>
b912730e 14056+#include <linux/nfs_fs.h>
4a4d8108
AM
14057+
14058+static inline int au_test_aufs(struct super_block *sb)
14059+{
14060+ return sb->s_magic == AUFS_SUPER_MAGIC;
14061+}
14062+
14063+static inline const char *au_sbtype(struct super_block *sb)
14064+{
14065+ return sb->s_type->name;
14066+}
1308ab2a 14067+
14068+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
14069+{
2000de60
JR
14070+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
14071+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
14072+#else
14073+ return 0;
14074+#endif
14075+}
14076+
1308ab2a 14077+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 14078+{
2000de60
JR
14079+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
14080+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
14081+#else
14082+ return 0;
14083+#endif
14084+}
14085+
1308ab2a 14086+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 14087+{
1308ab2a 14088+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
14089+ return sb->s_magic == CRAMFS_MAGIC;
14090+#endif
14091+ return 0;
14092+}
14093+
14094+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
14095+{
14096+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
14097+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
14098+#else
14099+ return 0;
14100+#endif
14101+}
14102+
1308ab2a 14103+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 14104+{
1308ab2a 14105+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
14106+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
14107+#else
14108+ return 0;
14109+#endif
14110+}
14111+
1308ab2a 14112+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 14113+{
1308ab2a 14114+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
14115+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
14116+#else
14117+ return 0;
14118+#endif
14119+}
14120+
1308ab2a 14121+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 14122+{
1308ab2a 14123+#ifdef CONFIG_TMPFS
14124+ return sb->s_magic == TMPFS_MAGIC;
14125+#else
14126+ return 0;
dece6358 14127+#endif
dece6358
AM
14128+}
14129+
1308ab2a 14130+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 14131+{
1308ab2a 14132+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
14133+ return !strcmp(au_sbtype(sb), "ecryptfs");
14134+#else
14135+ return 0;
14136+#endif
1facf9fc 14137+}
14138+
1308ab2a 14139+static inline int au_test_ramfs(struct super_block *sb)
14140+{
14141+ return sb->s_magic == RAMFS_MAGIC;
14142+}
14143+
14144+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
14145+{
14146+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
14147+ return sb->s_magic == UBIFS_SUPER_MAGIC;
14148+#else
14149+ return 0;
14150+#endif
14151+}
14152+
14153+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
14154+{
14155+#ifdef CONFIG_PROC_FS
14156+ return sb->s_magic == PROC_SUPER_MAGIC;
14157+#else
14158+ return 0;
14159+#endif
14160+}
14161+
14162+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
14163+{
14164+#ifdef CONFIG_SYSFS
14165+ return sb->s_magic == SYSFS_MAGIC;
14166+#else
14167+ return 0;
14168+#endif
14169+}
14170+
14171+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
14172+{
14173+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
14174+ return sb->s_magic == CONFIGFS_MAGIC;
14175+#else
14176+ return 0;
14177+#endif
14178+}
14179+
14180+static inline int au_test_minix(struct super_block *sb __maybe_unused)
14181+{
14182+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
14183+ return sb->s_magic == MINIX3_SUPER_MAGIC
14184+ || sb->s_magic == MINIX2_SUPER_MAGIC
14185+ || sb->s_magic == MINIX2_SUPER_MAGIC2
14186+ || sb->s_magic == MINIX_SUPER_MAGIC
14187+ || sb->s_magic == MINIX_SUPER_MAGIC2;
14188+#else
14189+ return 0;
14190+#endif
14191+}
14192+
1308ab2a 14193+static inline int au_test_fat(struct super_block *sb __maybe_unused)
14194+{
14195+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
14196+ return sb->s_magic == MSDOS_SUPER_MAGIC;
14197+#else
14198+ return 0;
14199+#endif
14200+}
14201+
14202+static inline int au_test_msdos(struct super_block *sb)
14203+{
14204+ return au_test_fat(sb);
14205+}
14206+
14207+static inline int au_test_vfat(struct super_block *sb)
14208+{
14209+ return au_test_fat(sb);
14210+}
14211+
14212+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
14213+{
14214+#ifdef CONFIG_SECURITYFS
14215+ return sb->s_magic == SECURITYFS_MAGIC;
14216+#else
14217+ return 0;
14218+#endif
14219+}
14220+
14221+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
14222+{
14223+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
14224+ return sb->s_magic == SQUASHFS_MAGIC;
14225+#else
14226+ return 0;
14227+#endif
14228+}
14229+
14230+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
14231+{
14232+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
14233+ return sb->s_magic == BTRFS_SUPER_MAGIC;
14234+#else
14235+ return 0;
14236+#endif
14237+}
14238+
14239+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
14240+{
14241+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
14242+ return sb->s_magic == XENFS_SUPER_MAGIC;
14243+#else
14244+ return 0;
14245+#endif
14246+}
14247+
14248+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
14249+{
14250+#ifdef CONFIG_DEBUG_FS
14251+ return sb->s_magic == DEBUGFS_MAGIC;
14252+#else
14253+ return 0;
14254+#endif
14255+}
14256+
14257+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
14258+{
14259+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
14260+ return sb->s_magic == NILFS_SUPER_MAGIC;
14261+#else
14262+ return 0;
14263+#endif
14264+}
14265+
4a4d8108
AM
14266+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
14267+{
14268+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
14269+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
14270+#else
14271+ return 0;
14272+#endif
14273+}
14274+
1308ab2a 14275+/* ---------------------------------------------------------------------- */
14276+/*
14277+ * they can't be an aufs branch.
14278+ */
14279+static inline int au_test_fs_unsuppoted(struct super_block *sb)
14280+{
14281+ return
14282+#ifndef CONFIG_AUFS_BR_RAMFS
14283+ au_test_ramfs(sb) ||
14284+#endif
14285+ au_test_procfs(sb)
14286+ || au_test_sysfs(sb)
14287+ || au_test_configfs(sb)
14288+ || au_test_debugfs(sb)
14289+ || au_test_securityfs(sb)
14290+ || au_test_xenfs(sb)
14291+ || au_test_ecryptfs(sb)
14292+ /* || !strcmp(au_sbtype(sb), "unionfs") */
14293+ || au_test_aufs(sb); /* will be supported in next version */
14294+}
14295+
1308ab2a 14296+static inline int au_test_fs_remote(struct super_block *sb)
14297+{
14298+ return !au_test_tmpfs(sb)
14299+#ifdef CONFIG_AUFS_BR_RAMFS
14300+ && !au_test_ramfs(sb)
14301+#endif
14302+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
14303+}
14304+
14305+/* ---------------------------------------------------------------------- */
14306+
14307+/*
14308+ * Note: these functions (below) are created after reading ->getattr() in all
14309+ * filesystems under linux/fs. it means we have to do so in every update...
14310+ */
14311+
14312+/*
14313+ * some filesystems require getattr to refresh the inode attributes before
14314+ * referencing.
14315+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
14316+ * and leave the work for d_revalidate()
14317+ */
14318+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
14319+{
14320+ return au_test_nfs(sb)
14321+ || au_test_fuse(sb)
1308ab2a 14322+ /* || au_test_btrfs(sb) */ /* untested */
1308ab2a 14323+ ;
14324+}
14325+
14326+/*
14327+ * filesystems which don't maintain i_size or i_blocks.
14328+ */
14329+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
14330+{
14331+ return au_test_xfs(sb)
4a4d8108
AM
14332+ || au_test_btrfs(sb)
14333+ || au_test_ubifs(sb)
14334+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 14335+ /* || au_test_minix(sb) */ /* untested */
14336+ ;
14337+}
14338+
14339+/*
14340+ * filesystems which don't store the correct value in some of their inode
14341+ * attributes.
14342+ */
14343+static inline int au_test_fs_bad_iattr(struct super_block *sb)
14344+{
14345+ return au_test_fs_bad_iattr_size(sb)
1308ab2a 14346+ || au_test_fat(sb)
14347+ || au_test_msdos(sb)
14348+ || au_test_vfat(sb);
1facf9fc 14349+}
14350+
14351+/* they don't check i_nlink in link(2) */
14352+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
14353+{
14354+ return au_test_tmpfs(sb)
14355+#ifdef CONFIG_AUFS_BR_RAMFS
14356+ || au_test_ramfs(sb)
14357+#endif
4a4d8108 14358+ || au_test_ubifs(sb)
4a4d8108 14359+ || au_test_hfsplus(sb);
1facf9fc 14360+}
14361+
14362+/*
14363+ * filesystems which sets S_NOATIME and S_NOCMTIME.
14364+ */
14365+static inline int au_test_fs_notime(struct super_block *sb)
14366+{
14367+ return au_test_nfs(sb)
14368+ || au_test_fuse(sb)
dece6358 14369+ || au_test_ubifs(sb)
1facf9fc 14370+ ;
14371+}
14372+
1facf9fc 14373+/* temporary support for i#1 in cramfs */
14374+static inline int au_test_fs_unique_ino(struct inode *inode)
14375+{
14376+ if (au_test_cramfs(inode->i_sb))
14377+ return inode->i_ino != 1;
14378+ return 1;
14379+}
14380+
14381+/* ---------------------------------------------------------------------- */
14382+
14383+/*
14384+ * the filesystem where the xino files placed must support i/o after unlink and
14385+ * maintain i_size and i_blocks.
14386+ */
14387+static inline int au_test_fs_bad_xino(struct super_block *sb)
14388+{
14389+ return au_test_fs_remote(sb)
14390+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 14391+ /* don't want unnecessary work for xino */
14392+ || au_test_aufs(sb)
1308ab2a 14393+ || au_test_ecryptfs(sb)
14394+ || au_test_nilfs(sb);
1facf9fc 14395+}
14396+
14397+static inline int au_test_fs_trunc_xino(struct super_block *sb)
14398+{
14399+ return au_test_tmpfs(sb)
14400+ || au_test_ramfs(sb);
14401+}
14402+
14403+/*
14404+ * test if the @sb is real-readonly.
14405+ */
14406+static inline int au_test_fs_rr(struct super_block *sb)
14407+{
14408+ return au_test_squashfs(sb)
14409+ || au_test_iso9660(sb)
14410+ || au_test_cramfs(sb)
14411+ || au_test_romfs(sb);
14412+}
14413+
b912730e
AM
14414+/*
14415+ * test if the @inode is nfs with 'noacl' option
14416+ * NFS always sets MS_POSIXACL regardless its mount option 'noacl.'
14417+ */
14418+static inline int au_test_nfs_noacl(struct inode *inode)
14419+{
14420+ return au_test_nfs(inode->i_sb)
14421+ /* && IS_POSIXACL(inode) */
14422+ && !nfs_server_capable(inode, NFS_CAP_ACLS);
14423+}
14424+
1facf9fc 14425+#endif /* __KERNEL__ */
14426+#endif /* __AUFS_FSTYPE_H__ */
7f207e10
AM
14427diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
14428--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 14429+++ linux/fs/aufs/hfsnotify.c 2015-09-24 10:47:58.254719746 +0200
c1595e42 14430@@ -0,0 +1,288 @@
1facf9fc 14431+/*
2000de60 14432+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 14433+ *
14434+ * This program, aufs is free software; you can redistribute it and/or modify
14435+ * it under the terms of the GNU General Public License as published by
14436+ * the Free Software Foundation; either version 2 of the License, or
14437+ * (at your option) any later version.
dece6358
AM
14438+ *
14439+ * This program is distributed in the hope that it will be useful,
14440+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14441+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14442+ * GNU General Public License for more details.
14443+ *
14444+ * You should have received a copy of the GNU General Public License
523b37e3 14445+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 14446+ */
14447+
14448+/*
4a4d8108 14449+ * fsnotify for the lower directories
1facf9fc 14450+ */
14451+
14452+#include "aufs.h"
14453+
4a4d8108
AM
14454+/* FS_IN_IGNORED is unnecessary */
14455+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
14456+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 14457+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 14458+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 14459+
0c5527e5 14460+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 14461+{
0c5527e5
AM
14462+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
14463+ hn_mark);
4a4d8108 14464+ AuDbg("here\n");
7eafdf33 14465+ au_cache_free_hnotify(hn);
076b876e 14466+ smp_mb__before_atomic();
1716fcea
AM
14467+ if (atomic64_dec_and_test(&au_hfsn_ifree))
14468+ wake_up(&au_hfsn_wq);
4a4d8108 14469+}
1facf9fc 14470+
027c5e7a 14471+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 14472+{
1716fcea 14473+ int err;
027c5e7a
AM
14474+ struct au_hnotify *hn;
14475+ struct super_block *sb;
14476+ struct au_branch *br;
0c5527e5 14477+ struct fsnotify_mark *mark;
027c5e7a 14478+ aufs_bindex_t bindex;
1facf9fc 14479+
027c5e7a
AM
14480+ hn = hinode->hi_notify;
14481+ sb = hn->hn_aufs_inode->i_sb;
14482+ bindex = au_br_index(sb, hinode->hi_id);
14483+ br = au_sbr(sb, bindex);
1716fcea
AM
14484+ AuDebugOn(!br->br_hfsn);
14485+
0c5527e5
AM
14486+ mark = &hn->hn_mark;
14487+ fsnotify_init_mark(mark, au_hfsn_free_mark);
14488+ mark->mask = AuHfsnMask;
7f207e10
AM
14489+ /*
14490+ * by udba rename or rmdir, aufs assign a new inode to the known
14491+ * h_inode, so specify 1 to allow dups.
14492+ */
c1595e42 14493+ lockdep_off();
1716fcea 14494+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 14495+ /*mnt*/NULL, /*allow_dups*/1);
1716fcea
AM
14496+ /* even if err */
14497+ fsnotify_put_mark(mark);
c1595e42 14498+ lockdep_on();
1716fcea
AM
14499+
14500+ return err;
1facf9fc 14501+}
14502+
7eafdf33 14503+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 14504+{
0c5527e5 14505+ struct fsnotify_mark *mark;
7eafdf33 14506+ unsigned long long ull;
1716fcea 14507+ struct fsnotify_group *group;
7eafdf33
AM
14508+
14509+ ull = atomic64_inc_return(&au_hfsn_ifree);
14510+ BUG_ON(!ull);
953406b4 14511+
0c5527e5 14512+ mark = &hn->hn_mark;
1716fcea
AM
14513+ spin_lock(&mark->lock);
14514+ group = mark->group;
14515+ fsnotify_get_group(group);
14516+ spin_unlock(&mark->lock);
c1595e42 14517+ lockdep_off();
1716fcea
AM
14518+ fsnotify_destroy_mark(mark, group);
14519+ fsnotify_put_group(group);
c1595e42 14520+ lockdep_on();
7f207e10 14521+
7eafdf33
AM
14522+ /* free hn by myself */
14523+ return 0;
1facf9fc 14524+}
14525+
14526+/* ---------------------------------------------------------------------- */
14527+
4a4d8108 14528+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 14529+{
0c5527e5 14530+ struct fsnotify_mark *mark;
1facf9fc 14531+
0c5527e5
AM
14532+ mark = &hinode->hi_notify->hn_mark;
14533+ spin_lock(&mark->lock);
1facf9fc 14534+ if (do_set) {
0c5527e5
AM
14535+ AuDebugOn(mark->mask & AuHfsnMask);
14536+ mark->mask |= AuHfsnMask;
1facf9fc 14537+ } else {
0c5527e5
AM
14538+ AuDebugOn(!(mark->mask & AuHfsnMask));
14539+ mark->mask &= ~AuHfsnMask;
1facf9fc 14540+ }
0c5527e5 14541+ spin_unlock(&mark->lock);
4a4d8108 14542+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 14543+}
14544+
4a4d8108 14545+/* ---------------------------------------------------------------------- */
1facf9fc 14546+
4a4d8108
AM
14547+/* #define AuDbgHnotify */
14548+#ifdef AuDbgHnotify
14549+static char *au_hfsn_name(u32 mask)
14550+{
14551+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
14552+#define test_ret(flag) \
14553+ do { \
14554+ if (mask & flag) \
14555+ return #flag; \
14556+ } while (0)
4a4d8108
AM
14557+ test_ret(FS_ACCESS);
14558+ test_ret(FS_MODIFY);
14559+ test_ret(FS_ATTRIB);
14560+ test_ret(FS_CLOSE_WRITE);
14561+ test_ret(FS_CLOSE_NOWRITE);
14562+ test_ret(FS_OPEN);
14563+ test_ret(FS_MOVED_FROM);
14564+ test_ret(FS_MOVED_TO);
14565+ test_ret(FS_CREATE);
14566+ test_ret(FS_DELETE);
14567+ test_ret(FS_DELETE_SELF);
14568+ test_ret(FS_MOVE_SELF);
14569+ test_ret(FS_UNMOUNT);
14570+ test_ret(FS_Q_OVERFLOW);
14571+ test_ret(FS_IN_IGNORED);
b912730e 14572+ test_ret(FS_ISDIR);
4a4d8108
AM
14573+ test_ret(FS_IN_ONESHOT);
14574+ test_ret(FS_EVENT_ON_CHILD);
14575+ return "";
14576+#undef test_ret
14577+#else
14578+ return "??";
14579+#endif
1facf9fc 14580+}
4a4d8108 14581+#endif
1facf9fc 14582+
14583+/* ---------------------------------------------------------------------- */
14584+
1716fcea
AM
14585+static void au_hfsn_free_group(struct fsnotify_group *group)
14586+{
14587+ struct au_br_hfsnotify *hfsn = group->private;
14588+
14589+ AuDbg("here\n");
14590+ kfree(hfsn);
14591+}
14592+
4a4d8108 14593+static int au_hfsn_handle_event(struct fsnotify_group *group,
fb47a38f 14594+ struct inode *inode,
0c5527e5
AM
14595+ struct fsnotify_mark *inode_mark,
14596+ struct fsnotify_mark *vfsmount_mark,
fb47a38f
JR
14597+ u32 mask, void *data, int data_type,
14598+ const unsigned char *file_name, u32 cookie)
1facf9fc 14599+{
14600+ int err;
4a4d8108
AM
14601+ struct au_hnotify *hnotify;
14602+ struct inode *h_dir, *h_inode;
fb47a38f 14603+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
4a4d8108 14604+
fb47a38f 14605+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 14606+
14607+ err = 0;
0c5527e5 14608+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108 14609+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 14610+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 14611+ goto out;
1facf9fc 14612+
fb47a38f
JR
14613+ h_dir = inode;
14614+ h_inode = NULL;
4a4d8108 14615+#ifdef AuDbgHnotify
392086de 14616+ au_debug_on();
4a4d8108
AM
14617+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
14618+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
14619+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
14620+ h_dir->i_ino, mask, au_hfsn_name(mask),
14621+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
14622+ /* WARN_ON(1); */
1facf9fc 14623+ }
392086de 14624+ au_debug_off();
1facf9fc 14625+#endif
4a4d8108 14626+
0c5527e5
AM
14627+ AuDebugOn(!inode_mark);
14628+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
14629+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 14630+
4a4d8108
AM
14631+out:
14632+ return err;
14633+}
1facf9fc 14634+
4a4d8108 14635+static struct fsnotify_ops au_hfsn_ops = {
1716fcea
AM
14636+ .handle_event = au_hfsn_handle_event,
14637+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
14638+};
14639+
14640+/* ---------------------------------------------------------------------- */
14641+
027c5e7a
AM
14642+static void au_hfsn_fin_br(struct au_branch *br)
14643+{
1716fcea 14644+ struct au_br_hfsnotify *hfsn;
027c5e7a 14645+
1716fcea 14646+ hfsn = br->br_hfsn;
c1595e42
JR
14647+ if (hfsn) {
14648+ lockdep_off();
1716fcea 14649+ fsnotify_put_group(hfsn->hfsn_group);
c1595e42
JR
14650+ lockdep_on();
14651+ }
027c5e7a
AM
14652+}
14653+
1716fcea 14654+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
14655+{
14656+ int err;
1716fcea
AM
14657+ struct fsnotify_group *group;
14658+ struct au_br_hfsnotify *hfsn;
1facf9fc 14659+
4a4d8108 14660+ err = 0;
1716fcea
AM
14661+ br->br_hfsn = NULL;
14662+ if (!au_br_hnotifyable(perm))
027c5e7a 14663+ goto out;
027c5e7a 14664+
1716fcea
AM
14665+ err = -ENOMEM;
14666+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
14667+ if (unlikely(!hfsn))
027c5e7a
AM
14668+ goto out;
14669+
1716fcea
AM
14670+ err = 0;
14671+ group = fsnotify_alloc_group(&au_hfsn_ops);
14672+ if (IS_ERR(group)) {
14673+ err = PTR_ERR(group);
0c5527e5 14674+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 14675+ goto out_hfsn;
4a4d8108 14676+ }
1facf9fc 14677+
1716fcea
AM
14678+ group->private = hfsn;
14679+ hfsn->hfsn_group = group;
14680+ br->br_hfsn = hfsn;
14681+ goto out; /* success */
14682+
14683+out_hfsn:
14684+ kfree(hfsn);
027c5e7a 14685+out:
1716fcea
AM
14686+ return err;
14687+}
14688+
14689+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
14690+{
14691+ int err;
14692+
14693+ err = 0;
14694+ if (!br->br_hfsn)
14695+ err = au_hfsn_init_br(br, perm);
14696+
1facf9fc 14697+ return err;
14698+}
14699+
7eafdf33
AM
14700+/* ---------------------------------------------------------------------- */
14701+
14702+static void au_hfsn_fin(void)
14703+{
14704+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
14705+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
14706+}
14707+
4a4d8108
AM
14708+const struct au_hnotify_op au_hnotify_op = {
14709+ .ctl = au_hfsn_ctl,
14710+ .alloc = au_hfsn_alloc,
14711+ .free = au_hfsn_free,
1facf9fc 14712+
7eafdf33
AM
14713+ .fin = au_hfsn_fin,
14714+
027c5e7a
AM
14715+ .reset_br = au_hfsn_reset_br,
14716+ .fin_br = au_hfsn_fin_br,
14717+ .init_br = au_hfsn_init_br
4a4d8108 14718+};
7f207e10
AM
14719diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
14720--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 14721+++ linux/fs/aufs/hfsplus.c 2015-09-24 10:47:58.254719746 +0200
523b37e3 14722@@ -0,0 +1,56 @@
4a4d8108 14723+/*
2000de60 14724+ * Copyright (C) 2010-2015 Junjiro R. Okajima
4a4d8108
AM
14725+ *
14726+ * This program, aufs is free software; you can redistribute it and/or modify
14727+ * it under the terms of the GNU General Public License as published by
14728+ * the Free Software Foundation; either version 2 of the License, or
14729+ * (at your option) any later version.
14730+ *
14731+ * This program is distributed in the hope that it will be useful,
14732+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14733+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14734+ * GNU General Public License for more details.
14735+ *
14736+ * You should have received a copy of the GNU General Public License
523b37e3 14737+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 14738+ */
1facf9fc 14739+
4a4d8108
AM
14740+/*
14741+ * special support for filesystems which aqucires an inode mutex
14742+ * at final closing a file, eg, hfsplus.
14743+ *
14744+ * This trick is very simple and stupid, just to open the file before really
14745+ * neceeary open to tell hfsplus that this is not the final closing.
14746+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
14747+ * and au_h_open_post() after releasing it.
14748+ */
1facf9fc 14749+
4a4d8108 14750+#include "aufs.h"
1facf9fc 14751+
392086de
AM
14752+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
14753+ int force_wr)
4a4d8108
AM
14754+{
14755+ struct file *h_file;
14756+ struct dentry *h_dentry;
1facf9fc 14757+
4a4d8108
AM
14758+ h_dentry = au_h_dptr(dentry, bindex);
14759+ AuDebugOn(!h_dentry);
5527c038 14760+ AuDebugOn(d_is_negative(h_dentry));
4a4d8108
AM
14761+
14762+ h_file = NULL;
14763+ if (au_test_hfsplus(h_dentry->d_sb)
7e9cd9fe 14764+ && d_is_reg(h_dentry))
4a4d8108
AM
14765+ h_file = au_h_open(dentry, bindex,
14766+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 14767+ /*file*/NULL, force_wr);
4a4d8108 14768+ return h_file;
1facf9fc 14769+}
14770+
4a4d8108
AM
14771+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
14772+ struct file *h_file)
14773+{
14774+ if (h_file) {
14775+ fput(h_file);
14776+ au_sbr_put(dentry->d_sb, bindex);
14777+ }
14778+}
7f207e10
AM
14779diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
14780--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 14781+++ linux/fs/aufs/hnotify.c 2015-09-24 10:47:58.254719746 +0200
5527c038 14782@@ -0,0 +1,710 @@
e49829fe 14783+/*
2000de60 14784+ * Copyright (C) 2005-2015 Junjiro R. Okajima
e49829fe
JR
14785+ *
14786+ * This program, aufs is free software; you can redistribute it and/or modify
14787+ * it under the terms of the GNU General Public License as published by
14788+ * the Free Software Foundation; either version 2 of the License, or
14789+ * (at your option) any later version.
14790+ *
14791+ * This program is distributed in the hope that it will be useful,
14792+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14793+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14794+ * GNU General Public License for more details.
14795+ *
14796+ * You should have received a copy of the GNU General Public License
523b37e3 14797+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
14798+ */
14799+
14800+/*
7f207e10 14801+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
14802+ */
14803+
14804+#include "aufs.h"
14805+
027c5e7a 14806+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
14807+{
14808+ int err;
7f207e10 14809+ struct au_hnotify *hn;
1facf9fc 14810+
4a4d8108
AM
14811+ err = -ENOMEM;
14812+ hn = au_cache_alloc_hnotify();
14813+ if (hn) {
14814+ hn->hn_aufs_inode = inode;
027c5e7a
AM
14815+ hinode->hi_notify = hn;
14816+ err = au_hnotify_op.alloc(hinode);
14817+ AuTraceErr(err);
14818+ if (unlikely(err)) {
14819+ hinode->hi_notify = NULL;
4a4d8108
AM
14820+ au_cache_free_hnotify(hn);
14821+ /*
14822+ * The upper dir was removed by udba, but the same named
14823+ * dir left. In this case, aufs assignes a new inode
14824+ * number and set the monitor again.
14825+ * For the lower dir, the old monitnor is still left.
14826+ */
14827+ if (err == -EEXIST)
14828+ err = 0;
14829+ }
1308ab2a 14830+ }
1308ab2a 14831+
027c5e7a 14832+ AuTraceErr(err);
1308ab2a 14833+ return err;
dece6358 14834+}
1facf9fc 14835+
4a4d8108 14836+void au_hn_free(struct au_hinode *hinode)
dece6358 14837+{
4a4d8108 14838+ struct au_hnotify *hn;
1facf9fc 14839+
4a4d8108
AM
14840+ hn = hinode->hi_notify;
14841+ if (hn) {
4a4d8108 14842+ hinode->hi_notify = NULL;
7eafdf33
AM
14843+ if (au_hnotify_op.free(hinode, hn))
14844+ au_cache_free_hnotify(hn);
4a4d8108
AM
14845+ }
14846+}
dece6358 14847+
4a4d8108 14848+/* ---------------------------------------------------------------------- */
dece6358 14849+
4a4d8108
AM
14850+void au_hn_ctl(struct au_hinode *hinode, int do_set)
14851+{
14852+ if (hinode->hi_notify)
14853+ au_hnotify_op.ctl(hinode, do_set);
14854+}
14855+
14856+void au_hn_reset(struct inode *inode, unsigned int flags)
14857+{
14858+ aufs_bindex_t bindex, bend;
14859+ struct inode *hi;
14860+ struct dentry *iwhdentry;
1facf9fc 14861+
1308ab2a 14862+ bend = au_ibend(inode);
4a4d8108
AM
14863+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14864+ hi = au_h_iptr(inode, bindex);
14865+ if (!hi)
14866+ continue;
1308ab2a 14867+
4a4d8108
AM
14868+ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
14869+ iwhdentry = au_hi_wh(inode, bindex);
14870+ if (iwhdentry)
14871+ dget(iwhdentry);
14872+ au_igrab(hi);
14873+ au_set_h_iptr(inode, bindex, NULL, 0);
14874+ au_set_h_iptr(inode, bindex, au_igrab(hi),
14875+ flags & ~AuHi_XINO);
14876+ iput(hi);
14877+ dput(iwhdentry);
14878+ /* mutex_unlock(&hi->i_mutex); */
1facf9fc 14879+ }
1facf9fc 14880+}
14881+
1308ab2a 14882+/* ---------------------------------------------------------------------- */
1facf9fc 14883+
4a4d8108 14884+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 14885+{
4a4d8108
AM
14886+ int err;
14887+ aufs_bindex_t bindex, bend, bfound, bstart;
14888+ struct inode *h_i;
1facf9fc 14889+
4a4d8108
AM
14890+ err = 0;
14891+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14892+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14893+ goto out;
14894+ }
1facf9fc 14895+
4a4d8108
AM
14896+ bfound = -1;
14897+ bend = au_ibend(inode);
14898+ bstart = au_ibstart(inode);
14899+#if 0 /* reserved for future use */
14900+ if (bindex == bend) {
14901+ /* keep this ino in rename case */
14902+ goto out;
14903+ }
14904+#endif
14905+ for (bindex = bstart; bindex <= bend; bindex++)
14906+ if (au_h_iptr(inode, bindex) == h_inode) {
14907+ bfound = bindex;
14908+ break;
14909+ }
14910+ if (bfound < 0)
1308ab2a 14911+ goto out;
1facf9fc 14912+
4a4d8108
AM
14913+ for (bindex = bstart; bindex <= bend; bindex++) {
14914+ h_i = au_h_iptr(inode, bindex);
14915+ if (!h_i)
14916+ continue;
1facf9fc 14917+
4a4d8108
AM
14918+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
14919+ /* ignore this error */
14920+ /* bad action? */
1facf9fc 14921+ }
1facf9fc 14922+
4a4d8108 14923+ /* children inode number will be broken */
1facf9fc 14924+
4f0767ce 14925+out:
4a4d8108
AM
14926+ AuTraceErr(err);
14927+ return err;
1facf9fc 14928+}
14929+
4a4d8108 14930+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 14931+{
4a4d8108
AM
14932+ int err, i, j, ndentry;
14933+ struct au_dcsub_pages dpages;
14934+ struct au_dpage *dpage;
14935+ struct dentry **dentries;
1facf9fc 14936+
4a4d8108
AM
14937+ err = au_dpages_init(&dpages, GFP_NOFS);
14938+ if (unlikely(err))
14939+ goto out;
14940+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
14941+ if (unlikely(err))
14942+ goto out_dpages;
1facf9fc 14943+
4a4d8108
AM
14944+ for (i = 0; i < dpages.ndpage; i++) {
14945+ dpage = dpages.dpages + i;
14946+ dentries = dpage->dentries;
14947+ ndentry = dpage->ndentry;
14948+ for (j = 0; j < ndentry; j++) {
14949+ struct dentry *d;
14950+
14951+ d = dentries[j];
14952+ if (IS_ROOT(d))
14953+ continue;
14954+
4a4d8108 14955+ au_digen_dec(d);
5527c038 14956+ if (d_really_is_positive(d))
4a4d8108
AM
14957+ /* todo: reset children xino?
14958+ cached children only? */
5527c038 14959+ au_iigen_dec(d_inode(d));
1308ab2a 14960+ }
dece6358 14961+ }
1facf9fc 14962+
4f0767ce 14963+out_dpages:
4a4d8108 14964+ au_dpages_free(&dpages);
dece6358 14965+
027c5e7a 14966+#if 0
4a4d8108
AM
14967+ /* discard children */
14968+ dentry_unhash(dentry);
14969+ dput(dentry);
027c5e7a 14970+#endif
4f0767ce 14971+out:
dece6358
AM
14972+ return err;
14973+}
14974+
1308ab2a 14975+/*
4a4d8108 14976+ * return 0 if processed.
1308ab2a 14977+ */
4a4d8108
AM
14978+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
14979+ const unsigned int isdir)
dece6358 14980+{
1308ab2a 14981+ int err;
4a4d8108
AM
14982+ struct dentry *d;
14983+ struct qstr *dname;
1facf9fc 14984+
4a4d8108
AM
14985+ err = 1;
14986+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14987+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14988+ err = 0;
14989+ goto out;
14990+ }
dece6358 14991+
4a4d8108
AM
14992+ if (!isdir) {
14993+ AuDebugOn(!name);
14994+ au_iigen_dec(inode);
027c5e7a 14995+ spin_lock(&inode->i_lock);
c1595e42 14996+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 14997+ spin_lock(&d->d_lock);
4a4d8108
AM
14998+ dname = &d->d_name;
14999+ if (dname->len != nlen
027c5e7a
AM
15000+ && memcmp(dname->name, name, nlen)) {
15001+ spin_unlock(&d->d_lock);
4a4d8108 15002+ continue;
027c5e7a 15003+ }
4a4d8108 15004+ err = 0;
4a4d8108
AM
15005+ au_digen_dec(d);
15006+ spin_unlock(&d->d_lock);
15007+ break;
1facf9fc 15008+ }
027c5e7a 15009+ spin_unlock(&inode->i_lock);
1308ab2a 15010+ } else {
027c5e7a 15011+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
c1595e42 15012+ d = d_find_any_alias(inode);
4a4d8108
AM
15013+ if (!d) {
15014+ au_iigen_dec(inode);
15015+ goto out;
15016+ }
1facf9fc 15017+
027c5e7a 15018+ spin_lock(&d->d_lock);
4a4d8108 15019+ dname = &d->d_name;
027c5e7a
AM
15020+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
15021+ spin_unlock(&d->d_lock);
4a4d8108 15022+ err = hn_gen_tree(d);
027c5e7a
AM
15023+ spin_lock(&d->d_lock);
15024+ }
15025+ spin_unlock(&d->d_lock);
4a4d8108
AM
15026+ dput(d);
15027+ }
1facf9fc 15028+
4f0767ce 15029+out:
4a4d8108 15030+ AuTraceErr(err);
1308ab2a 15031+ return err;
15032+}
dece6358 15033+
4a4d8108 15034+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 15035+{
4a4d8108 15036+ int err;
1facf9fc 15037+
5527c038 15038+ if (IS_ROOT(dentry)) {
0c3ec466 15039+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
15040+ return 0;
15041+ }
1308ab2a 15042+
4a4d8108
AM
15043+ err = 0;
15044+ if (!isdir) {
4a4d8108 15045+ au_digen_dec(dentry);
5527c038
JR
15046+ if (d_really_is_positive(dentry))
15047+ au_iigen_dec(d_inode(dentry));
4a4d8108 15048+ } else {
027c5e7a 15049+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
5527c038 15050+ if (d_really_is_positive(dentry))
4a4d8108
AM
15051+ err = hn_gen_tree(dentry);
15052+ }
15053+
15054+ AuTraceErr(err);
15055+ return err;
1facf9fc 15056+}
15057+
4a4d8108 15058+/* ---------------------------------------------------------------------- */
1facf9fc 15059+
4a4d8108
AM
15060+/* hnotify job flags */
15061+#define AuHnJob_XINO0 1
15062+#define AuHnJob_GEN (1 << 1)
15063+#define AuHnJob_DIRENT (1 << 2)
15064+#define AuHnJob_ISDIR (1 << 3)
15065+#define AuHnJob_TRYXINO0 (1 << 4)
15066+#define AuHnJob_MNTPNT (1 << 5)
15067+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
15068+#define au_fset_hnjob(flags, name) \
15069+ do { (flags) |= AuHnJob_##name; } while (0)
15070+#define au_fclr_hnjob(flags, name) \
15071+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 15072+
4a4d8108
AM
15073+enum {
15074+ AuHn_CHILD,
15075+ AuHn_PARENT,
15076+ AuHnLast
15077+};
1facf9fc 15078+
4a4d8108
AM
15079+struct au_hnotify_args {
15080+ struct inode *h_dir, *dir, *h_child_inode;
15081+ u32 mask;
15082+ unsigned int flags[AuHnLast];
15083+ unsigned int h_child_nlen;
15084+ char h_child_name[];
15085+};
1facf9fc 15086+
4a4d8108
AM
15087+struct hn_job_args {
15088+ unsigned int flags;
15089+ struct inode *inode, *h_inode, *dir, *h_dir;
15090+ struct dentry *dentry;
15091+ char *h_name;
15092+ int h_nlen;
15093+};
1308ab2a 15094+
4a4d8108
AM
15095+static int hn_job(struct hn_job_args *a)
15096+{
15097+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
076b876e 15098+ int e;
1308ab2a 15099+
4a4d8108
AM
15100+ /* reset xino */
15101+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
15102+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 15103+
4a4d8108
AM
15104+ if (au_ftest_hnjob(a->flags, TRYXINO0)
15105+ && a->inode
15106+ && a->h_inode) {
15107+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
38d290e6
JR
15108+ if (!a->h_inode->i_nlink
15109+ && !(a->h_inode->i_state & I_LINKABLE))
4a4d8108
AM
15110+ hn_xino(a->inode, a->h_inode); /* ignore this error */
15111+ mutex_unlock(&a->h_inode->i_mutex);
1308ab2a 15112+ }
1facf9fc 15113+
4a4d8108
AM
15114+ /* make the generation obsolete */
15115+ if (au_ftest_hnjob(a->flags, GEN)) {
076b876e 15116+ e = -1;
4a4d8108 15117+ if (a->inode)
076b876e 15118+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
4a4d8108 15119+ isdir);
076b876e 15120+ if (e && a->dentry)
4a4d8108
AM
15121+ hn_gen_by_name(a->dentry, isdir);
15122+ /* ignore this error */
1facf9fc 15123+ }
1facf9fc 15124+
4a4d8108
AM
15125+ /* make dir entries obsolete */
15126+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
15127+ struct au_vdir *vdir;
1facf9fc 15128+
4a4d8108
AM
15129+ vdir = au_ivdir(a->inode);
15130+ if (vdir)
15131+ vdir->vd_jiffy = 0;
15132+ /* IMustLock(a->inode); */
15133+ /* a->inode->i_version++; */
15134+ }
1facf9fc 15135+
4a4d8108
AM
15136+ /* can do nothing but warn */
15137+ if (au_ftest_hnjob(a->flags, MNTPNT)
15138+ && a->dentry
15139+ && d_mountpoint(a->dentry))
523b37e3 15140+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 15141+
4a4d8108 15142+ return 0;
1308ab2a 15143+}
1facf9fc 15144+
1308ab2a 15145+/* ---------------------------------------------------------------------- */
1facf9fc 15146+
4a4d8108
AM
15147+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
15148+ struct inode *dir)
1308ab2a 15149+{
4a4d8108
AM
15150+ struct dentry *dentry, *d, *parent;
15151+ struct qstr *dname;
1308ab2a 15152+
c1595e42 15153+ parent = d_find_any_alias(dir);
4a4d8108
AM
15154+ if (!parent)
15155+ return NULL;
1308ab2a 15156+
4a4d8108 15157+ dentry = NULL;
027c5e7a 15158+ spin_lock(&parent->d_lock);
c1595e42 15159+ list_for_each_entry(d, &parent->d_subdirs, d_child) {
523b37e3 15160+ /* AuDbg("%pd\n", d); */
027c5e7a 15161+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
15162+ dname = &d->d_name;
15163+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
15164+ goto cont_unlock;
15165+ if (au_di(d))
15166+ au_digen_dec(d);
15167+ else
15168+ goto cont_unlock;
c1595e42 15169+ if (au_dcount(d) > 0) {
027c5e7a 15170+ dentry = dget_dlock(d);
4a4d8108 15171+ spin_unlock(&d->d_lock);
027c5e7a 15172+ break;
dece6358 15173+ }
1facf9fc 15174+
f6b6e03d 15175+cont_unlock:
027c5e7a 15176+ spin_unlock(&d->d_lock);
1308ab2a 15177+ }
027c5e7a 15178+ spin_unlock(&parent->d_lock);
4a4d8108 15179+ dput(parent);
1facf9fc 15180+
4a4d8108
AM
15181+ if (dentry)
15182+ di_write_lock_child(dentry);
1308ab2a 15183+
4a4d8108
AM
15184+ return dentry;
15185+}
dece6358 15186+
4a4d8108
AM
15187+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
15188+ aufs_bindex_t bindex, ino_t h_ino)
15189+{
15190+ struct inode *inode;
15191+ ino_t ino;
15192+ int err;
15193+
15194+ inode = NULL;
15195+ err = au_xino_read(sb, bindex, h_ino, &ino);
15196+ if (!err && ino)
15197+ inode = ilookup(sb, ino);
15198+ if (!inode)
15199+ goto out;
15200+
15201+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 15202+ pr_warn("wrong root branch\n");
4a4d8108
AM
15203+ iput(inode);
15204+ inode = NULL;
15205+ goto out;
1308ab2a 15206+ }
15207+
4a4d8108 15208+ ii_write_lock_child(inode);
1308ab2a 15209+
4f0767ce 15210+out:
4a4d8108 15211+ return inode;
dece6358
AM
15212+}
15213+
4a4d8108 15214+static void au_hn_bh(void *_args)
1facf9fc 15215+{
4a4d8108
AM
15216+ struct au_hnotify_args *a = _args;
15217+ struct super_block *sb;
15218+ aufs_bindex_t bindex, bend, bfound;
15219+ unsigned char xino, try_iput;
1facf9fc 15220+ int err;
1308ab2a 15221+ struct inode *inode;
4a4d8108
AM
15222+ ino_t h_ino;
15223+ struct hn_job_args args;
15224+ struct dentry *dentry;
15225+ struct au_sbinfo *sbinfo;
1facf9fc 15226+
4a4d8108
AM
15227+ AuDebugOn(!_args);
15228+ AuDebugOn(!a->h_dir);
15229+ AuDebugOn(!a->dir);
15230+ AuDebugOn(!a->mask);
15231+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
15232+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
15233+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 15234+
4a4d8108
AM
15235+ inode = NULL;
15236+ dentry = NULL;
15237+ /*
15238+ * do not lock a->dir->i_mutex here
15239+ * because of d_revalidate() may cause a deadlock.
15240+ */
15241+ sb = a->dir->i_sb;
15242+ AuDebugOn(!sb);
15243+ sbinfo = au_sbi(sb);
15244+ AuDebugOn(!sbinfo);
7f207e10 15245+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 15246+
4a4d8108
AM
15247+ ii_read_lock_parent(a->dir);
15248+ bfound = -1;
15249+ bend = au_ibend(a->dir);
15250+ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
15251+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
15252+ bfound = bindex;
15253+ break;
15254+ }
15255+ ii_read_unlock(a->dir);
15256+ if (unlikely(bfound < 0))
15257+ goto out;
1facf9fc 15258+
4a4d8108
AM
15259+ xino = !!au_opt_test(au_mntflags(sb), XINO);
15260+ h_ino = 0;
15261+ if (a->h_child_inode)
15262+ h_ino = a->h_child_inode->i_ino;
1facf9fc 15263+
4a4d8108
AM
15264+ if (a->h_child_nlen
15265+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
15266+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
15267+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
15268+ a->dir);
15269+ try_iput = 0;
5527c038
JR
15270+ if (dentry && d_really_is_positive(dentry))
15271+ inode = d_inode(dentry);
4a4d8108
AM
15272+ if (xino && !inode && h_ino
15273+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
15274+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
15275+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
15276+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
15277+ try_iput = 1;
15278+ }
1facf9fc 15279+
4a4d8108
AM
15280+ args.flags = a->flags[AuHn_CHILD];
15281+ args.dentry = dentry;
15282+ args.inode = inode;
15283+ args.h_inode = a->h_child_inode;
15284+ args.dir = a->dir;
15285+ args.h_dir = a->h_dir;
15286+ args.h_name = a->h_child_name;
15287+ args.h_nlen = a->h_child_nlen;
15288+ err = hn_job(&args);
15289+ if (dentry) {
027c5e7a 15290+ if (au_di(dentry))
4a4d8108
AM
15291+ di_write_unlock(dentry);
15292+ dput(dentry);
15293+ }
15294+ if (inode && try_iput) {
15295+ ii_write_unlock(inode);
15296+ iput(inode);
15297+ }
1facf9fc 15298+
4a4d8108
AM
15299+ ii_write_lock_parent(a->dir);
15300+ args.flags = a->flags[AuHn_PARENT];
15301+ args.dentry = NULL;
15302+ args.inode = a->dir;
15303+ args.h_inode = a->h_dir;
15304+ args.dir = NULL;
15305+ args.h_dir = NULL;
15306+ args.h_name = NULL;
15307+ args.h_nlen = 0;
15308+ err = hn_job(&args);
15309+ ii_write_unlock(a->dir);
1facf9fc 15310+
4f0767ce 15311+out:
4a4d8108
AM
15312+ iput(a->h_child_inode);
15313+ iput(a->h_dir);
15314+ iput(a->dir);
027c5e7a
AM
15315+ si_write_unlock(sb);
15316+ au_nwt_done(&sbinfo->si_nowait);
1308ab2a 15317+ kfree(a);
dece6358 15318+}
1facf9fc 15319+
4a4d8108
AM
15320+/* ---------------------------------------------------------------------- */
15321+
15322+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15323+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 15324+{
4a4d8108 15325+ int err, len;
53392da6 15326+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
15327+ unsigned char isdir, isroot, wh;
15328+ struct inode *dir;
15329+ struct au_hnotify_args *args;
15330+ char *p, *h_child_name;
dece6358 15331+
1308ab2a 15332+ err = 0;
4a4d8108
AM
15333+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
15334+ dir = igrab(hnotify->hn_aufs_inode);
15335+ if (!dir)
15336+ goto out;
1facf9fc 15337+
4a4d8108
AM
15338+ isroot = (dir->i_ino == AUFS_ROOT_INO);
15339+ wh = 0;
15340+ h_child_name = (void *)h_child_qstr->name;
15341+ len = h_child_qstr->len;
15342+ if (h_child_name) {
15343+ if (len > AUFS_WH_PFX_LEN
15344+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
15345+ h_child_name += AUFS_WH_PFX_LEN;
15346+ len -= AUFS_WH_PFX_LEN;
15347+ wh = 1;
15348+ }
1facf9fc 15349+ }
dece6358 15350+
4a4d8108
AM
15351+ isdir = 0;
15352+ if (h_child_inode)
15353+ isdir = !!S_ISDIR(h_child_inode->i_mode);
15354+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
15355+ flags[AuHn_CHILD] = 0;
15356+ if (isdir)
15357+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
15358+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
15359+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
15360+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
15361+ case FS_MOVED_FROM:
15362+ case FS_MOVED_TO:
15363+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
15364+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15365+ /*FALLTHROUGH*/
15366+ case FS_CREATE:
fb47a38f 15367+ AuDebugOn(!h_child_name);
4a4d8108 15368+ break;
1facf9fc 15369+
4a4d8108
AM
15370+ case FS_DELETE:
15371+ /*
15372+ * aufs never be able to get this child inode.
15373+ * revalidation should be in d_revalidate()
15374+ * by checking i_nlink, i_generation or d_unhashed().
15375+ */
15376+ AuDebugOn(!h_child_name);
15377+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
15378+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15379+ break;
dece6358 15380+
4a4d8108
AM
15381+ default:
15382+ AuDebugOn(1);
15383+ }
1308ab2a 15384+
4a4d8108
AM
15385+ if (wh)
15386+ h_child_inode = NULL;
1308ab2a 15387+
4a4d8108
AM
15388+ err = -ENOMEM;
15389+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 15390+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
15391+ if (unlikely(!args)) {
15392+ AuErr1("no memory\n");
15393+ iput(dir);
15394+ goto out;
15395+ }
15396+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
15397+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
15398+ args->mask = mask;
15399+ args->dir = dir;
15400+ args->h_dir = igrab(h_dir);
15401+ if (h_child_inode)
15402+ h_child_inode = igrab(h_child_inode); /* can be NULL */
15403+ args->h_child_inode = h_child_inode;
15404+ args->h_child_nlen = len;
15405+ if (len) {
15406+ p = (void *)args;
15407+ p += sizeof(*args);
15408+ memcpy(p, h_child_name, len);
15409+ p[len] = 0;
1308ab2a 15410+ }
1308ab2a 15411+
38d290e6 15412+ /* NFS fires the event for silly-renamed one from kworker */
53392da6 15413+ f = 0;
38d290e6
JR
15414+ if (!dir->i_nlink
15415+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
53392da6
AM
15416+ f = AuWkq_NEST;
15417+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
15418+ if (unlikely(err)) {
15419+ pr_err("wkq %d\n", err);
15420+ iput(args->h_child_inode);
15421+ iput(args->h_dir);
15422+ iput(args->dir);
15423+ kfree(args);
1facf9fc 15424+ }
1facf9fc 15425+
4a4d8108 15426+out:
1facf9fc 15427+ return err;
15428+}
15429+
027c5e7a
AM
15430+/* ---------------------------------------------------------------------- */
15431+
15432+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
15433+{
15434+ int err;
15435+
15436+ AuDebugOn(!(udba & AuOptMask_UDBA));
15437+
15438+ err = 0;
15439+ if (au_hnotify_op.reset_br)
15440+ err = au_hnotify_op.reset_br(udba, br, perm);
15441+
15442+ return err;
15443+}
15444+
15445+int au_hnotify_init_br(struct au_branch *br, int perm)
15446+{
15447+ int err;
15448+
15449+ err = 0;
15450+ if (au_hnotify_op.init_br)
15451+ err = au_hnotify_op.init_br(br, perm);
15452+
15453+ return err;
15454+}
15455+
15456+void au_hnotify_fin_br(struct au_branch *br)
15457+{
15458+ if (au_hnotify_op.fin_br)
15459+ au_hnotify_op.fin_br(br);
15460+}
15461+
4a4d8108
AM
15462+static void au_hn_destroy_cache(void)
15463+{
15464+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
15465+ au_cachep[AuCache_HNOTIFY] = NULL;
15466+}
1308ab2a 15467+
4a4d8108 15468+int __init au_hnotify_init(void)
1facf9fc 15469+{
1308ab2a 15470+ int err;
1308ab2a 15471+
4a4d8108
AM
15472+ err = -ENOMEM;
15473+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
15474+ if (au_cachep[AuCache_HNOTIFY]) {
027c5e7a
AM
15475+ err = 0;
15476+ if (au_hnotify_op.init)
15477+ err = au_hnotify_op.init();
4a4d8108
AM
15478+ if (unlikely(err))
15479+ au_hn_destroy_cache();
1308ab2a 15480+ }
1308ab2a 15481+ AuTraceErr(err);
4a4d8108 15482+ return err;
1308ab2a 15483+}
15484+
4a4d8108 15485+void au_hnotify_fin(void)
1308ab2a 15486+{
027c5e7a
AM
15487+ if (au_hnotify_op.fin)
15488+ au_hnotify_op.fin();
4a4d8108
AM
15489+ /* cf. au_cache_fin() */
15490+ if (au_cachep[AuCache_HNOTIFY])
15491+ au_hn_destroy_cache();
dece6358 15492+}
7f207e10
AM
15493diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
15494--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 15495+++ linux/fs/aufs/iinfo.c 2015-09-24 10:47:58.254719746 +0200
38d290e6 15496@@ -0,0 +1,277 @@
dece6358 15497+/*
2000de60 15498+ * Copyright (C) 2005-2015 Junjiro R. Okajima
dece6358
AM
15499+ *
15500+ * This program, aufs is free software; you can redistribute it and/or modify
15501+ * it under the terms of the GNU General Public License as published by
15502+ * the Free Software Foundation; either version 2 of the License, or
15503+ * (at your option) any later version.
15504+ *
15505+ * This program is distributed in the hope that it will be useful,
15506+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15507+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15508+ * GNU General Public License for more details.
15509+ *
15510+ * You should have received a copy of the GNU General Public License
523b37e3 15511+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 15512+ */
1facf9fc 15513+
dece6358 15514+/*
4a4d8108 15515+ * inode private data
dece6358 15516+ */
1facf9fc 15517+
1308ab2a 15518+#include "aufs.h"
1facf9fc 15519+
4a4d8108 15520+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15521+{
4a4d8108 15522+ struct inode *h_inode;
1facf9fc 15523+
4a4d8108 15524+ IiMustAnyLock(inode);
1facf9fc 15525+
4a4d8108
AM
15526+ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
15527+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
15528+ return h_inode;
15529+}
1facf9fc 15530+
4a4d8108
AM
15531+/* todo: hard/soft set? */
15532+void au_hiput(struct au_hinode *hinode)
15533+{
15534+ au_hn_free(hinode);
15535+ dput(hinode->hi_whdentry);
15536+ iput(hinode->hi_inode);
15537+}
1facf9fc 15538+
4a4d8108
AM
15539+unsigned int au_hi_flags(struct inode *inode, int isdir)
15540+{
15541+ unsigned int flags;
15542+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 15543+
4a4d8108
AM
15544+ flags = 0;
15545+ if (au_opt_test(mnt_flags, XINO))
15546+ au_fset_hi(flags, XINO);
15547+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
15548+ au_fset_hi(flags, HNOTIFY);
15549+ return flags;
1facf9fc 15550+}
15551+
4a4d8108
AM
15552+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15553+ struct inode *h_inode, unsigned int flags)
1308ab2a 15554+{
4a4d8108
AM
15555+ struct au_hinode *hinode;
15556+ struct inode *hi;
15557+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 15558+
4a4d8108 15559+ IiMustWriteLock(inode);
dece6358 15560+
4a4d8108
AM
15561+ hinode = iinfo->ii_hinode + bindex;
15562+ hi = hinode->hi_inode;
15563+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
15564+
15565+ if (hi)
15566+ au_hiput(hinode);
15567+ hinode->hi_inode = h_inode;
15568+ if (h_inode) {
15569+ int err;
15570+ struct super_block *sb = inode->i_sb;
15571+ struct au_branch *br;
15572+
027c5e7a
AM
15573+ AuDebugOn(inode->i_mode
15574+ && (h_inode->i_mode & S_IFMT)
15575+ != (inode->i_mode & S_IFMT));
4a4d8108
AM
15576+ if (bindex == iinfo->ii_bstart)
15577+ au_cpup_igen(inode, h_inode);
15578+ br = au_sbr(sb, bindex);
15579+ hinode->hi_id = br->br_id;
15580+ if (au_ftest_hi(flags, XINO)) {
15581+ err = au_xino_write(sb, bindex, h_inode->i_ino,
15582+ inode->i_ino);
15583+ if (unlikely(err))
15584+ AuIOErr1("failed au_xino_write() %d\n", err);
15585+ }
15586+
15587+ if (au_ftest_hi(flags, HNOTIFY)
15588+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 15589+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
15590+ if (unlikely(err))
15591+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 15592+ }
15593+ }
4a4d8108 15594+}
dece6358 15595+
4a4d8108
AM
15596+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
15597+ struct dentry *h_wh)
15598+{
15599+ struct au_hinode *hinode;
dece6358 15600+
4a4d8108
AM
15601+ IiMustWriteLock(inode);
15602+
15603+ hinode = au_ii(inode)->ii_hinode + bindex;
15604+ AuDebugOn(hinode->hi_whdentry);
15605+ hinode->hi_whdentry = h_wh;
1facf9fc 15606+}
15607+
537831f9 15608+void au_update_iigen(struct inode *inode, int half)
1308ab2a 15609+{
537831f9
AM
15610+ struct au_iinfo *iinfo;
15611+ struct au_iigen *iigen;
15612+ unsigned int sigen;
15613+
15614+ sigen = au_sigen(inode->i_sb);
15615+ iinfo = au_ii(inode);
15616+ iigen = &iinfo->ii_generation;
15617+ spin_lock(&iinfo->ii_genspin);
15618+ iigen->ig_generation = sigen;
15619+ if (half)
15620+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
15621+ else
15622+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
15623+ spin_unlock(&iinfo->ii_genspin);
4a4d8108 15624+}
1facf9fc 15625+
4a4d8108
AM
15626+/* it may be called at remount time, too */
15627+void au_update_ibrange(struct inode *inode, int do_put_zero)
15628+{
15629+ struct au_iinfo *iinfo;
027c5e7a 15630+ aufs_bindex_t bindex, bend;
1facf9fc 15631+
4a4d8108 15632+ iinfo = au_ii(inode);
027c5e7a 15633+ if (!iinfo)
4a4d8108 15634+ return;
1facf9fc 15635+
4a4d8108 15636+ IiMustWriteLock(inode);
1facf9fc 15637+
027c5e7a 15638+ if (do_put_zero && iinfo->ii_bstart >= 0) {
4a4d8108
AM
15639+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
15640+ bindex++) {
15641+ struct inode *h_i;
1facf9fc 15642+
4a4d8108 15643+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
38d290e6
JR
15644+ if (h_i
15645+ && !h_i->i_nlink
15646+ && !(h_i->i_state & I_LINKABLE))
027c5e7a
AM
15647+ au_set_h_iptr(inode, bindex, NULL, 0);
15648+ }
4a4d8108
AM
15649+ }
15650+
027c5e7a
AM
15651+ iinfo->ii_bstart = -1;
15652+ iinfo->ii_bend = -1;
15653+ bend = au_sbend(inode->i_sb);
15654+ for (bindex = 0; bindex <= bend; bindex++)
15655+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
15656+ iinfo->ii_bstart = bindex;
4a4d8108 15657+ break;
027c5e7a
AM
15658+ }
15659+ if (iinfo->ii_bstart >= 0)
15660+ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
15661+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
15662+ iinfo->ii_bend = bindex;
15663+ break;
15664+ }
15665+ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
1308ab2a 15666+}
1facf9fc 15667+
dece6358 15668+/* ---------------------------------------------------------------------- */
1facf9fc 15669+
4a4d8108 15670+void au_icntnr_init_once(void *_c)
dece6358 15671+{
4a4d8108
AM
15672+ struct au_icntnr *c = _c;
15673+ struct au_iinfo *iinfo = &c->iinfo;
e49829fe 15674+ static struct lock_class_key aufs_ii;
1facf9fc 15675+
537831f9 15676+ spin_lock_init(&iinfo->ii_genspin);
4a4d8108 15677+ au_rw_init(&iinfo->ii_rwsem);
e49829fe 15678+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
4a4d8108
AM
15679+ inode_init_once(&c->vfs_inode);
15680+}
1facf9fc 15681+
4a4d8108
AM
15682+int au_iinfo_init(struct inode *inode)
15683+{
15684+ struct au_iinfo *iinfo;
15685+ struct super_block *sb;
15686+ int nbr, i;
1facf9fc 15687+
4a4d8108
AM
15688+ sb = inode->i_sb;
15689+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
15690+ nbr = au_sbend(sb) + 1;
15691+ if (unlikely(nbr <= 0))
15692+ nbr = 1;
15693+ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
15694+ if (iinfo->ii_hinode) {
7f207e10 15695+ au_ninodes_inc(sb);
4a4d8108
AM
15696+ for (i = 0; i < nbr; i++)
15697+ iinfo->ii_hinode[i].hi_id = -1;
1facf9fc 15698+
537831f9 15699+ iinfo->ii_generation.ig_generation = au_sigen(sb);
4a4d8108
AM
15700+ iinfo->ii_bstart = -1;
15701+ iinfo->ii_bend = -1;
15702+ iinfo->ii_vdir = NULL;
15703+ return 0;
1308ab2a 15704+ }
4a4d8108
AM
15705+ return -ENOMEM;
15706+}
1facf9fc 15707+
4a4d8108
AM
15708+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
15709+{
15710+ int err, sz;
15711+ struct au_hinode *hip;
1facf9fc 15712+
4a4d8108
AM
15713+ AuRwMustWriteLock(&iinfo->ii_rwsem);
15714+
15715+ err = -ENOMEM;
15716+ sz = sizeof(*hip) * (iinfo->ii_bend + 1);
15717+ if (!sz)
15718+ sz = sizeof(*hip);
15719+ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
15720+ if (hip) {
15721+ iinfo->ii_hinode = hip;
15722+ err = 0;
1308ab2a 15723+ }
4a4d8108 15724+
1308ab2a 15725+ return err;
1facf9fc 15726+}
15727+
4a4d8108 15728+void au_iinfo_fin(struct inode *inode)
1facf9fc 15729+{
4a4d8108
AM
15730+ struct au_iinfo *iinfo;
15731+ struct au_hinode *hi;
15732+ struct super_block *sb;
b752ccd1
AM
15733+ aufs_bindex_t bindex, bend;
15734+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 15735+
4a4d8108
AM
15736+ iinfo = au_ii(inode);
15737+ /* bad_inode case */
15738+ if (!iinfo)
15739+ return;
1308ab2a 15740+
b752ccd1 15741+ sb = inode->i_sb;
7f207e10 15742+ au_ninodes_dec(sb);
b752ccd1
AM
15743+ if (si_pid_test(sb))
15744+ au_xino_delete_inode(inode, unlinked);
15745+ else {
15746+ /*
15747+ * it is safe to hide the dependency between sbinfo and
15748+ * sb->s_umount.
15749+ */
15750+ lockdep_off();
15751+ si_noflush_read_lock(sb);
15752+ au_xino_delete_inode(inode, unlinked);
15753+ si_read_unlock(sb);
15754+ lockdep_on();
15755+ }
15756+
4a4d8108
AM
15757+ if (iinfo->ii_vdir)
15758+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 15759+
b752ccd1
AM
15760+ bindex = iinfo->ii_bstart;
15761+ if (bindex >= 0) {
15762+ hi = iinfo->ii_hinode + bindex;
4a4d8108 15763+ bend = iinfo->ii_bend;
b752ccd1
AM
15764+ while (bindex++ <= bend) {
15765+ if (hi->hi_inode)
4a4d8108 15766+ au_hiput(hi);
4a4d8108
AM
15767+ hi++;
15768+ }
15769+ }
4a4d8108 15770+ kfree(iinfo->ii_hinode);
027c5e7a 15771+ iinfo->ii_hinode = NULL;
4a4d8108 15772+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 15773+}
7f207e10
AM
15774diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
15775--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 15776+++ linux/fs/aufs/inode.c 2015-09-24 10:47:58.254719746 +0200
5527c038 15777@@ -0,0 +1,500 @@
4a4d8108 15778+/*
2000de60 15779+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
15780+ *
15781+ * This program, aufs is free software; you can redistribute it and/or modify
15782+ * it under the terms of the GNU General Public License as published by
15783+ * the Free Software Foundation; either version 2 of the License, or
15784+ * (at your option) any later version.
15785+ *
15786+ * This program is distributed in the hope that it will be useful,
15787+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15788+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15789+ * GNU General Public License for more details.
15790+ *
15791+ * You should have received a copy of the GNU General Public License
523b37e3 15792+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15793+ */
1facf9fc 15794+
4a4d8108
AM
15795+/*
15796+ * inode functions
15797+ */
1facf9fc 15798+
4a4d8108 15799+#include "aufs.h"
1308ab2a 15800+
4a4d8108
AM
15801+struct inode *au_igrab(struct inode *inode)
15802+{
15803+ if (inode) {
15804+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 15805+ ihold(inode);
1facf9fc 15806+ }
4a4d8108
AM
15807+ return inode;
15808+}
1facf9fc 15809+
4a4d8108
AM
15810+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
15811+{
15812+ au_cpup_attr_all(inode, /*force*/0);
537831f9 15813+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
15814+ if (do_version)
15815+ inode->i_version++;
dece6358 15816+}
1facf9fc 15817+
027c5e7a 15818+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 15819+{
4a4d8108 15820+ int err, e;
027c5e7a 15821+ umode_t type;
4a4d8108 15822+ aufs_bindex_t bindex, new_bindex;
1308ab2a 15823+ struct super_block *sb;
4a4d8108 15824+ struct au_iinfo *iinfo;
027c5e7a 15825+ struct au_hinode *p, *q, tmp;
1facf9fc 15826+
4a4d8108 15827+ IiMustWriteLock(inode);
1facf9fc 15828+
027c5e7a 15829+ *update = 0;
4a4d8108 15830+ sb = inode->i_sb;
027c5e7a 15831+ type = inode->i_mode & S_IFMT;
4a4d8108
AM
15832+ iinfo = au_ii(inode);
15833+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
15834+ if (unlikely(err))
1308ab2a 15835+ goto out;
1facf9fc 15836+
027c5e7a 15837+ AuDebugOn(iinfo->ii_bstart < 0);
4a4d8108 15838+ p = iinfo->ii_hinode + iinfo->ii_bstart;
4a4d8108
AM
15839+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
15840+ bindex++, p++) {
15841+ if (!p->hi_inode)
15842+ continue;
1facf9fc 15843+
027c5e7a 15844+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
15845+ new_bindex = au_br_index(sb, p->hi_id);
15846+ if (new_bindex == bindex)
15847+ continue;
1facf9fc 15848+
4a4d8108 15849+ if (new_bindex < 0) {
027c5e7a 15850+ *update = 1;
4a4d8108
AM
15851+ au_hiput(p);
15852+ p->hi_inode = NULL;
15853+ continue;
1308ab2a 15854+ }
4a4d8108
AM
15855+
15856+ if (new_bindex < iinfo->ii_bstart)
15857+ iinfo->ii_bstart = new_bindex;
15858+ if (iinfo->ii_bend < new_bindex)
15859+ iinfo->ii_bend = new_bindex;
15860+ /* swap two lower inode, and loop again */
15861+ q = iinfo->ii_hinode + new_bindex;
15862+ tmp = *q;
15863+ *q = *p;
15864+ *p = tmp;
15865+ if (tmp.hi_inode) {
15866+ bindex--;
15867+ p--;
1308ab2a 15868+ }
15869+ }
4a4d8108
AM
15870+ au_update_ibrange(inode, /*do_put_zero*/0);
15871+ e = au_dy_irefresh(inode);
15872+ if (unlikely(e && !err))
15873+ err = e;
1facf9fc 15874+
4f0767ce 15875+out:
027c5e7a
AM
15876+ AuTraceErr(err);
15877+ return err;
15878+}
15879+
15880+int au_refresh_hinode_self(struct inode *inode)
15881+{
15882+ int err, update;
15883+
15884+ err = au_ii_refresh(inode, &update);
15885+ if (!err)
15886+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
15887+
15888+ AuTraceErr(err);
4a4d8108
AM
15889+ return err;
15890+}
1facf9fc 15891+
4a4d8108
AM
15892+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
15893+{
027c5e7a 15894+ int err, e, update;
4a4d8108 15895+ unsigned int flags;
027c5e7a 15896+ umode_t mode;
4a4d8108 15897+ aufs_bindex_t bindex, bend;
027c5e7a 15898+ unsigned char isdir;
4a4d8108
AM
15899+ struct au_hinode *p;
15900+ struct au_iinfo *iinfo;
1facf9fc 15901+
027c5e7a 15902+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
15903+ if (unlikely(err))
15904+ goto out;
15905+
15906+ update = 0;
15907+ iinfo = au_ii(inode);
15908+ p = iinfo->ii_hinode + iinfo->ii_bstart;
027c5e7a
AM
15909+ mode = (inode->i_mode & S_IFMT);
15910+ isdir = S_ISDIR(mode);
4a4d8108
AM
15911+ flags = au_hi_flags(inode, isdir);
15912+ bend = au_dbend(dentry);
15913+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
5527c038 15914+ struct inode *h_i, *h_inode;
4a4d8108
AM
15915+ struct dentry *h_d;
15916+
15917+ h_d = au_h_dptr(dentry, bindex);
5527c038 15918+ if (!h_d || d_is_negative(h_d))
4a4d8108
AM
15919+ continue;
15920+
5527c038
JR
15921+ h_inode = d_inode(h_d);
15922+ AuDebugOn(mode != (h_inode->i_mode & S_IFMT));
4a4d8108
AM
15923+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
15924+ h_i = au_h_iptr(inode, bindex);
15925+ if (h_i) {
5527c038 15926+ if (h_i == h_inode)
4a4d8108
AM
15927+ continue;
15928+ err = -EIO;
15929+ break;
15930+ }
15931+ }
15932+ if (bindex < iinfo->ii_bstart)
15933+ iinfo->ii_bstart = bindex;
15934+ if (iinfo->ii_bend < bindex)
15935+ iinfo->ii_bend = bindex;
5527c038 15936+ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags);
4a4d8108 15937+ update = 1;
1308ab2a 15938+ }
4a4d8108
AM
15939+ au_update_ibrange(inode, /*do_put_zero*/0);
15940+ e = au_dy_irefresh(inode);
15941+ if (unlikely(e && !err))
15942+ err = e;
027c5e7a
AM
15943+ if (!err)
15944+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 15945+
4f0767ce 15946+out:
4a4d8108 15947+ AuTraceErr(err);
1308ab2a 15948+ return err;
dece6358
AM
15949+}
15950+
4a4d8108 15951+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 15952+{
4a4d8108
AM
15953+ int err;
15954+ unsigned int flags;
15955+ umode_t mode;
15956+ aufs_bindex_t bindex, bstart, btail;
15957+ unsigned char isdir;
15958+ struct dentry *h_dentry;
15959+ struct inode *h_inode;
15960+ struct au_iinfo *iinfo;
dece6358 15961+
4a4d8108 15962+ IiMustWriteLock(inode);
dece6358 15963+
4a4d8108
AM
15964+ err = 0;
15965+ isdir = 0;
15966+ bstart = au_dbstart(dentry);
5527c038
JR
15967+ h_dentry = au_h_dptr(dentry, bstart);
15968+ h_inode = d_inode(h_dentry);
4a4d8108
AM
15969+ mode = h_inode->i_mode;
15970+ switch (mode & S_IFMT) {
15971+ case S_IFREG:
15972+ btail = au_dbtail(dentry);
15973+ inode->i_op = &aufs_iop;
15974+ inode->i_fop = &aufs_file_fop;
15975+ err = au_dy_iaop(inode, bstart, h_inode);
15976+ if (unlikely(err))
15977+ goto out;
15978+ break;
15979+ case S_IFDIR:
15980+ isdir = 1;
15981+ btail = au_dbtaildir(dentry);
15982+ inode->i_op = &aufs_dir_iop;
15983+ inode->i_fop = &aufs_dir_fop;
15984+ break;
15985+ case S_IFLNK:
15986+ btail = au_dbtail(dentry);
15987+ inode->i_op = &aufs_symlink_iop;
15988+ break;
15989+ case S_IFBLK:
15990+ case S_IFCHR:
15991+ case S_IFIFO:
15992+ case S_IFSOCK:
15993+ btail = au_dbtail(dentry);
15994+ inode->i_op = &aufs_iop;
38d290e6 15995+ init_special_inode(inode, mode, h_inode->i_rdev);
4a4d8108
AM
15996+ break;
15997+ default:
15998+ AuIOErr("Unknown file type 0%o\n", mode);
15999+ err = -EIO;
1308ab2a 16000+ goto out;
4a4d8108 16001+ }
dece6358 16002+
4a4d8108
AM
16003+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
16004+ flags = au_hi_flags(inode, isdir);
16005+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
16006+ && au_ftest_hi(flags, HNOTIFY)
16007+ && dentry->d_name.len > AUFS_WH_PFX_LEN
16008+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
16009+ au_fclr_hi(flags, HNOTIFY);
16010+ iinfo = au_ii(inode);
16011+ iinfo->ii_bstart = bstart;
16012+ iinfo->ii_bend = btail;
16013+ for (bindex = bstart; bindex <= btail; bindex++) {
16014+ h_dentry = au_h_dptr(dentry, bindex);
16015+ if (h_dentry)
16016+ au_set_h_iptr(inode, bindex,
5527c038 16017+ au_igrab(d_inode(h_dentry)), flags);
4a4d8108
AM
16018+ }
16019+ au_cpup_attr_all(inode, /*force*/1);
c1595e42
JR
16020+ /*
16021+ * to force calling aufs_get_acl() every time,
16022+ * do not call cache_no_acl() for aufs inode.
16023+ */
dece6358 16024+
4f0767ce 16025+out:
4a4d8108
AM
16026+ return err;
16027+}
dece6358 16028+
027c5e7a
AM
16029+/*
16030+ * successful returns with iinfo write_locked
16031+ * minus: errno
16032+ * zero: success, matched
16033+ * plus: no error, but unmatched
16034+ */
16035+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
16036+{
16037+ int err;
537831f9
AM
16038+ unsigned int gen;
16039+ struct au_iigen iigen;
4a4d8108
AM
16040+ aufs_bindex_t bindex, bend;
16041+ struct inode *h_inode, *h_dinode;
5527c038 16042+ struct dentry *h_dentry;
dece6358 16043+
4a4d8108
AM
16044+ /*
16045+ * before this function, if aufs got any iinfo lock, it must be only
16046+ * one, the parent dir.
16047+ * it can happen by UDBA and the obsoleted inode number.
16048+ */
16049+ err = -EIO;
16050+ if (unlikely(inode->i_ino == parent_ino(dentry)))
16051+ goto out;
16052+
027c5e7a 16053+ err = 1;
4a4d8108 16054+ ii_write_lock_new_child(inode);
5527c038
JR
16055+ h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
16056+ h_dinode = d_inode(h_dentry);
4a4d8108
AM
16057+ bend = au_ibend(inode);
16058+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
16059+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
16060+ if (!h_inode || h_inode != h_dinode)
16061+ continue;
16062+
16063+ err = 0;
16064+ gen = au_iigen(inode, &iigen);
16065+ if (gen == au_digen(dentry)
16066+ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
4a4d8108 16067+ break;
537831f9
AM
16068+
16069+ /* fully refresh inode using dentry */
16070+ err = au_refresh_hinode(inode, dentry);
16071+ if (!err)
16072+ au_update_iigen(inode, /*half*/0);
16073+ break;
1facf9fc 16074+ }
dece6358 16075+
4a4d8108
AM
16076+ if (unlikely(err))
16077+ ii_write_unlock(inode);
4f0767ce 16078+out:
1facf9fc 16079+ return err;
16080+}
1facf9fc 16081+
4a4d8108
AM
16082+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
16083+ unsigned int d_type, ino_t *ino)
1facf9fc 16084+{
4a4d8108
AM
16085+ int err;
16086+ struct mutex *mtx;
1facf9fc 16087+
b752ccd1 16088+ /* prevent hardlinked inode number from race condition */
4a4d8108 16089+ mtx = NULL;
b752ccd1 16090+ if (d_type != DT_DIR) {
4a4d8108
AM
16091+ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
16092+ mutex_lock(mtx);
16093+ }
16094+ err = au_xino_read(sb, bindex, h_ino, ino);
16095+ if (unlikely(err))
16096+ goto out;
1308ab2a 16097+
4a4d8108
AM
16098+ if (!*ino) {
16099+ err = -EIO;
16100+ *ino = au_xino_new_ino(sb);
16101+ if (unlikely(!*ino))
1facf9fc 16102+ goto out;
4a4d8108
AM
16103+ err = au_xino_write(sb, bindex, h_ino, *ino);
16104+ if (unlikely(err))
1308ab2a 16105+ goto out;
1308ab2a 16106+ }
1facf9fc 16107+
4f0767ce 16108+out:
b752ccd1 16109+ if (mtx)
4a4d8108 16110+ mutex_unlock(mtx);
1facf9fc 16111+ return err;
16112+}
16113+
4a4d8108
AM
16114+/* successful returns with iinfo write_locked */
16115+/* todo: return with unlocked? */
16116+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 16117+{
5527c038 16118+ struct inode *inode, *h_inode;
4a4d8108
AM
16119+ struct dentry *h_dentry;
16120+ struct super_block *sb;
b752ccd1 16121+ struct mutex *mtx;
4a4d8108 16122+ ino_t h_ino, ino;
1716fcea 16123+ int err;
4a4d8108 16124+ aufs_bindex_t bstart;
1facf9fc 16125+
4a4d8108
AM
16126+ sb = dentry->d_sb;
16127+ bstart = au_dbstart(dentry);
16128+ h_dentry = au_h_dptr(dentry, bstart);
5527c038
JR
16129+ h_inode = d_inode(h_dentry);
16130+ h_ino = h_inode->i_ino;
b752ccd1
AM
16131+
16132+ /*
16133+ * stop 'race'-ing between hardlinks under different
16134+ * parents.
16135+ */
16136+ mtx = NULL;
2000de60 16137+ if (!d_is_dir(h_dentry))
b752ccd1
AM
16138+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
16139+
4f0767ce 16140+new_ino:
b752ccd1
AM
16141+ if (mtx)
16142+ mutex_lock(mtx);
4a4d8108
AM
16143+ err = au_xino_read(sb, bstart, h_ino, &ino);
16144+ inode = ERR_PTR(err);
16145+ if (unlikely(err))
16146+ goto out;
b752ccd1 16147+
4a4d8108
AM
16148+ if (!ino) {
16149+ ino = au_xino_new_ino(sb);
16150+ if (unlikely(!ino)) {
16151+ inode = ERR_PTR(-EIO);
dece6358
AM
16152+ goto out;
16153+ }
16154+ }
1facf9fc 16155+
4a4d8108
AM
16156+ AuDbg("i%lu\n", (unsigned long)ino);
16157+ inode = au_iget_locked(sb, ino);
16158+ err = PTR_ERR(inode);
16159+ if (IS_ERR(inode))
1facf9fc 16160+ goto out;
1facf9fc 16161+
4a4d8108
AM
16162+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
16163+ if (inode->i_state & I_NEW) {
1716fcea 16164+ /* verbose coding for lock class name */
2000de60 16165+ if (unlikely(d_is_symlink(h_dentry)))
1716fcea
AM
16166+ au_rw_class(&au_ii(inode)->ii_rwsem,
16167+ au_lc_key + AuLcSymlink_IIINFO);
2000de60 16168+ else if (unlikely(d_is_dir(h_dentry)))
1716fcea
AM
16169+ au_rw_class(&au_ii(inode)->ii_rwsem,
16170+ au_lc_key + AuLcDir_IIINFO);
16171+ else /* likely */
16172+ au_rw_class(&au_ii(inode)->ii_rwsem,
16173+ au_lc_key + AuLcNonDir_IIINFO);
2dfbb274 16174+
4a4d8108
AM
16175+ ii_write_lock_new_child(inode);
16176+ err = set_inode(inode, dentry);
16177+ if (!err) {
16178+ unlock_new_inode(inode);
16179+ goto out; /* success */
16180+ }
1308ab2a 16181+
027c5e7a
AM
16182+ /*
16183+ * iget_failed() calls iput(), but we need to call
16184+ * ii_write_unlock() after iget_failed(). so dirty hack for
16185+ * i_count.
16186+ */
16187+ atomic_inc(&inode->i_count);
4a4d8108 16188+ iget_failed(inode);
027c5e7a
AM
16189+ ii_write_unlock(inode);
16190+ au_xino_write(sb, bstart, h_ino, /*ino*/0);
16191+ /* ignore this error */
16192+ goto out_iput;
16193+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
16194+ /*
16195+ * horrible race condition between lookup, readdir and copyup
16196+ * (or something).
16197+ */
16198+ if (mtx)
16199+ mutex_unlock(mtx);
027c5e7a
AM
16200+ err = reval_inode(inode, dentry);
16201+ if (unlikely(err < 0)) {
16202+ mtx = NULL;
16203+ goto out_iput;
16204+ }
16205+
b752ccd1
AM
16206+ if (!err) {
16207+ mtx = NULL;
4a4d8108 16208+ goto out; /* success */
b752ccd1
AM
16209+ } else if (mtx)
16210+ mutex_lock(mtx);
4a4d8108
AM
16211+ }
16212+
5527c038 16213+ if (unlikely(au_test_fs_unique_ino(h_inode)))
4a4d8108 16214+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3
AM
16215+ " b%d, %s, %pd, hi%lu, i%lu.\n",
16216+ bstart, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
16217+ (unsigned long)h_ino, (unsigned long)ino);
16218+ ino = 0;
16219+ err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
16220+ if (!err) {
16221+ iput(inode);
b752ccd1
AM
16222+ if (mtx)
16223+ mutex_unlock(mtx);
4a4d8108
AM
16224+ goto new_ino;
16225+ }
1308ab2a 16226+
4f0767ce 16227+out_iput:
4a4d8108 16228+ iput(inode);
4a4d8108 16229+ inode = ERR_PTR(err);
4f0767ce 16230+out:
b752ccd1
AM
16231+ if (mtx)
16232+ mutex_unlock(mtx);
4a4d8108 16233+ return inode;
1facf9fc 16234+}
16235+
4a4d8108 16236+/* ---------------------------------------------------------------------- */
1facf9fc 16237+
4a4d8108
AM
16238+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16239+ struct inode *inode)
16240+{
16241+ int err;
076b876e 16242+ struct inode *hi;
1facf9fc 16243+
4a4d8108 16244+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 16245+
4a4d8108
AM
16246+ /* pseudo-link after flushed may happen out of bounds */
16247+ if (!err
16248+ && inode
16249+ && au_ibstart(inode) <= bindex
16250+ && bindex <= au_ibend(inode)) {
16251+ /*
16252+ * permission check is unnecessary since vfsub routine
16253+ * will be called later
16254+ */
076b876e 16255+ hi = au_h_iptr(inode, bindex);
4a4d8108
AM
16256+ if (hi)
16257+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 16258+ }
16259+
4a4d8108
AM
16260+ return err;
16261+}
dece6358 16262+
4a4d8108
AM
16263+int au_test_h_perm(struct inode *h_inode, int mask)
16264+{
2dfbb274 16265+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
16266+ return 0;
16267+ return inode_permission(h_inode, mask);
16268+}
1facf9fc 16269+
4a4d8108
AM
16270+int au_test_h_perm_sio(struct inode *h_inode, int mask)
16271+{
16272+ if (au_test_nfs(h_inode->i_sb)
16273+ && (mask & MAY_WRITE)
16274+ && S_ISDIR(h_inode->i_mode))
16275+ mask |= MAY_READ; /* force permission check */
16276+ return au_test_h_perm(h_inode, mask);
1facf9fc 16277+}
7f207e10
AM
16278diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
16279--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 16280+++ linux/fs/aufs/inode.h 2015-09-24 10:47:58.254719746 +0200
b912730e 16281@@ -0,0 +1,673 @@
4a4d8108 16282+/*
2000de60 16283+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
16284+ *
16285+ * This program, aufs is free software; you can redistribute it and/or modify
16286+ * it under the terms of the GNU General Public License as published by
16287+ * the Free Software Foundation; either version 2 of the License, or
16288+ * (at your option) any later version.
16289+ *
16290+ * This program is distributed in the hope that it will be useful,
16291+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16292+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16293+ * GNU General Public License for more details.
16294+ *
16295+ * You should have received a copy of the GNU General Public License
523b37e3 16296+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 16297+ */
1facf9fc 16298+
1308ab2a 16299+/*
4a4d8108 16300+ * inode operations
1308ab2a 16301+ */
dece6358 16302+
4a4d8108
AM
16303+#ifndef __AUFS_INODE_H__
16304+#define __AUFS_INODE_H__
dece6358 16305+
4a4d8108 16306+#ifdef __KERNEL__
1308ab2a 16307+
4a4d8108 16308+#include <linux/fsnotify.h>
4a4d8108 16309+#include "rwsem.h"
1308ab2a 16310+
4a4d8108 16311+struct vfsmount;
1facf9fc 16312+
4a4d8108
AM
16313+struct au_hnotify {
16314+#ifdef CONFIG_AUFS_HNOTIFY
16315+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 16316+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 16317+ struct fsnotify_mark hn_mark;
4a4d8108 16318+#endif
7f207e10 16319+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
16320+#endif
16321+} ____cacheline_aligned_in_smp;
1facf9fc 16322+
4a4d8108
AM
16323+struct au_hinode {
16324+ struct inode *hi_inode;
16325+ aufs_bindex_t hi_id;
16326+#ifdef CONFIG_AUFS_HNOTIFY
16327+ struct au_hnotify *hi_notify;
16328+#endif
dece6358 16329+
4a4d8108
AM
16330+ /* reference to the copied-up whiteout with get/put */
16331+ struct dentry *hi_whdentry;
16332+};
dece6358 16333+
537831f9
AM
16334+/* ig_flags */
16335+#define AuIG_HALF_REFRESHED 1
16336+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
16337+#define au_ig_fset(flags, name) \
16338+ do { (flags) |= AuIG_##name; } while (0)
16339+#define au_ig_fclr(flags, name) \
16340+ do { (flags) &= ~AuIG_##name; } while (0)
16341+
16342+struct au_iigen {
16343+ __u32 ig_generation, ig_flags;
16344+};
16345+
4a4d8108
AM
16346+struct au_vdir;
16347+struct au_iinfo {
537831f9 16348+ spinlock_t ii_genspin;
7a9e40b8 16349+ struct au_iigen ii_generation;
4a4d8108 16350+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 16351+
4a4d8108
AM
16352+ struct au_rwsem ii_rwsem;
16353+ aufs_bindex_t ii_bstart, ii_bend;
16354+ __u32 ii_higen;
16355+ struct au_hinode *ii_hinode;
16356+ struct au_vdir *ii_vdir;
16357+};
1facf9fc 16358+
4a4d8108
AM
16359+struct au_icntnr {
16360+ struct au_iinfo iinfo;
16361+ struct inode vfs_inode;
16362+} ____cacheline_aligned_in_smp;
1308ab2a 16363+
4a4d8108
AM
16364+/* au_pin flags */
16365+#define AuPin_DI_LOCKED 1
16366+#define AuPin_MNT_WRITE (1 << 1)
16367+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
16368+#define au_fset_pin(flags, name) \
16369+ do { (flags) |= AuPin_##name; } while (0)
16370+#define au_fclr_pin(flags, name) \
16371+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
16372+
16373+struct au_pin {
16374+ /* input */
16375+ struct dentry *dentry;
16376+ unsigned int udba;
16377+ unsigned char lsc_di, lsc_hi, flags;
16378+ aufs_bindex_t bindex;
16379+
16380+ /* output */
16381+ struct dentry *parent;
16382+ struct au_hinode *hdir;
16383+ struct vfsmount *h_mnt;
86dc4139
AM
16384+
16385+ /* temporary unlock/relock for copyup */
16386+ struct dentry *h_dentry, *h_parent;
16387+ struct au_branch *br;
16388+ struct task_struct *task;
4a4d8108 16389+};
1facf9fc 16390+
86dc4139 16391+void au_pin_hdir_unlock(struct au_pin *p);
c1595e42 16392+int au_pin_hdir_lock(struct au_pin *p);
86dc4139
AM
16393+int au_pin_hdir_relock(struct au_pin *p);
16394+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
16395+void au_pin_hdir_acquire_nest(struct au_pin *p);
16396+void au_pin_hdir_release(struct au_pin *p);
16397+
1308ab2a 16398+/* ---------------------------------------------------------------------- */
16399+
4a4d8108 16400+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 16401+{
4a4d8108 16402+ struct au_iinfo *iinfo;
1facf9fc 16403+
4a4d8108
AM
16404+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
16405+ if (iinfo->ii_hinode)
16406+ return iinfo;
16407+ return NULL; /* debugging bad_inode case */
16408+}
1facf9fc 16409+
4a4d8108 16410+/* ---------------------------------------------------------------------- */
1facf9fc 16411+
4a4d8108
AM
16412+/* inode.c */
16413+struct inode *au_igrab(struct inode *inode);
027c5e7a 16414+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
16415+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
16416+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
16417+ unsigned int d_type, ino_t *ino);
16418+struct inode *au_new_inode(struct dentry *dentry, int must_new);
16419+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16420+ struct inode *inode);
16421+int au_test_h_perm(struct inode *h_inode, int mask);
16422+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 16423+
4a4d8108
AM
16424+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
16425+ ino_t h_ino, unsigned int d_type, ino_t *ino)
16426+{
16427+#ifdef CONFIG_AUFS_SHWH
16428+ return au_ino(sb, bindex, h_ino, d_type, ino);
16429+#else
16430+ return 0;
16431+#endif
16432+}
1facf9fc 16433+
4a4d8108
AM
16434+/* i_op.c */
16435+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
1308ab2a 16436+
4a4d8108
AM
16437+/* au_wr_dir flags */
16438+#define AuWrDir_ADD_ENTRY 1
7e9cd9fe
AM
16439+#define AuWrDir_ISDIR (1 << 1)
16440+#define AuWrDir_TMPFILE (1 << 2)
4a4d8108 16441+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
16442+#define au_fset_wrdir(flags, name) \
16443+ do { (flags) |= AuWrDir_##name; } while (0)
16444+#define au_fclr_wrdir(flags, name) \
16445+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 16446+
4a4d8108
AM
16447+struct au_wr_dir_args {
16448+ aufs_bindex_t force_btgt;
16449+ unsigned char flags;
16450+};
16451+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16452+ struct au_wr_dir_args *args);
dece6358 16453+
4a4d8108
AM
16454+struct dentry *au_pinned_h_parent(struct au_pin *pin);
16455+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
16456+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
16457+ unsigned int udba, unsigned char flags);
16458+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
16459+ unsigned int udba, unsigned char flags) __must_check;
16460+int au_do_pin(struct au_pin *pin) __must_check;
16461+void au_unpin(struct au_pin *pin);
c1595e42
JR
16462+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
16463+
16464+#define AuIcpup_DID_CPUP 1
16465+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
16466+#define au_fset_icpup(flags, name) \
16467+ do { (flags) |= AuIcpup_##name; } while (0)
16468+#define au_fclr_icpup(flags, name) \
16469+ do { (flags) &= ~AuIcpup_##name; } while (0)
16470+
16471+struct au_icpup_args {
16472+ unsigned char flags;
16473+ unsigned char pin_flags;
16474+ aufs_bindex_t btgt;
16475+ unsigned int udba;
16476+ struct au_pin pin;
16477+ struct path h_path;
16478+ struct inode *h_inode;
16479+};
16480+
16481+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
16482+ struct au_icpup_args *a);
16483+
16484+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path);
1facf9fc 16485+
4a4d8108
AM
16486+/* i_op_add.c */
16487+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
16488+ struct dentry *h_parent, int isdir);
7eafdf33
AM
16489+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
16490+ dev_t dev);
4a4d8108 16491+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 16492+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 16493+ bool want_excl);
b912730e
AM
16494+struct vfsub_aopen_args;
16495+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
16496+ struct vfsub_aopen_args *args);
38d290e6 16497+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
4a4d8108
AM
16498+int aufs_link(struct dentry *src_dentry, struct inode *dir,
16499+ struct dentry *dentry);
7eafdf33 16500+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 16501+
4a4d8108
AM
16502+/* i_op_del.c */
16503+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
16504+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
16505+ struct dentry *h_parent, int isdir);
16506+int aufs_unlink(struct inode *dir, struct dentry *dentry);
16507+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 16508+
4a4d8108
AM
16509+/* i_op_ren.c */
16510+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
16511+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
16512+ struct inode *dir, struct dentry *dentry);
1facf9fc 16513+
4a4d8108
AM
16514+/* iinfo.c */
16515+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
16516+void au_hiput(struct au_hinode *hinode);
16517+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
16518+ struct dentry *h_wh);
16519+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 16520+
4a4d8108
AM
16521+/* hinode flags */
16522+#define AuHi_XINO 1
16523+#define AuHi_HNOTIFY (1 << 1)
16524+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
16525+#define au_fset_hi(flags, name) \
16526+ do { (flags) |= AuHi_##name; } while (0)
16527+#define au_fclr_hi(flags, name) \
16528+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 16529+
4a4d8108
AM
16530+#ifndef CONFIG_AUFS_HNOTIFY
16531+#undef AuHi_HNOTIFY
16532+#define AuHi_HNOTIFY 0
16533+#endif
1facf9fc 16534+
4a4d8108
AM
16535+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
16536+ struct inode *h_inode, unsigned int flags);
1facf9fc 16537+
537831f9 16538+void au_update_iigen(struct inode *inode, int half);
4a4d8108 16539+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 16540+
4a4d8108
AM
16541+void au_icntnr_init_once(void *_c);
16542+int au_iinfo_init(struct inode *inode);
16543+void au_iinfo_fin(struct inode *inode);
16544+int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
1308ab2a 16545+
e49829fe 16546+#ifdef CONFIG_PROC_FS
4a4d8108 16547+/* plink.c */
e49829fe 16548+int au_plink_maint(struct super_block *sb, int flags);
7e9cd9fe 16549+struct au_sbinfo;
e49829fe
JR
16550+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
16551+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
16552+#ifdef CONFIG_AUFS_DEBUG
16553+void au_plink_list(struct super_block *sb);
16554+#else
16555+AuStubVoid(au_plink_list, struct super_block *sb)
16556+#endif
16557+int au_plink_test(struct inode *inode);
16558+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
16559+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
16560+ struct dentry *h_dentry);
e49829fe
JR
16561+void au_plink_put(struct super_block *sb, int verbose);
16562+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 16563+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
16564+#else
16565+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
16566+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
16567+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
16568+AuStubVoid(au_plink_list, struct super_block *sb);
16569+AuStubInt0(au_plink_test, struct inode *inode);
16570+AuStub(struct dentry *, au_plink_lkup, return NULL,
16571+ struct inode *inode, aufs_bindex_t bindex);
16572+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
16573+ struct dentry *h_dentry);
16574+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
16575+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
16576+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
16577+#endif /* CONFIG_PROC_FS */
1facf9fc 16578+
c1595e42
JR
16579+#ifdef CONFIG_AUFS_XATTR
16580+/* xattr.c */
7e9cd9fe
AM
16581+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
16582+ unsigned int verbose);
c1595e42
JR
16583+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
16584+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
16585+ size_t size);
16586+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
16587+ size_t size, int flags);
16588+int aufs_removexattr(struct dentry *dentry, const char *name);
16589+
16590+/* void au_xattr_init(struct super_block *sb); */
16591+#else
16592+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe 16593+ int ignore_flags, unsigned int verbose);
c1595e42
JR
16594+/* AuStubVoid(au_xattr_init, struct super_block *sb); */
16595+#endif
16596+
16597+#ifdef CONFIG_FS_POSIX_ACL
16598+struct posix_acl *aufs_get_acl(struct inode *inode, int type);
16599+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
16600+#endif
16601+
16602+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
16603+enum {
16604+ AU_XATTR_SET,
16605+ AU_XATTR_REMOVE,
16606+ AU_ACL_SET
16607+};
16608+
16609+struct au_srxattr {
16610+ int type;
16611+ union {
16612+ struct {
16613+ const char *name;
16614+ const void *value;
16615+ size_t size;
16616+ int flags;
16617+ } set;
16618+ struct {
16619+ const char *name;
16620+ } remove;
16621+ struct {
16622+ struct posix_acl *acl;
16623+ int type;
16624+ } acl_set;
16625+ } u;
16626+};
16627+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg);
16628+#endif
16629+
4a4d8108 16630+/* ---------------------------------------------------------------------- */
1308ab2a 16631+
4a4d8108
AM
16632+/* lock subclass for iinfo */
16633+enum {
16634+ AuLsc_II_CHILD, /* child first */
16635+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
16636+ AuLsc_II_CHILD3, /* copyup dirs */
16637+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
16638+ AuLsc_II_PARENT2,
16639+ AuLsc_II_PARENT3, /* copyup dirs */
16640+ AuLsc_II_NEW_CHILD
16641+};
1308ab2a 16642+
1facf9fc 16643+/*
4a4d8108
AM
16644+ * ii_read_lock_child, ii_write_lock_child,
16645+ * ii_read_lock_child2, ii_write_lock_child2,
16646+ * ii_read_lock_child3, ii_write_lock_child3,
16647+ * ii_read_lock_parent, ii_write_lock_parent,
16648+ * ii_read_lock_parent2, ii_write_lock_parent2,
16649+ * ii_read_lock_parent3, ii_write_lock_parent3,
16650+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 16651+ */
4a4d8108
AM
16652+#define AuReadLockFunc(name, lsc) \
16653+static inline void ii_read_lock_##name(struct inode *i) \
16654+{ \
16655+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
16656+}
16657+
16658+#define AuWriteLockFunc(name, lsc) \
16659+static inline void ii_write_lock_##name(struct inode *i) \
16660+{ \
16661+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
16662+}
16663+
16664+#define AuRWLockFuncs(name, lsc) \
16665+ AuReadLockFunc(name, lsc) \
16666+ AuWriteLockFunc(name, lsc)
16667+
16668+AuRWLockFuncs(child, CHILD);
16669+AuRWLockFuncs(child2, CHILD2);
16670+AuRWLockFuncs(child3, CHILD3);
16671+AuRWLockFuncs(parent, PARENT);
16672+AuRWLockFuncs(parent2, PARENT2);
16673+AuRWLockFuncs(parent3, PARENT3);
16674+AuRWLockFuncs(new_child, NEW_CHILD);
16675+
16676+#undef AuReadLockFunc
16677+#undef AuWriteLockFunc
16678+#undef AuRWLockFuncs
1facf9fc 16679+
16680+/*
4a4d8108 16681+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 16682+ */
4a4d8108 16683+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 16684+
4a4d8108
AM
16685+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
16686+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
16687+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 16688+
4a4d8108 16689+/* ---------------------------------------------------------------------- */
1308ab2a 16690+
027c5e7a
AM
16691+static inline void au_icntnr_init(struct au_icntnr *c)
16692+{
16693+#ifdef CONFIG_AUFS_DEBUG
16694+ c->vfs_inode.i_mode = 0;
16695+#endif
16696+}
16697+
537831f9 16698+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
4a4d8108 16699+{
537831f9
AM
16700+ unsigned int gen;
16701+ struct au_iinfo *iinfo;
16702+
16703+ iinfo = au_ii(inode);
16704+ spin_lock(&iinfo->ii_genspin);
16705+ if (iigen)
16706+ *iigen = iinfo->ii_generation;
16707+ gen = iinfo->ii_generation.ig_generation;
16708+ spin_unlock(&iinfo->ii_genspin);
16709+
16710+ return gen;
4a4d8108 16711+}
1308ab2a 16712+
4a4d8108
AM
16713+/* tiny test for inode number */
16714+/* tmpfs generation is too rough */
16715+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
16716+{
16717+ struct au_iinfo *iinfo;
1308ab2a 16718+
4a4d8108
AM
16719+ iinfo = au_ii(inode);
16720+ AuRwMustAnyLock(&iinfo->ii_rwsem);
16721+ return !(iinfo->ii_hsb1 == h_inode->i_sb
16722+ && iinfo->ii_higen == h_inode->i_generation);
16723+}
1308ab2a 16724+
4a4d8108
AM
16725+static inline void au_iigen_dec(struct inode *inode)
16726+{
537831f9
AM
16727+ struct au_iinfo *iinfo;
16728+
16729+ iinfo = au_ii(inode);
16730+ spin_lock(&iinfo->ii_genspin);
16731+ iinfo->ii_generation.ig_generation--;
16732+ spin_unlock(&iinfo->ii_genspin);
027c5e7a
AM
16733+}
16734+
16735+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
16736+{
16737+ int err;
16738+
16739+ err = 0;
537831f9 16740+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
16741+ err = -EIO;
16742+
16743+ return err;
4a4d8108 16744+}
1308ab2a 16745+
4a4d8108 16746+/* ---------------------------------------------------------------------- */
1308ab2a 16747+
4a4d8108
AM
16748+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
16749+ aufs_bindex_t bindex)
16750+{
16751+ IiMustAnyLock(inode);
16752+ return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
16753+}
1308ab2a 16754+
4a4d8108
AM
16755+static inline aufs_bindex_t au_ibstart(struct inode *inode)
16756+{
16757+ IiMustAnyLock(inode);
16758+ return au_ii(inode)->ii_bstart;
16759+}
1308ab2a 16760+
4a4d8108
AM
16761+static inline aufs_bindex_t au_ibend(struct inode *inode)
16762+{
16763+ IiMustAnyLock(inode);
16764+ return au_ii(inode)->ii_bend;
16765+}
1308ab2a 16766+
4a4d8108
AM
16767+static inline struct au_vdir *au_ivdir(struct inode *inode)
16768+{
16769+ IiMustAnyLock(inode);
16770+ return au_ii(inode)->ii_vdir;
16771+}
1308ab2a 16772+
4a4d8108
AM
16773+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
16774+{
16775+ IiMustAnyLock(inode);
16776+ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
16777+}
1308ab2a 16778+
4a4d8108 16779+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 16780+{
4a4d8108
AM
16781+ IiMustWriteLock(inode);
16782+ au_ii(inode)->ii_bstart = bindex;
16783+}
1308ab2a 16784+
4a4d8108
AM
16785+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
16786+{
16787+ IiMustWriteLock(inode);
16788+ au_ii(inode)->ii_bend = bindex;
1308ab2a 16789+}
16790+
4a4d8108
AM
16791+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
16792+{
16793+ IiMustWriteLock(inode);
16794+ au_ii(inode)->ii_vdir = vdir;
16795+}
1facf9fc 16796+
4a4d8108 16797+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 16798+{
4a4d8108
AM
16799+ IiMustAnyLock(inode);
16800+ return au_ii(inode)->ii_hinode + bindex;
16801+}
dece6358 16802+
4a4d8108 16803+/* ---------------------------------------------------------------------- */
1facf9fc 16804+
4a4d8108
AM
16805+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
16806+{
16807+ if (pin)
16808+ return pin->parent;
16809+ return NULL;
1facf9fc 16810+}
16811+
4a4d8108 16812+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 16813+{
4a4d8108
AM
16814+ if (pin && pin->hdir)
16815+ return pin->hdir->hi_inode;
16816+ return NULL;
1308ab2a 16817+}
1facf9fc 16818+
4a4d8108
AM
16819+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
16820+{
16821+ if (pin)
16822+ return pin->hdir;
16823+ return NULL;
16824+}
1facf9fc 16825+
4a4d8108 16826+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 16827+{
4a4d8108
AM
16828+ if (pin)
16829+ pin->dentry = dentry;
16830+}
1308ab2a 16831+
4a4d8108
AM
16832+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
16833+ unsigned char lflag)
16834+{
16835+ if (pin) {
7f207e10 16836+ if (lflag)
4a4d8108 16837+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 16838+ else
4a4d8108 16839+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 16840+ }
4a4d8108
AM
16841+}
16842+
7e9cd9fe 16843+#if 0 /* reserved */
4a4d8108
AM
16844+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
16845+{
16846+ if (pin) {
16847+ dput(pin->parent);
16848+ pin->parent = dget(parent);
1facf9fc 16849+ }
4a4d8108 16850+}
7e9cd9fe 16851+#endif
1facf9fc 16852+
4a4d8108
AM
16853+/* ---------------------------------------------------------------------- */
16854+
027c5e7a 16855+struct au_branch;
4a4d8108
AM
16856+#ifdef CONFIG_AUFS_HNOTIFY
16857+struct au_hnotify_op {
16858+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 16859+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
16860+
16861+ /*
16862+ * if it returns true, the the caller should free hinode->hi_notify,
16863+ * otherwise ->free() frees it.
16864+ */
16865+ int (*free)(struct au_hinode *hinode,
16866+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
16867+
16868+ void (*fin)(void);
16869+ int (*init)(void);
027c5e7a
AM
16870+
16871+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
16872+ void (*fin_br)(struct au_branch *br);
16873+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
16874+};
16875+
16876+/* hnotify.c */
027c5e7a 16877+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
16878+void au_hn_free(struct au_hinode *hinode);
16879+void au_hn_ctl(struct au_hinode *hinode, int do_set);
16880+void au_hn_reset(struct inode *inode, unsigned int flags);
16881+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
16882+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
16883+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
16884+int au_hnotify_init_br(struct au_branch *br, int perm);
16885+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
16886+int __init au_hnotify_init(void);
16887+void au_hnotify_fin(void);
16888+
7f207e10 16889+/* hfsnotify.c */
4a4d8108
AM
16890+extern const struct au_hnotify_op au_hnotify_op;
16891+
16892+static inline
16893+void au_hn_init(struct au_hinode *hinode)
16894+{
16895+ hinode->hi_notify = NULL;
1308ab2a 16896+}
16897+
53392da6
AM
16898+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
16899+{
16900+ return hinode->hi_notify;
16901+}
16902+
4a4d8108 16903+#else
c1595e42
JR
16904+AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
16905+ struct au_hinode *hinode __maybe_unused,
16906+ struct inode *inode __maybe_unused)
16907+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
4a4d8108
AM
16908+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
16909+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
16910+ int do_set __maybe_unused)
16911+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
16912+ unsigned int flags __maybe_unused)
027c5e7a
AM
16913+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
16914+ struct au_branch *br __maybe_unused,
16915+ int perm __maybe_unused)
16916+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
16917+ int perm __maybe_unused)
16918+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
16919+AuStubInt0(__init au_hnotify_init, void)
16920+AuStubVoid(au_hnotify_fin, void)
16921+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
16922+#endif /* CONFIG_AUFS_HNOTIFY */
16923+
16924+static inline void au_hn_suspend(struct au_hinode *hdir)
16925+{
16926+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 16927+}
16928+
4a4d8108 16929+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 16930+{
4a4d8108
AM
16931+ au_hn_ctl(hdir, /*do_set*/1);
16932+}
1308ab2a 16933+
4a4d8108
AM
16934+static inline void au_hn_imtx_lock(struct au_hinode *hdir)
16935+{
16936+ mutex_lock(&hdir->hi_inode->i_mutex);
16937+ au_hn_suspend(hdir);
16938+}
dece6358 16939+
4a4d8108
AM
16940+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
16941+ unsigned int sc __maybe_unused)
16942+{
16943+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
16944+ au_hn_suspend(hdir);
1facf9fc 16945+}
1facf9fc 16946+
4a4d8108
AM
16947+static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
16948+{
16949+ au_hn_resume(hdir);
16950+ mutex_unlock(&hdir->hi_inode->i_mutex);
16951+}
16952+
16953+#endif /* __KERNEL__ */
16954+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
16955diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
16956--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 16957+++ linux/fs/aufs/ioctl.c 2015-09-24 10:47:58.254719746 +0200
c1595e42 16958@@ -0,0 +1,219 @@
4a4d8108 16959+/*
2000de60 16960+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
16961+ *
16962+ * This program, aufs is free software; you can redistribute it and/or modify
16963+ * it under the terms of the GNU General Public License as published by
16964+ * the Free Software Foundation; either version 2 of the License, or
16965+ * (at your option) any later version.
16966+ *
16967+ * This program is distributed in the hope that it will be useful,
16968+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16969+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16970+ * GNU General Public License for more details.
16971+ *
16972+ * You should have received a copy of the GNU General Public License
523b37e3 16973+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16974+ */
16975+
16976+/*
16977+ * ioctl
16978+ * plink-management and readdir in userspace.
16979+ * assist the pathconf(3) wrapper library.
c2b27bf2 16980+ * move-down
076b876e 16981+ * File-based Hierarchical Storage Management.
4a4d8108
AM
16982+ */
16983+
c2b27bf2
AM
16984+#include <linux/compat.h>
16985+#include <linux/file.h>
4a4d8108
AM
16986+#include "aufs.h"
16987+
1e00d052 16988+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
16989+{
16990+ int err, fd;
16991+ aufs_bindex_t wbi, bindex, bend;
16992+ struct file *h_file;
16993+ struct super_block *sb;
16994+ struct dentry *root;
1e00d052
AM
16995+ struct au_branch *br;
16996+ struct aufs_wbr_fd wbrfd = {
16997+ .oflags = au_dir_roflags,
16998+ .brid = -1
16999+ };
17000+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
17001+ | O_NOATIME | O_CLOEXEC;
4a4d8108 17002+
1e00d052
AM
17003+ AuDebugOn(wbrfd.oflags & ~valid);
17004+
17005+ if (arg) {
17006+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
17007+ if (unlikely(err)) {
17008+ err = -EFAULT;
17009+ goto out;
17010+ }
17011+
17012+ err = -EINVAL;
17013+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
17014+ wbrfd.oflags |= au_dir_roflags;
17015+ AuDbg("0%o\n", wbrfd.oflags);
17016+ if (unlikely(wbrfd.oflags & ~valid))
17017+ goto out;
17018+ }
17019+
2000de60 17020+ fd = get_unused_fd_flags(0);
1e00d052
AM
17021+ err = fd;
17022+ if (unlikely(fd < 0))
4a4d8108 17023+ goto out;
4a4d8108 17024+
1e00d052 17025+ h_file = ERR_PTR(-EINVAL);
4a4d8108 17026+ wbi = 0;
1e00d052 17027+ br = NULL;
4a4d8108
AM
17028+ sb = path->dentry->d_sb;
17029+ root = sb->s_root;
17030+ aufs_read_lock(root, AuLock_IR);
1e00d052
AM
17031+ bend = au_sbend(sb);
17032+ if (wbrfd.brid >= 0) {
17033+ wbi = au_br_index(sb, wbrfd.brid);
17034+ if (unlikely(wbi < 0 || wbi > bend))
17035+ goto out_unlock;
17036+ }
17037+
17038+ h_file = ERR_PTR(-ENOENT);
17039+ br = au_sbr(sb, wbi);
17040+ if (!au_br_writable(br->br_perm)) {
17041+ if (arg)
17042+ goto out_unlock;
17043+
17044+ bindex = wbi + 1;
17045+ wbi = -1;
17046+ for (; bindex <= bend; bindex++) {
17047+ br = au_sbr(sb, bindex);
17048+ if (au_br_writable(br->br_perm)) {
4a4d8108 17049+ wbi = bindex;
1e00d052 17050+ br = au_sbr(sb, wbi);
4a4d8108
AM
17051+ break;
17052+ }
17053+ }
4a4d8108
AM
17054+ }
17055+ AuDbg("wbi %d\n", wbi);
1e00d052 17056+ if (wbi >= 0)
392086de
AM
17057+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
17058+ /*force_wr*/0);
1e00d052
AM
17059+
17060+out_unlock:
4a4d8108
AM
17061+ aufs_read_unlock(root, AuLock_IR);
17062+ err = PTR_ERR(h_file);
17063+ if (IS_ERR(h_file))
17064+ goto out_fd;
17065+
1e00d052 17066+ atomic_dec(&br->br_count); /* cf. au_h_open() */
4a4d8108
AM
17067+ fd_install(fd, h_file);
17068+ err = fd;
17069+ goto out; /* success */
17070+
4f0767ce 17071+out_fd:
4a4d8108 17072+ put_unused_fd(fd);
4f0767ce 17073+out:
1e00d052 17074+ AuTraceErr(err);
4a4d8108
AM
17075+ return err;
17076+}
17077+
17078+/* ---------------------------------------------------------------------- */
17079+
17080+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
17081+{
17082+ long err;
c1595e42 17083+ struct dentry *dentry;
4a4d8108
AM
17084+
17085+ switch (cmd) {
4a4d8108
AM
17086+ case AUFS_CTL_RDU:
17087+ case AUFS_CTL_RDU_INO:
17088+ err = au_rdu_ioctl(file, cmd, arg);
17089+ break;
17090+
17091+ case AUFS_CTL_WBR_FD:
1e00d052 17092+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
17093+ break;
17094+
027c5e7a
AM
17095+ case AUFS_CTL_IBUSY:
17096+ err = au_ibusy_ioctl(file, arg);
17097+ break;
17098+
076b876e
AM
17099+ case AUFS_CTL_BRINFO:
17100+ err = au_brinfo_ioctl(file, arg);
17101+ break;
17102+
17103+ case AUFS_CTL_FHSM_FD:
2000de60 17104+ dentry = file->f_path.dentry;
c1595e42
JR
17105+ if (IS_ROOT(dentry))
17106+ err = au_fhsm_fd(dentry->d_sb, arg);
17107+ else
17108+ err = -ENOTTY;
076b876e
AM
17109+ break;
17110+
4a4d8108
AM
17111+ default:
17112+ /* do not call the lower */
17113+ AuDbg("0x%x\n", cmd);
17114+ err = -ENOTTY;
17115+ }
17116+
17117+ AuTraceErr(err);
17118+ return err;
17119+}
17120+
17121+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
17122+{
17123+ long err;
17124+
17125+ switch (cmd) {
c2b27bf2 17126+ case AUFS_CTL_MVDOWN:
2000de60 17127+ err = au_mvdown(file->f_path.dentry, (void __user *)arg);
c2b27bf2
AM
17128+ break;
17129+
4a4d8108 17130+ case AUFS_CTL_WBR_FD:
1e00d052 17131+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
17132+ break;
17133+
17134+ default:
17135+ /* do not call the lower */
17136+ AuDbg("0x%x\n", cmd);
17137+ err = -ENOTTY;
17138+ }
17139+
17140+ AuTraceErr(err);
17141+ return err;
17142+}
b752ccd1
AM
17143+
17144+#ifdef CONFIG_COMPAT
17145+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
17146+ unsigned long arg)
17147+{
17148+ long err;
17149+
17150+ switch (cmd) {
17151+ case AUFS_CTL_RDU:
17152+ case AUFS_CTL_RDU_INO:
17153+ err = au_rdu_compat_ioctl(file, cmd, arg);
17154+ break;
17155+
027c5e7a
AM
17156+ case AUFS_CTL_IBUSY:
17157+ err = au_ibusy_compat_ioctl(file, arg);
17158+ break;
17159+
076b876e
AM
17160+ case AUFS_CTL_BRINFO:
17161+ err = au_brinfo_compat_ioctl(file, arg);
17162+ break;
17163+
b752ccd1
AM
17164+ default:
17165+ err = aufs_ioctl_dir(file, cmd, arg);
17166+ }
17167+
17168+ AuTraceErr(err);
17169+ return err;
17170+}
17171+
b752ccd1
AM
17172+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
17173+ unsigned long arg)
17174+{
17175+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
17176+}
17177+#endif
7f207e10
AM
17178diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
17179--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 17180+++ linux/fs/aufs/i_op_add.c 2015-09-24 10:47:58.254719746 +0200
5527c038 17181@@ -0,0 +1,932 @@
4a4d8108 17182+/*
2000de60 17183+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
17184+ *
17185+ * This program, aufs is free software; you can redistribute it and/or modify
17186+ * it under the terms of the GNU General Public License as published by
17187+ * the Free Software Foundation; either version 2 of the License, or
17188+ * (at your option) any later version.
17189+ *
17190+ * This program is distributed in the hope that it will be useful,
17191+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17192+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17193+ * GNU General Public License for more details.
17194+ *
17195+ * You should have received a copy of the GNU General Public License
523b37e3 17196+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
17197+ */
17198+
17199+/*
17200+ * inode operations (add entry)
17201+ */
17202+
17203+#include "aufs.h"
17204+
17205+/*
17206+ * final procedure of adding a new entry, except link(2).
17207+ * remove whiteout, instantiate, copyup the parent dir's times and size
17208+ * and update version.
17209+ * if it failed, re-create the removed whiteout.
17210+ */
17211+static int epilog(struct inode *dir, aufs_bindex_t bindex,
17212+ struct dentry *wh_dentry, struct dentry *dentry)
17213+{
17214+ int err, rerr;
17215+ aufs_bindex_t bwh;
17216+ struct path h_path;
076b876e 17217+ struct super_block *sb;
4a4d8108
AM
17218+ struct inode *inode, *h_dir;
17219+ struct dentry *wh;
17220+
17221+ bwh = -1;
076b876e 17222+ sb = dir->i_sb;
4a4d8108 17223+ if (wh_dentry) {
5527c038 17224+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
4a4d8108
AM
17225+ IMustLock(h_dir);
17226+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
17227+ bwh = au_dbwh(dentry);
17228+ h_path.dentry = wh_dentry;
076b876e 17229+ h_path.mnt = au_sbr_mnt(sb, bindex);
4a4d8108
AM
17230+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
17231+ dentry);
17232+ if (unlikely(err))
17233+ goto out;
17234+ }
17235+
17236+ inode = au_new_inode(dentry, /*must_new*/1);
17237+ if (!IS_ERR(inode)) {
17238+ d_instantiate(dentry, inode);
5527c038 17239+ dir = d_inode(dentry->d_parent); /* dir inode is locked */
4a4d8108 17240+ IMustLock(dir);
b912730e 17241+ au_dir_ts(dir, bindex);
4a4d8108 17242+ dir->i_version++;
076b876e 17243+ au_fhsm_wrote(sb, bindex, /*force*/0);
4a4d8108
AM
17244+ return 0; /* success */
17245+ }
17246+
17247+ err = PTR_ERR(inode);
17248+ if (!wh_dentry)
17249+ goto out;
17250+
17251+ /* revert */
17252+ /* dir inode is locked */
17253+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
17254+ rerr = PTR_ERR(wh);
17255+ if (IS_ERR(wh)) {
523b37e3
AM
17256+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
17257+ dentry, err, rerr);
4a4d8108
AM
17258+ err = -EIO;
17259+ } else
17260+ dput(wh);
17261+
4f0767ce 17262+out:
4a4d8108
AM
17263+ return err;
17264+}
17265+
027c5e7a
AM
17266+static int au_d_may_add(struct dentry *dentry)
17267+{
17268+ int err;
17269+
17270+ err = 0;
17271+ if (unlikely(d_unhashed(dentry)))
17272+ err = -ENOENT;
5527c038 17273+ if (unlikely(d_really_is_positive(dentry)))
027c5e7a
AM
17274+ err = -EEXIST;
17275+ return err;
17276+}
17277+
4a4d8108
AM
17278+/*
17279+ * simple tests for the adding inode operations.
17280+ * following the checks in vfs, plus the parent-child relationship.
17281+ */
17282+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
17283+ struct dentry *h_parent, int isdir)
17284+{
17285+ int err;
17286+ umode_t h_mode;
17287+ struct dentry *h_dentry;
17288+ struct inode *h_inode;
17289+
17290+ err = -ENAMETOOLONG;
17291+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17292+ goto out;
17293+
17294+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 17295+ if (d_really_is_negative(dentry)) {
4a4d8108 17296+ err = -EEXIST;
5527c038 17297+ if (unlikely(d_is_positive(h_dentry)))
4a4d8108
AM
17298+ goto out;
17299+ } else {
17300+ /* rename(2) case */
17301+ err = -EIO;
5527c038
JR
17302+ if (unlikely(d_is_negative(h_dentry)))
17303+ goto out;
17304+ h_inode = d_inode(h_dentry);
17305+ if (unlikely(!h_inode->i_nlink))
4a4d8108
AM
17306+ goto out;
17307+
17308+ h_mode = h_inode->i_mode;
17309+ if (!isdir) {
17310+ err = -EISDIR;
17311+ if (unlikely(S_ISDIR(h_mode)))
17312+ goto out;
17313+ } else if (unlikely(!S_ISDIR(h_mode))) {
17314+ err = -ENOTDIR;
17315+ goto out;
17316+ }
17317+ }
17318+
17319+ err = 0;
17320+ /* expected parent dir is locked */
17321+ if (unlikely(h_parent != h_dentry->d_parent))
17322+ err = -EIO;
17323+
4f0767ce 17324+out:
4a4d8108
AM
17325+ AuTraceErr(err);
17326+ return err;
17327+}
17328+
17329+/*
17330+ * initial procedure of adding a new entry.
17331+ * prepare writable branch and the parent dir, lock it,
17332+ * and lookup whiteout for the new entry.
17333+ */
17334+static struct dentry*
17335+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
17336+ struct dentry *src_dentry, struct au_pin *pin,
17337+ struct au_wr_dir_args *wr_dir_args)
17338+{
17339+ struct dentry *wh_dentry, *h_parent;
17340+ struct super_block *sb;
17341+ struct au_branch *br;
17342+ int err;
17343+ unsigned int udba;
17344+ aufs_bindex_t bcpup;
17345+
523b37e3 17346+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17347+
17348+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
17349+ bcpup = err;
17350+ wh_dentry = ERR_PTR(err);
17351+ if (unlikely(err < 0))
17352+ goto out;
17353+
17354+ sb = dentry->d_sb;
17355+ udba = au_opt_udba(sb);
17356+ err = au_pin(pin, dentry, bcpup, udba,
17357+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17358+ wh_dentry = ERR_PTR(err);
17359+ if (unlikely(err))
17360+ goto out;
17361+
17362+ h_parent = au_pinned_h_parent(pin);
17363+ if (udba != AuOpt_UDBA_NONE
17364+ && au_dbstart(dentry) == bcpup)
17365+ err = au_may_add(dentry, bcpup, h_parent,
17366+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
17367+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17368+ err = -ENAMETOOLONG;
17369+ wh_dentry = ERR_PTR(err);
17370+ if (unlikely(err))
17371+ goto out_unpin;
17372+
17373+ br = au_sbr(sb, bcpup);
17374+ if (dt) {
17375+ struct path tmp = {
17376+ .dentry = h_parent,
86dc4139 17377+ .mnt = au_br_mnt(br)
4a4d8108
AM
17378+ };
17379+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
17380+ }
17381+
17382+ wh_dentry = NULL;
17383+ if (bcpup != au_dbwh(dentry))
17384+ goto out; /* success */
17385+
2000de60
JR
17386+ /*
17387+ * ENAMETOOLONG here means that if we allowed create such name, then it
17388+ * would not be able to removed in the future. So we don't allow such
17389+ * name here and we don't handle ENAMETOOLONG differently here.
17390+ */
4a4d8108
AM
17391+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
17392+
4f0767ce 17393+out_unpin:
4a4d8108
AM
17394+ if (IS_ERR(wh_dentry))
17395+ au_unpin(pin);
4f0767ce 17396+out:
4a4d8108
AM
17397+ return wh_dentry;
17398+}
17399+
17400+/* ---------------------------------------------------------------------- */
17401+
17402+enum { Mknod, Symlink, Creat };
17403+struct simple_arg {
17404+ int type;
17405+ union {
17406+ struct {
b912730e
AM
17407+ umode_t mode;
17408+ bool want_excl;
17409+ bool try_aopen;
17410+ struct vfsub_aopen_args *aopen;
4a4d8108
AM
17411+ } c;
17412+ struct {
17413+ const char *symname;
17414+ } s;
17415+ struct {
7eafdf33 17416+ umode_t mode;
4a4d8108
AM
17417+ dev_t dev;
17418+ } m;
17419+ } u;
17420+};
17421+
17422+static int add_simple(struct inode *dir, struct dentry *dentry,
17423+ struct simple_arg *arg)
17424+{
076b876e 17425+ int err, rerr;
4a4d8108
AM
17426+ aufs_bindex_t bstart;
17427+ unsigned char created;
b912730e
AM
17428+ const unsigned char try_aopen
17429+ = (arg->type == Creat && arg->u.c.try_aopen);
4a4d8108
AM
17430+ struct dentry *wh_dentry, *parent;
17431+ struct inode *h_dir;
b912730e
AM
17432+ struct super_block *sb;
17433+ struct au_branch *br;
c2b27bf2
AM
17434+ /* to reuduce stack size */
17435+ struct {
17436+ struct au_dtime dt;
17437+ struct au_pin pin;
17438+ struct path h_path;
17439+ struct au_wr_dir_args wr_dir_args;
17440+ } *a;
4a4d8108 17441+
523b37e3 17442+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17443+ IMustLock(dir);
17444+
c2b27bf2
AM
17445+ err = -ENOMEM;
17446+ a = kmalloc(sizeof(*a), GFP_NOFS);
17447+ if (unlikely(!a))
17448+ goto out;
17449+ a->wr_dir_args.force_btgt = -1;
17450+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
17451+
4a4d8108 17452+ parent = dentry->d_parent; /* dir inode is locked */
b912730e
AM
17453+ if (!try_aopen) {
17454+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17455+ if (unlikely(err))
17456+ goto out_free;
17457+ }
027c5e7a
AM
17458+ err = au_d_may_add(dentry);
17459+ if (unlikely(err))
17460+ goto out_unlock;
b912730e
AM
17461+ if (!try_aopen)
17462+ di_write_lock_parent(parent);
c2b27bf2
AM
17463+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
17464+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
17465+ err = PTR_ERR(wh_dentry);
17466+ if (IS_ERR(wh_dentry))
027c5e7a 17467+ goto out_parent;
4a4d8108
AM
17468+
17469+ bstart = au_dbstart(dentry);
b912730e
AM
17470+ sb = dentry->d_sb;
17471+ br = au_sbr(sb, bstart);
c2b27bf2 17472+ a->h_path.dentry = au_h_dptr(dentry, bstart);
b912730e 17473+ a->h_path.mnt = au_br_mnt(br);
c2b27bf2 17474+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
17475+ switch (arg->type) {
17476+ case Creat:
b912730e
AM
17477+ err = 0;
17478+ if (!try_aopen || !h_dir->i_op->atomic_open)
17479+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
17480+ arg->u.c.want_excl);
17481+ else
17482+ err = vfsub_atomic_open(h_dir, a->h_path.dentry,
17483+ arg->u.c.aopen, br);
4a4d8108
AM
17484+ break;
17485+ case Symlink:
c2b27bf2 17486+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
4a4d8108
AM
17487+ break;
17488+ case Mknod:
c2b27bf2
AM
17489+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
17490+ arg->u.m.dev);
4a4d8108
AM
17491+ break;
17492+ default:
17493+ BUG();
17494+ }
17495+ created = !err;
17496+ if (!err)
17497+ err = epilog(dir, bstart, wh_dentry, dentry);
17498+
17499+ /* revert */
5527c038 17500+ if (unlikely(created && err && d_is_positive(a->h_path.dentry))) {
523b37e3
AM
17501+ /* no delegation since it is just created */
17502+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
17503+ /*force*/0);
4a4d8108 17504+ if (rerr) {
523b37e3
AM
17505+ AuIOErr("%pd revert failure(%d, %d)\n",
17506+ dentry, err, rerr);
4a4d8108
AM
17507+ err = -EIO;
17508+ }
c2b27bf2 17509+ au_dtime_revert(&a->dt);
4a4d8108
AM
17510+ }
17511+
b912730e
AM
17512+ if (!err && try_aopen && !h_dir->i_op->atomic_open)
17513+ *arg->u.c.aopen->opened |= FILE_CREATED;
17514+
c2b27bf2 17515+ au_unpin(&a->pin);
4a4d8108
AM
17516+ dput(wh_dentry);
17517+
027c5e7a 17518+out_parent:
b912730e
AM
17519+ if (!try_aopen)
17520+ di_write_unlock(parent);
027c5e7a 17521+out_unlock:
4a4d8108
AM
17522+ if (unlikely(err)) {
17523+ au_update_dbstart(dentry);
17524+ d_drop(dentry);
17525+ }
b912730e
AM
17526+ if (!try_aopen)
17527+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
17528+out_free:
17529+ kfree(a);
027c5e7a 17530+out:
4a4d8108
AM
17531+ return err;
17532+}
17533+
7eafdf33
AM
17534+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
17535+ dev_t dev)
4a4d8108
AM
17536+{
17537+ struct simple_arg arg = {
17538+ .type = Mknod,
17539+ .u.m = {
17540+ .mode = mode,
17541+ .dev = dev
17542+ }
17543+ };
17544+ return add_simple(dir, dentry, &arg);
17545+}
17546+
17547+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
17548+{
17549+ struct simple_arg arg = {
17550+ .type = Symlink,
17551+ .u.s.symname = symname
17552+ };
17553+ return add_simple(dir, dentry, &arg);
17554+}
17555+
7eafdf33 17556+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 17557+ bool want_excl)
4a4d8108
AM
17558+{
17559+ struct simple_arg arg = {
17560+ .type = Creat,
17561+ .u.c = {
b4510431
AM
17562+ .mode = mode,
17563+ .want_excl = want_excl
4a4d8108
AM
17564+ }
17565+ };
17566+ return add_simple(dir, dentry, &arg);
17567+}
17568+
b912730e
AM
17569+int au_aopen_or_create(struct inode *dir, struct dentry *dentry,
17570+ struct vfsub_aopen_args *aopen_args)
17571+{
17572+ struct simple_arg arg = {
17573+ .type = Creat,
17574+ .u.c = {
17575+ .mode = aopen_args->create_mode,
17576+ .want_excl = aopen_args->open_flag & O_EXCL,
17577+ .try_aopen = true,
17578+ .aopen = aopen_args
17579+ }
17580+ };
17581+ return add_simple(dir, dentry, &arg);
17582+}
17583+
38d290e6
JR
17584+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
17585+{
17586+ int err;
17587+ aufs_bindex_t bindex;
17588+ struct super_block *sb;
17589+ struct dentry *parent, *h_parent, *h_dentry;
17590+ struct inode *h_dir, *inode;
17591+ struct vfsmount *h_mnt;
17592+ struct au_wr_dir_args wr_dir_args = {
17593+ .force_btgt = -1,
17594+ .flags = AuWrDir_TMPFILE
17595+ };
17596+
17597+ /* copy-up may happen */
17598+ mutex_lock(&dir->i_mutex);
17599+
17600+ sb = dir->i_sb;
17601+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17602+ if (unlikely(err))
17603+ goto out;
17604+
17605+ err = au_di_init(dentry);
17606+ if (unlikely(err))
17607+ goto out_si;
17608+
17609+ err = -EBUSY;
17610+ parent = d_find_any_alias(dir);
17611+ AuDebugOn(!parent);
17612+ di_write_lock_parent(parent);
5527c038 17613+ if (unlikely(d_inode(parent) != dir))
38d290e6
JR
17614+ goto out_parent;
17615+
17616+ err = au_digen_test(parent, au_sigen(sb));
17617+ if (unlikely(err))
17618+ goto out_parent;
17619+
17620+ bindex = au_dbstart(parent);
17621+ au_set_dbstart(dentry, bindex);
17622+ au_set_dbend(dentry, bindex);
17623+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
17624+ bindex = err;
17625+ if (unlikely(err < 0))
17626+ goto out_parent;
17627+
17628+ err = -EOPNOTSUPP;
17629+ h_dir = au_h_iptr(dir, bindex);
17630+ if (unlikely(!h_dir->i_op->tmpfile))
17631+ goto out_parent;
17632+
17633+ h_mnt = au_sbr_mnt(sb, bindex);
17634+ err = vfsub_mnt_want_write(h_mnt);
17635+ if (unlikely(err))
17636+ goto out_parent;
17637+
17638+ h_parent = au_h_dptr(parent, bindex);
5527c038 17639+ err = inode_permission(d_inode(h_parent), MAY_WRITE | MAY_EXEC);
38d290e6
JR
17640+ if (unlikely(err))
17641+ goto out_mnt;
17642+
17643+ err = -ENOMEM;
17644+ h_dentry = d_alloc(h_parent, &dentry->d_name);
17645+ if (unlikely(!h_dentry))
17646+ goto out_mnt;
17647+
17648+ err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode);
17649+ if (unlikely(err))
17650+ goto out_dentry;
17651+
17652+ au_set_dbstart(dentry, bindex);
17653+ au_set_dbend(dentry, bindex);
17654+ au_set_h_dptr(dentry, bindex, dget(h_dentry));
17655+ inode = au_new_inode(dentry, /*must_new*/1);
17656+ if (IS_ERR(inode)) {
17657+ err = PTR_ERR(inode);
17658+ au_set_h_dptr(dentry, bindex, NULL);
17659+ au_set_dbstart(dentry, -1);
17660+ au_set_dbend(dentry, -1);
17661+ } else {
17662+ if (!inode->i_nlink)
17663+ set_nlink(inode, 1);
17664+ d_tmpfile(dentry, inode);
17665+ au_di(dentry)->di_tmpfile = 1;
17666+
17667+ /* update without i_mutex */
17668+ if (au_ibstart(dir) == au_dbstart(dentry))
17669+ au_cpup_attr_timesizes(dir);
17670+ }
17671+
17672+out_dentry:
17673+ dput(h_dentry);
17674+out_mnt:
17675+ vfsub_mnt_drop_write(h_mnt);
17676+out_parent:
17677+ di_write_unlock(parent);
17678+ dput(parent);
17679+ di_write_unlock(dentry);
17680+ if (!err)
17681+#if 0
17682+ /* verbose coding for lock class name */
17683+ au_rw_class(&au_di(dentry)->di_rwsem,
17684+ au_lc_key + AuLcNonDir_DIINFO);
17685+#else
17686+ ;
17687+#endif
17688+ else {
17689+ au_di_fin(dentry);
17690+ dentry->d_fsdata = NULL;
17691+ }
17692+out_si:
17693+ si_read_unlock(sb);
17694+out:
17695+ mutex_unlock(&dir->i_mutex);
17696+ return err;
17697+}
17698+
4a4d8108
AM
17699+/* ---------------------------------------------------------------------- */
17700+
17701+struct au_link_args {
17702+ aufs_bindex_t bdst, bsrc;
17703+ struct au_pin pin;
17704+ struct path h_path;
17705+ struct dentry *src_parent, *parent;
17706+};
17707+
17708+static int au_cpup_before_link(struct dentry *src_dentry,
17709+ struct au_link_args *a)
17710+{
17711+ int err;
17712+ struct dentry *h_src_dentry;
c2b27bf2
AM
17713+ struct au_cp_generic cpg = {
17714+ .dentry = src_dentry,
17715+ .bdst = a->bdst,
17716+ .bsrc = a->bsrc,
17717+ .len = -1,
17718+ .pin = &a->pin,
17719+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
17720+ };
4a4d8108
AM
17721+
17722+ di_read_lock_parent(a->src_parent, AuLock_IR);
17723+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
17724+ if (unlikely(err))
17725+ goto out;
17726+
17727+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
17728+ err = au_pin(&a->pin, src_dentry, a->bdst,
17729+ au_opt_udba(src_dentry->d_sb),
17730+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17731+ if (unlikely(err))
17732+ goto out;
367653fa 17733+
c2b27bf2 17734+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
17735+ au_unpin(&a->pin);
17736+
4f0767ce 17737+out:
4a4d8108
AM
17738+ di_read_unlock(a->src_parent, AuLock_IR);
17739+ return err;
17740+}
17741+
86dc4139
AM
17742+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
17743+ struct au_link_args *a)
4a4d8108
AM
17744+{
17745+ int err;
17746+ unsigned char plink;
86dc4139 17747+ aufs_bindex_t bend;
4a4d8108 17748+ struct dentry *h_src_dentry;
523b37e3 17749+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
17750+ struct super_block *sb;
17751+ struct file *h_file;
17752+
17753+ plink = 0;
17754+ h_inode = NULL;
17755+ sb = src_dentry->d_sb;
5527c038 17756+ inode = d_inode(src_dentry);
4a4d8108
AM
17757+ if (au_ibstart(inode) <= a->bdst)
17758+ h_inode = au_h_iptr(inode, a->bdst);
17759+ if (!h_inode || !h_inode->i_nlink) {
17760+ /* copyup src_dentry as the name of dentry. */
86dc4139
AM
17761+ bend = au_dbend(dentry);
17762+ if (bend < a->bsrc)
17763+ au_set_dbend(dentry, a->bsrc);
17764+ au_set_h_dptr(dentry, a->bsrc,
17765+ dget(au_h_dptr(src_dentry, a->bsrc)));
17766+ dget(a->h_path.dentry);
17767+ au_set_h_dptr(dentry, a->bdst, NULL);
c1595e42
JR
17768+ AuDbg("temporary d_inode...\n");
17769+ spin_lock(&dentry->d_lock);
5527c038 17770+ dentry->d_inode = d_inode(src_dentry); /* tmp */
c1595e42 17771+ spin_unlock(&dentry->d_lock);
392086de 17772+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 17773+ if (IS_ERR(h_file))
4a4d8108 17774+ err = PTR_ERR(h_file);
86dc4139 17775+ else {
c2b27bf2
AM
17776+ struct au_cp_generic cpg = {
17777+ .dentry = dentry,
17778+ .bdst = a->bdst,
17779+ .bsrc = -1,
17780+ .len = -1,
17781+ .pin = &a->pin,
17782+ .flags = AuCpup_KEEPLINO
17783+ };
17784+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
17785+ au_h_open_post(dentry, a->bsrc, h_file);
17786+ if (!err) {
17787+ dput(a->h_path.dentry);
17788+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
17789+ } else
17790+ au_set_h_dptr(dentry, a->bdst,
17791+ a->h_path.dentry);
17792+ }
c1595e42 17793+ spin_lock(&dentry->d_lock);
86dc4139 17794+ dentry->d_inode = NULL; /* restore */
c1595e42
JR
17795+ spin_unlock(&dentry->d_lock);
17796+ AuDbg("temporary d_inode...done\n");
86dc4139
AM
17797+ au_set_h_dptr(dentry, a->bsrc, NULL);
17798+ au_set_dbend(dentry, bend);
4a4d8108
AM
17799+ } else {
17800+ /* the inode of src_dentry already exists on a.bdst branch */
17801+ h_src_dentry = d_find_alias(h_inode);
17802+ if (!h_src_dentry && au_plink_test(inode)) {
17803+ plink = 1;
17804+ h_src_dentry = au_plink_lkup(inode, a->bdst);
17805+ err = PTR_ERR(h_src_dentry);
17806+ if (IS_ERR(h_src_dentry))
17807+ goto out;
17808+
5527c038 17809+ if (unlikely(d_is_negative(h_src_dentry))) {
4a4d8108
AM
17810+ dput(h_src_dentry);
17811+ h_src_dentry = NULL;
17812+ }
17813+
17814+ }
17815+ if (h_src_dentry) {
523b37e3 17816+ delegated = NULL;
4a4d8108 17817+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
17818+ &a->h_path, &delegated);
17819+ if (unlikely(err == -EWOULDBLOCK)) {
17820+ pr_warn("cannot retry for NFSv4 delegation"
17821+ " for an internal link\n");
17822+ iput(delegated);
17823+ }
4a4d8108
AM
17824+ dput(h_src_dentry);
17825+ } else {
17826+ AuIOErr("no dentry found for hi%lu on b%d\n",
17827+ h_inode->i_ino, a->bdst);
17828+ err = -EIO;
17829+ }
17830+ }
17831+
17832+ if (!err && !plink)
17833+ au_plink_append(inode, a->bdst, a->h_path.dentry);
17834+
17835+out:
2cbb1c4b 17836+ AuTraceErr(err);
4a4d8108
AM
17837+ return err;
17838+}
17839+
17840+int aufs_link(struct dentry *src_dentry, struct inode *dir,
17841+ struct dentry *dentry)
17842+{
17843+ int err, rerr;
17844+ struct au_dtime dt;
17845+ struct au_link_args *a;
17846+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 17847+ struct inode *inode, *delegated;
4a4d8108
AM
17848+ struct super_block *sb;
17849+ struct au_wr_dir_args wr_dir_args = {
17850+ /* .force_btgt = -1, */
17851+ .flags = AuWrDir_ADD_ENTRY
17852+ };
17853+
17854+ IMustLock(dir);
5527c038 17855+ inode = d_inode(src_dentry);
4a4d8108
AM
17856+ IMustLock(inode);
17857+
4a4d8108
AM
17858+ err = -ENOMEM;
17859+ a = kzalloc(sizeof(*a), GFP_NOFS);
17860+ if (unlikely(!a))
17861+ goto out;
17862+
17863+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
17864+ err = aufs_read_and_write_lock2(dentry, src_dentry,
17865+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
17866+ if (unlikely(err))
17867+ goto out_kfree;
38d290e6 17868+ err = au_d_linkable(src_dentry);
027c5e7a
AM
17869+ if (unlikely(err))
17870+ goto out_unlock;
17871+ err = au_d_may_add(dentry);
17872+ if (unlikely(err))
17873+ goto out_unlock;
e49829fe 17874+
4a4d8108 17875+ a->src_parent = dget_parent(src_dentry);
2cbb1c4b 17876+ wr_dir_args.force_btgt = au_ibstart(inode);
4a4d8108
AM
17877+
17878+ di_write_lock_parent(a->parent);
17879+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
17880+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
17881+ &wr_dir_args);
17882+ err = PTR_ERR(wh_dentry);
17883+ if (IS_ERR(wh_dentry))
027c5e7a 17884+ goto out_parent;
4a4d8108
AM
17885+
17886+ err = 0;
17887+ sb = dentry->d_sb;
17888+ a->bdst = au_dbstart(dentry);
17889+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
17890+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
2cbb1c4b
JR
17891+ a->bsrc = au_ibstart(inode);
17892+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
38d290e6
JR
17893+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
17894+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
2cbb1c4b
JR
17895+ if (!h_src_dentry) {
17896+ a->bsrc = au_dbstart(src_dentry);
17897+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
17898+ AuDebugOn(!h_src_dentry);
38d290e6
JR
17899+ } else if (IS_ERR(h_src_dentry)) {
17900+ err = PTR_ERR(h_src_dentry);
2cbb1c4b 17901+ goto out_parent;
38d290e6 17902+ }
2cbb1c4b 17903+
4a4d8108
AM
17904+ if (au_opt_test(au_mntflags(sb), PLINK)) {
17905+ if (a->bdst < a->bsrc
17906+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 17907+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
17908+ else {
17909+ delegated = NULL;
4a4d8108 17910+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
17911+ &a->h_path, &delegated);
17912+ if (unlikely(err == -EWOULDBLOCK)) {
17913+ pr_warn("cannot retry for NFSv4 delegation"
17914+ " for an internal link\n");
17915+ iput(delegated);
17916+ }
17917+ }
2cbb1c4b 17918+ dput(h_src_dentry);
4a4d8108
AM
17919+ } else {
17920+ /*
17921+ * copyup src_dentry to the branch we process,
17922+ * and then link(2) to it.
17923+ */
2cbb1c4b 17924+ dput(h_src_dentry);
4a4d8108
AM
17925+ if (a->bdst < a->bsrc
17926+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
17927+ au_unpin(&a->pin);
17928+ di_write_unlock(a->parent);
17929+ err = au_cpup_before_link(src_dentry, a);
17930+ di_write_lock_parent(a->parent);
17931+ if (!err)
17932+ err = au_pin(&a->pin, dentry, a->bdst,
17933+ au_opt_udba(sb),
17934+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17935+ if (unlikely(err))
17936+ goto out_wh;
17937+ }
17938+ if (!err) {
17939+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
17940+ err = -ENOENT;
5527c038 17941+ if (h_src_dentry && d_is_positive(h_src_dentry)) {
523b37e3 17942+ delegated = NULL;
4a4d8108
AM
17943+ err = vfsub_link(h_src_dentry,
17944+ au_pinned_h_dir(&a->pin),
523b37e3
AM
17945+ &a->h_path, &delegated);
17946+ if (unlikely(err == -EWOULDBLOCK)) {
17947+ pr_warn("cannot retry"
17948+ " for NFSv4 delegation"
17949+ " for an internal link\n");
17950+ iput(delegated);
17951+ }
17952+ }
4a4d8108
AM
17953+ }
17954+ }
17955+ if (unlikely(err))
17956+ goto out_unpin;
17957+
17958+ if (wh_dentry) {
17959+ a->h_path.dentry = wh_dentry;
17960+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
17961+ dentry);
17962+ if (unlikely(err))
17963+ goto out_revert;
17964+ }
17965+
b912730e 17966+ au_dir_ts(dir, a->bdst);
4a4d8108 17967+ dir->i_version++;
4a4d8108
AM
17968+ inc_nlink(inode);
17969+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
17970+ d_instantiate(dentry, au_igrab(inode));
17971+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
17972+ /* some filesystem calls d_drop() */
17973+ d_drop(dentry);
076b876e
AM
17974+ /* some filesystems consume an inode even hardlink */
17975+ au_fhsm_wrote(sb, a->bdst, /*force*/0);
4a4d8108
AM
17976+ goto out_unpin; /* success */
17977+
4f0767ce 17978+out_revert:
523b37e3
AM
17979+ /* no delegation since it is just created */
17980+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
17981+ /*delegated*/NULL, /*force*/0);
027c5e7a 17982+ if (unlikely(rerr)) {
523b37e3 17983+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
17984+ err = -EIO;
17985+ }
4a4d8108 17986+ au_dtime_revert(&dt);
4f0767ce 17987+out_unpin:
4a4d8108 17988+ au_unpin(&a->pin);
4f0767ce 17989+out_wh:
4a4d8108 17990+ dput(wh_dentry);
027c5e7a
AM
17991+out_parent:
17992+ di_write_unlock(a->parent);
17993+ dput(a->src_parent);
4f0767ce 17994+out_unlock:
4a4d8108
AM
17995+ if (unlikely(err)) {
17996+ au_update_dbstart(dentry);
17997+ d_drop(dentry);
17998+ }
4a4d8108 17999+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 18000+out_kfree:
4a4d8108 18001+ kfree(a);
4f0767ce 18002+out:
86dc4139 18003+ AuTraceErr(err);
4a4d8108
AM
18004+ return err;
18005+}
18006+
7eafdf33 18007+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
18008+{
18009+ int err, rerr;
18010+ aufs_bindex_t bindex;
18011+ unsigned char diropq;
18012+ struct path h_path;
18013+ struct dentry *wh_dentry, *parent, *opq_dentry;
18014+ struct mutex *h_mtx;
18015+ struct super_block *sb;
18016+ struct {
18017+ struct au_pin pin;
18018+ struct au_dtime dt;
18019+ } *a; /* reduce the stack usage */
18020+ struct au_wr_dir_args wr_dir_args = {
18021+ .force_btgt = -1,
18022+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
18023+ };
18024+
18025+ IMustLock(dir);
18026+
18027+ err = -ENOMEM;
18028+ a = kmalloc(sizeof(*a), GFP_NOFS);
18029+ if (unlikely(!a))
18030+ goto out;
18031+
027c5e7a
AM
18032+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
18033+ if (unlikely(err))
18034+ goto out_free;
18035+ err = au_d_may_add(dentry);
18036+ if (unlikely(err))
18037+ goto out_unlock;
18038+
4a4d8108
AM
18039+ parent = dentry->d_parent; /* dir inode is locked */
18040+ di_write_lock_parent(parent);
18041+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
18042+ &a->pin, &wr_dir_args);
18043+ err = PTR_ERR(wh_dentry);
18044+ if (IS_ERR(wh_dentry))
027c5e7a 18045+ goto out_parent;
4a4d8108
AM
18046+
18047+ sb = dentry->d_sb;
18048+ bindex = au_dbstart(dentry);
18049+ h_path.dentry = au_h_dptr(dentry, bindex);
18050+ h_path.mnt = au_sbr_mnt(sb, bindex);
18051+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
18052+ if (unlikely(err))
027c5e7a 18053+ goto out_unpin;
4a4d8108
AM
18054+
18055+ /* make the dir opaque */
18056+ diropq = 0;
5527c038 18057+ h_mtx = &d_inode(h_path.dentry)->i_mutex;
4a4d8108
AM
18058+ if (wh_dentry
18059+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
18060+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18061+ opq_dentry = au_diropq_create(dentry, bindex);
18062+ mutex_unlock(h_mtx);
18063+ err = PTR_ERR(opq_dentry);
18064+ if (IS_ERR(opq_dentry))
18065+ goto out_dir;
18066+ dput(opq_dentry);
18067+ diropq = 1;
18068+ }
18069+
18070+ err = epilog(dir, bindex, wh_dentry, dentry);
18071+ if (!err) {
18072+ inc_nlink(dir);
027c5e7a 18073+ goto out_unpin; /* success */
4a4d8108
AM
18074+ }
18075+
18076+ /* revert */
18077+ if (diropq) {
18078+ AuLabel(revert opq);
18079+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18080+ rerr = au_diropq_remove(dentry, bindex);
18081+ mutex_unlock(h_mtx);
18082+ if (rerr) {
523b37e3
AM
18083+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
18084+ dentry, err, rerr);
4a4d8108
AM
18085+ err = -EIO;
18086+ }
18087+ }
18088+
4f0767ce 18089+out_dir:
4a4d8108
AM
18090+ AuLabel(revert dir);
18091+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
18092+ if (rerr) {
523b37e3
AM
18093+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
18094+ dentry, err, rerr);
4a4d8108
AM
18095+ err = -EIO;
18096+ }
4a4d8108 18097+ au_dtime_revert(&a->dt);
027c5e7a 18098+out_unpin:
4a4d8108
AM
18099+ au_unpin(&a->pin);
18100+ dput(wh_dentry);
027c5e7a
AM
18101+out_parent:
18102+ di_write_unlock(parent);
18103+out_unlock:
4a4d8108
AM
18104+ if (unlikely(err)) {
18105+ au_update_dbstart(dentry);
18106+ d_drop(dentry);
18107+ }
4a4d8108 18108+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 18109+out_free:
4a4d8108 18110+ kfree(a);
4f0767ce 18111+out:
4a4d8108
AM
18112+ return err;
18113+}
7f207e10
AM
18114diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
18115--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
18116+++ linux/fs/aufs/i_op.c 2015-11-11 17:21:46.918863802 +0100
18117@@ -0,0 +1,1482 @@
4a4d8108 18118+/*
2000de60 18119+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
18120+ *
18121+ * This program, aufs is free software; you can redistribute it and/or modify
18122+ * it under the terms of the GNU General Public License as published by
18123+ * the Free Software Foundation; either version 2 of the License, or
18124+ * (at your option) any later version.
18125+ *
18126+ * This program is distributed in the hope that it will be useful,
18127+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18128+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18129+ * GNU General Public License for more details.
18130+ *
18131+ * You should have received a copy of the GNU General Public License
523b37e3 18132+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 18133+ */
1facf9fc 18134+
1308ab2a 18135+/*
4a4d8108 18136+ * inode operations (except add/del/rename)
1308ab2a 18137+ */
4a4d8108
AM
18138+
18139+#include <linux/device_cgroup.h>
18140+#include <linux/fs_stack.h>
4a4d8108
AM
18141+#include <linux/namei.h>
18142+#include <linux/security.h>
4a4d8108
AM
18143+#include "aufs.h"
18144+
1e00d052 18145+static int h_permission(struct inode *h_inode, int mask,
79b8bda9 18146+ struct path *h_path, int brperm)
1facf9fc 18147+{
1308ab2a 18148+ int err;
4a4d8108 18149+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 18150+
4a4d8108
AM
18151+ err = -EACCES;
18152+ if ((write_mask && IS_IMMUTABLE(h_inode))
18153+ || ((mask & MAY_EXEC)
18154+ && S_ISREG(h_inode->i_mode)
79b8bda9 18155+ && (path_noexec(h_path)
4a4d8108
AM
18156+ || !(h_inode->i_mode & S_IXUGO))))
18157+ goto out;
18158+
18159+ /*
18160+ * - skip the lower fs test in the case of write to ro branch.
18161+ * - nfs dir permission write check is optimized, but a policy for
18162+ * link/rename requires a real check.
b912730e
AM
18163+ * - nfs always sets MS_POSIXACL regardless its mount option 'noacl.'
18164+ * in this case, generic_permission() returns -EOPNOTSUPP.
4a4d8108
AM
18165+ */
18166+ if ((write_mask && !au_br_writable(brperm))
18167+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
18168+ && write_mask && !(mask & MAY_READ))
18169+ || !h_inode->i_op->permission) {
18170+ /* AuLabel(generic_permission); */
b912730e 18171+ /* AuDbg("get_acl %pf\n", h_inode->i_op->get_acl); */
1e00d052 18172+ err = generic_permission(h_inode, mask);
b912730e
AM
18173+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode))
18174+ err = h_inode->i_op->permission(h_inode, mask);
18175+ AuTraceErr(err);
1308ab2a 18176+ } else {
4a4d8108 18177+ /* AuLabel(h_inode->permission); */
1e00d052 18178+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
18179+ AuTraceErr(err);
18180+ }
1facf9fc 18181+
4a4d8108
AM
18182+ if (!err)
18183+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 18184+ if (!err)
4a4d8108 18185+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
18186+
18187+#if 0
18188+ if (!err) {
18189+ /* todo: do we need to call ima_path_check()? */
18190+ struct path h_path = {
18191+ .dentry =
18192+ .mnt = h_mnt
18193+ };
18194+ err = ima_path_check(&h_path,
18195+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
18196+ IMA_COUNT_LEAVE);
1308ab2a 18197+ }
4a4d8108 18198+#endif
dece6358 18199+
4f0767ce 18200+out:
1308ab2a 18201+ return err;
18202+}
dece6358 18203+
1e00d052 18204+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 18205+{
18206+ int err;
4a4d8108
AM
18207+ aufs_bindex_t bindex, bend;
18208+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
18209+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
18210+ struct inode *h_inode;
18211+ struct super_block *sb;
18212+ struct au_branch *br;
1facf9fc 18213+
027c5e7a 18214+ /* todo: support rcu-walk? */
1e00d052 18215+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
18216+ return -ECHILD;
18217+
4a4d8108
AM
18218+ sb = inode->i_sb;
18219+ si_read_lock(sb, AuLock_FLUSH);
18220+ ii_read_lock_child(inode);
027c5e7a
AM
18221+#if 0
18222+ err = au_iigen_test(inode, au_sigen(sb));
18223+ if (unlikely(err))
18224+ goto out;
18225+#endif
dece6358 18226+
076b876e
AM
18227+ if (!isdir
18228+ || write_mask
18229+ || au_opt_test(au_mntflags(sb), DIRPERM1)) {
4a4d8108
AM
18230+ err = au_busy_or_stale();
18231+ h_inode = au_h_iptr(inode, au_ibstart(inode));
18232+ if (unlikely(!h_inode
18233+ || (h_inode->i_mode & S_IFMT)
18234+ != (inode->i_mode & S_IFMT)))
18235+ goto out;
1facf9fc 18236+
4a4d8108
AM
18237+ err = 0;
18238+ bindex = au_ibstart(inode);
18239+ br = au_sbr(sb, bindex);
79b8bda9 18240+ err = h_permission(h_inode, mask, &br->br_path, br->br_perm);
4a4d8108
AM
18241+ if (write_mask
18242+ && !err
18243+ && !special_file(h_inode->i_mode)) {
18244+ /* test whether the upper writable branch exists */
18245+ err = -EROFS;
18246+ for (; bindex >= 0; bindex--)
18247+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
18248+ err = 0;
18249+ break;
18250+ }
18251+ }
18252+ goto out;
18253+ }
dece6358 18254+
4a4d8108 18255+ /* non-write to dir */
1308ab2a 18256+ err = 0;
4a4d8108
AM
18257+ bend = au_ibend(inode);
18258+ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
18259+ h_inode = au_h_iptr(inode, bindex);
18260+ if (h_inode) {
18261+ err = au_busy_or_stale();
18262+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
18263+ break;
18264+
18265+ br = au_sbr(sb, bindex);
79b8bda9 18266+ err = h_permission(h_inode, mask, &br->br_path,
4a4d8108
AM
18267+ br->br_perm);
18268+ }
18269+ }
1308ab2a 18270+
4f0767ce 18271+out:
4a4d8108
AM
18272+ ii_read_unlock(inode);
18273+ si_read_unlock(sb);
1308ab2a 18274+ return err;
18275+}
18276+
4a4d8108 18277+/* ---------------------------------------------------------------------- */
1facf9fc 18278+
4a4d8108 18279+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 18280+ unsigned int flags)
4a4d8108
AM
18281+{
18282+ struct dentry *ret, *parent;
b752ccd1 18283+ struct inode *inode;
4a4d8108 18284+ struct super_block *sb;
1716fcea 18285+ int err, npositive;
dece6358 18286+
4a4d8108 18287+ IMustLock(dir);
1308ab2a 18288+
537831f9
AM
18289+ /* todo: support rcu-walk? */
18290+ ret = ERR_PTR(-ECHILD);
18291+ if (flags & LOOKUP_RCU)
18292+ goto out;
18293+
18294+ ret = ERR_PTR(-ENAMETOOLONG);
18295+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
18296+ goto out;
18297+
4a4d8108 18298+ sb = dir->i_sb;
7f207e10
AM
18299+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18300+ ret = ERR_PTR(err);
18301+ if (unlikely(err))
18302+ goto out;
18303+
4a4d8108
AM
18304+ err = au_di_init(dentry);
18305+ ret = ERR_PTR(err);
18306+ if (unlikely(err))
7f207e10 18307+ goto out_si;
1308ab2a 18308+
9dbd164d 18309+ inode = NULL;
027c5e7a 18310+ npositive = 0; /* suppress a warning */
4a4d8108
AM
18311+ parent = dentry->d_parent; /* dir inode is locked */
18312+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
18313+ err = au_alive_dir(parent);
18314+ if (!err)
18315+ err = au_digen_test(parent, au_sigen(sb));
18316+ if (!err) {
18317+ npositive = au_lkup_dentry(dentry, au_dbstart(parent),
537831f9 18318+ /*type*/0);
027c5e7a
AM
18319+ err = npositive;
18320+ }
4a4d8108 18321+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
18322+ ret = ERR_PTR(err);
18323+ if (unlikely(err < 0))
18324+ goto out_unlock;
1308ab2a 18325+
4a4d8108 18326+ if (npositive) {
b752ccd1 18327+ inode = au_new_inode(dentry, /*must_new*/0);
c1595e42
JR
18328+ if (IS_ERR(inode)) {
18329+ ret = (void *)inode;
18330+ inode = NULL;
18331+ goto out_unlock;
18332+ }
9dbd164d 18333+ }
4a4d8108 18334+
c1595e42
JR
18335+ if (inode)
18336+ atomic_inc(&inode->i_count);
4a4d8108 18337+ ret = d_splice_alias(inode, dentry);
537831f9
AM
18338+#if 0
18339+ if (unlikely(d_need_lookup(dentry))) {
18340+ spin_lock(&dentry->d_lock);
18341+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
18342+ spin_unlock(&dentry->d_lock);
18343+ } else
18344+#endif
c1595e42 18345+ if (inode) {
2000de60 18346+ if (!IS_ERR(ret)) {
c1595e42 18347+ iput(inode);
2000de60
JR
18348+ if (ret && ret != dentry)
18349+ ii_write_unlock(inode);
18350+ } else {
c1595e42
JR
18351+ ii_write_unlock(inode);
18352+ iput(inode);
18353+ inode = NULL;
18354+ }
7f207e10 18355+ }
1facf9fc 18356+
4f0767ce 18357+out_unlock:
4a4d8108 18358+ di_write_unlock(dentry);
2dfbb274 18359+ if (inode) {
1716fcea
AM
18360+ /* verbose coding for lock class name */
18361+ if (unlikely(S_ISLNK(inode->i_mode)))
18362+ au_rw_class(&au_di(dentry)->di_rwsem,
18363+ au_lc_key + AuLcSymlink_DIINFO);
18364+ else if (unlikely(S_ISDIR(inode->i_mode)))
18365+ au_rw_class(&au_di(dentry)->di_rwsem,
18366+ au_lc_key + AuLcDir_DIINFO);
18367+ else /* likely */
18368+ au_rw_class(&au_di(dentry)->di_rwsem,
18369+ au_lc_key + AuLcNonDir_DIINFO);
9dbd164d 18370+ }
7f207e10 18371+out_si:
4a4d8108 18372+ si_read_unlock(sb);
7f207e10 18373+out:
4a4d8108
AM
18374+ return ret;
18375+}
1facf9fc 18376+
4a4d8108 18377+/* ---------------------------------------------------------------------- */
1facf9fc 18378+
b912730e
AM
18379+struct aopen_node {
18380+ struct hlist_node hlist;
18381+ struct file *file, *h_file;
18382+};
18383+
18384+static int au_do_aopen(struct inode *inode, struct file *file)
18385+{
18386+ struct au_sphlhead *aopen;
18387+ struct aopen_node *node;
18388+ struct au_do_open_args args = {
18389+ .no_lock = 1,
18390+ .open = au_do_open_nondir
18391+ };
18392+
18393+ aopen = &au_sbi(inode->i_sb)->si_aopen;
18394+ spin_lock(&aopen->spin);
18395+ hlist_for_each_entry(node, &aopen->head, hlist)
18396+ if (node->file == file) {
18397+ args.h_file = node->h_file;
18398+ break;
18399+ }
18400+ spin_unlock(&aopen->spin);
18401+ /* AuDebugOn(!args.h_file); */
18402+
18403+ return au_do_open(file, &args);
18404+}
18405+
18406+static int aufs_atomic_open(struct inode *dir, struct dentry *dentry,
18407+ struct file *file, unsigned int open_flag,
18408+ umode_t create_mode, int *opened)
18409+{
18410+ int err, h_opened = *opened;
18411+ struct dentry *parent;
18412+ struct dentry *d;
18413+ struct au_sphlhead *aopen;
18414+ struct vfsub_aopen_args args = {
18415+ .open_flag = open_flag,
18416+ .create_mode = create_mode,
18417+ .opened = &h_opened
18418+ };
18419+ struct aopen_node aopen_node = {
18420+ .file = file
18421+ };
18422+
18423+ IMustLock(dir);
18424+ AuDbg("open_flag 0x%x\n", open_flag);
18425+ AuDbgDentry(dentry);
18426+
18427+ err = 0;
18428+ if (!au_di(dentry)) {
18429+ d = aufs_lookup(dir, dentry, /*flags*/0);
18430+ if (IS_ERR(d)) {
18431+ err = PTR_ERR(d);
18432+ goto out;
18433+ } else if (d) {
18434+ /*
18435+ * obsoleted dentry found.
18436+ * another error will be returned later.
18437+ */
18438+ d_drop(d);
18439+ dput(d);
18440+ AuDbgDentry(d);
18441+ }
18442+ AuDbgDentry(dentry);
18443+ }
18444+
18445+ if (d_is_positive(dentry)
18446+ || d_unhashed(dentry)
18447+ || d_unlinked(dentry)
18448+ || !(open_flag & O_CREAT))
18449+ goto out_no_open;
18450+
18451+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
18452+ if (unlikely(err))
18453+ goto out;
18454+
18455+ parent = dentry->d_parent; /* dir is locked */
18456+ di_write_lock_parent(parent);
18457+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
18458+ if (unlikely(err))
18459+ goto out_unlock;
18460+
18461+ AuDbgDentry(dentry);
18462+ if (d_is_positive(dentry))
18463+ goto out_unlock;
18464+
18465+ args.file = get_empty_filp();
18466+ err = PTR_ERR(args.file);
18467+ if (IS_ERR(args.file))
18468+ goto out_unlock;
18469+
18470+ args.file->f_flags = file->f_flags;
18471+ err = au_aopen_or_create(dir, dentry, &args);
18472+ AuTraceErr(err);
18473+ AuDbgFile(args.file);
18474+ if (unlikely(err < 0)) {
18475+ if (h_opened & FILE_OPENED)
18476+ fput(args.file);
18477+ else
18478+ put_filp(args.file);
18479+ goto out_unlock;
18480+ }
18481+
18482+ /* some filesystems don't set FILE_CREATED while succeeded? */
18483+ *opened |= FILE_CREATED;
18484+ if (h_opened & FILE_OPENED)
18485+ aopen_node.h_file = args.file;
18486+ else {
18487+ put_filp(args.file);
18488+ args.file = NULL;
18489+ }
18490+ aopen = &au_sbi(dir->i_sb)->si_aopen;
18491+ au_sphl_add(&aopen_node.hlist, aopen);
18492+ err = finish_open(file, dentry, au_do_aopen, opened);
18493+ au_sphl_del(&aopen_node.hlist, aopen);
18494+ AuTraceErr(err);
18495+ AuDbgFile(file);
18496+ if (aopen_node.h_file)
18497+ fput(aopen_node.h_file);
18498+
18499+out_unlock:
18500+ di_write_unlock(parent);
18501+ aufs_read_unlock(dentry, AuLock_DW);
18502+ AuDbgDentry(dentry);
18503+ if (unlikely(err))
18504+ goto out;
18505+out_no_open:
18506+ if (!err && !(*opened & FILE_CREATED)) {
18507+ AuLabel(out_no_open);
18508+ dget(dentry);
18509+ err = finish_no_open(file, dentry);
18510+ }
18511+out:
18512+ AuDbg("%pd%s%s\n", dentry,
18513+ (*opened & FILE_CREATED) ? " created" : "",
18514+ (*opened & FILE_OPENED) ? " opened" : "");
18515+ AuTraceErr(err);
18516+ return err;
18517+}
18518+
18519+
18520+/* ---------------------------------------------------------------------- */
18521+
4a4d8108
AM
18522+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
18523+ const unsigned char add_entry, aufs_bindex_t bcpup,
18524+ aufs_bindex_t bstart)
18525+{
18526+ int err;
18527+ struct dentry *h_parent;
18528+ struct inode *h_dir;
1facf9fc 18529+
027c5e7a 18530+ if (add_entry)
5527c038 18531+ IMustLock(d_inode(parent));
027c5e7a 18532+ else
4a4d8108
AM
18533+ di_write_lock_parent(parent);
18534+
18535+ err = 0;
18536+ if (!au_h_dptr(parent, bcpup)) {
c2b27bf2
AM
18537+ if (bstart > bcpup)
18538+ err = au_cpup_dirs(dentry, bcpup);
18539+ else if (bstart < bcpup)
4a4d8108
AM
18540+ err = au_cpdown_dirs(dentry, bcpup);
18541+ else
c2b27bf2 18542+ BUG();
4a4d8108 18543+ }
38d290e6 18544+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
4a4d8108 18545+ h_parent = au_h_dptr(parent, bcpup);
5527c038 18546+ h_dir = d_inode(h_parent);
4a4d8108 18547+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
7e9cd9fe 18548+ err = au_lkup_neg(dentry, bcpup, /*wh*/0);
4a4d8108
AM
18549+ /* todo: no unlock here */
18550+ mutex_unlock(&h_dir->i_mutex);
027c5e7a
AM
18551+
18552+ AuDbg("bcpup %d\n", bcpup);
18553+ if (!err) {
5527c038 18554+ if (d_really_is_negative(dentry))
027c5e7a 18555+ au_set_h_dptr(dentry, bstart, NULL);
4a4d8108
AM
18556+ au_update_dbrange(dentry, /*do_put_zero*/0);
18557+ }
1308ab2a 18558+ }
1facf9fc 18559+
4a4d8108
AM
18560+ if (!add_entry)
18561+ di_write_unlock(parent);
18562+ if (!err)
18563+ err = bcpup; /* success */
1308ab2a 18564+
027c5e7a 18565+ AuTraceErr(err);
4a4d8108
AM
18566+ return err;
18567+}
1facf9fc 18568+
4a4d8108
AM
18569+/*
18570+ * decide the branch and the parent dir where we will create a new entry.
18571+ * returns new bindex or an error.
18572+ * copyup the parent dir if needed.
18573+ */
18574+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
18575+ struct au_wr_dir_args *args)
18576+{
18577+ int err;
392086de 18578+ unsigned int flags;
4a4d8108 18579+ aufs_bindex_t bcpup, bstart, src_bstart;
86dc4139
AM
18580+ const unsigned char add_entry
18581+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
38d290e6 18582+ | au_ftest_wrdir(args->flags, TMPFILE);
4a4d8108
AM
18583+ struct super_block *sb;
18584+ struct dentry *parent;
18585+ struct au_sbinfo *sbinfo;
1facf9fc 18586+
4a4d8108
AM
18587+ sb = dentry->d_sb;
18588+ sbinfo = au_sbi(sb);
18589+ parent = dget_parent(dentry);
18590+ bstart = au_dbstart(dentry);
18591+ bcpup = bstart;
18592+ if (args->force_btgt < 0) {
18593+ if (src_dentry) {
18594+ src_bstart = au_dbstart(src_dentry);
18595+ if (src_bstart < bstart)
18596+ bcpup = src_bstart;
18597+ } else if (add_entry) {
392086de
AM
18598+ flags = 0;
18599+ if (au_ftest_wrdir(args->flags, ISDIR))
18600+ au_fset_wbr(flags, DIR);
18601+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
18602+ bcpup = err;
18603+ }
1facf9fc 18604+
5527c038 18605+ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) {
4a4d8108
AM
18606+ if (add_entry)
18607+ err = AuWbrCopyup(sbinfo, dentry);
18608+ else {
18609+ if (!IS_ROOT(dentry)) {
18610+ di_read_lock_parent(parent, !AuLock_IR);
18611+ err = AuWbrCopyup(sbinfo, dentry);
18612+ di_read_unlock(parent, !AuLock_IR);
18613+ } else
18614+ err = AuWbrCopyup(sbinfo, dentry);
18615+ }
18616+ bcpup = err;
18617+ if (unlikely(err < 0))
18618+ goto out;
18619+ }
18620+ } else {
18621+ bcpup = args->force_btgt;
5527c038 18622+ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry)));
1308ab2a 18623+ }
027c5e7a 18624+
4a4d8108
AM
18625+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
18626+ err = bcpup;
18627+ if (bcpup == bstart)
18628+ goto out; /* success */
4a4d8108
AM
18629+
18630+ /* copyup the new parent into the branch we process */
18631+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
027c5e7a 18632+ if (err >= 0) {
5527c038 18633+ if (d_really_is_negative(dentry)) {
027c5e7a
AM
18634+ au_set_h_dptr(dentry, bstart, NULL);
18635+ au_set_dbstart(dentry, bcpup);
18636+ au_set_dbend(dentry, bcpup);
18637+ }
38d290e6
JR
18638+ AuDebugOn(add_entry
18639+ && !au_ftest_wrdir(args->flags, TMPFILE)
18640+ && !au_h_dptr(dentry, bcpup));
027c5e7a 18641+ }
86dc4139
AM
18642+
18643+out:
18644+ dput(parent);
18645+ return err;
18646+}
18647+
18648+/* ---------------------------------------------------------------------- */
18649+
18650+void au_pin_hdir_unlock(struct au_pin *p)
18651+{
18652+ if (p->hdir)
18653+ au_hn_imtx_unlock(p->hdir);
18654+}
18655+
c1595e42 18656+int au_pin_hdir_lock(struct au_pin *p)
86dc4139
AM
18657+{
18658+ int err;
18659+
18660+ err = 0;
18661+ if (!p->hdir)
18662+ goto out;
18663+
18664+ /* even if an error happens later, keep this lock */
18665+ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
18666+
18667+ err = -EBUSY;
5527c038 18668+ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent)))
86dc4139
AM
18669+ goto out;
18670+
18671+ err = 0;
18672+ if (p->h_dentry)
18673+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
18674+ p->h_parent, p->br);
18675+
18676+out:
18677+ return err;
18678+}
18679+
18680+int au_pin_hdir_relock(struct au_pin *p)
18681+{
18682+ int err, i;
18683+ struct inode *h_i;
18684+ struct dentry *h_d[] = {
18685+ p->h_dentry,
18686+ p->h_parent
18687+ };
18688+
18689+ err = au_pin_hdir_lock(p);
18690+ if (unlikely(err))
18691+ goto out;
18692+
18693+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
18694+ if (!h_d[i])
18695+ continue;
5527c038
JR
18696+ if (d_is_positive(h_d[i])) {
18697+ h_i = d_inode(h_d[i]);
86dc4139 18698+ err = !h_i->i_nlink;
5527c038 18699+ }
86dc4139
AM
18700+ }
18701+
18702+out:
18703+ return err;
18704+}
18705+
18706+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
18707+{
18708+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
18709+ p->hdir->hi_inode->i_mutex.owner = task;
18710+#endif
18711+}
18712+
18713+void au_pin_hdir_acquire_nest(struct au_pin *p)
18714+{
18715+ if (p->hdir) {
18716+ mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
18717+ p->lsc_hi, 0, NULL, _RET_IP_);
18718+ au_pin_hdir_set_owner(p, current);
18719+ }
dece6358 18720+}
1facf9fc 18721+
86dc4139
AM
18722+void au_pin_hdir_release(struct au_pin *p)
18723+{
18724+ if (p->hdir) {
18725+ au_pin_hdir_set_owner(p, p->task);
18726+ mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
18727+ }
18728+}
1308ab2a 18729+
4a4d8108 18730+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 18731+{
4a4d8108
AM
18732+ if (pin && pin->parent)
18733+ return au_h_dptr(pin->parent, pin->bindex);
18734+ return NULL;
dece6358 18735+}
1facf9fc 18736+
4a4d8108 18737+void au_unpin(struct au_pin *p)
dece6358 18738+{
86dc4139
AM
18739+ if (p->hdir)
18740+ au_pin_hdir_unlock(p);
e49829fe 18741+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 18742+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
18743+ if (!p->hdir)
18744+ return;
1facf9fc 18745+
4a4d8108
AM
18746+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18747+ di_read_unlock(p->parent, AuLock_IR);
18748+ iput(p->hdir->hi_inode);
18749+ dput(p->parent);
18750+ p->parent = NULL;
18751+ p->hdir = NULL;
18752+ p->h_mnt = NULL;
86dc4139 18753+ /* do not clear p->task */
4a4d8108 18754+}
1308ab2a 18755+
4a4d8108
AM
18756+int au_do_pin(struct au_pin *p)
18757+{
18758+ int err;
18759+ struct super_block *sb;
4a4d8108
AM
18760+ struct inode *h_dir;
18761+
18762+ err = 0;
18763+ sb = p->dentry->d_sb;
86dc4139 18764+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
18765+ if (IS_ROOT(p->dentry)) {
18766+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 18767+ p->h_mnt = au_br_mnt(p->br);
b4510431 18768+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
18769+ if (unlikely(err)) {
18770+ au_fclr_pin(p->flags, MNT_WRITE);
18771+ goto out_err;
18772+ }
18773+ }
dece6358 18774+ goto out;
1facf9fc 18775+ }
18776+
86dc4139 18777+ p->h_dentry = NULL;
4a4d8108 18778+ if (p->bindex <= au_dbend(p->dentry))
86dc4139 18779+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 18780+
4a4d8108
AM
18781+ p->parent = dget_parent(p->dentry);
18782+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18783+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 18784+
4a4d8108 18785+ h_dir = NULL;
86dc4139 18786+ p->h_parent = au_h_dptr(p->parent, p->bindex);
5527c038 18787+ p->hdir = au_hi(d_inode(p->parent), p->bindex);
4a4d8108
AM
18788+ if (p->hdir)
18789+ h_dir = p->hdir->hi_inode;
dece6358 18790+
b752ccd1
AM
18791+ /*
18792+ * udba case, or
18793+ * if DI_LOCKED is not set, then p->parent may be different
18794+ * and h_parent can be NULL.
18795+ */
86dc4139 18796+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 18797+ err = -EBUSY;
4a4d8108
AM
18798+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18799+ di_read_unlock(p->parent, AuLock_IR);
18800+ dput(p->parent);
18801+ p->parent = NULL;
18802+ goto out_err;
18803+ }
1308ab2a 18804+
4a4d8108 18805+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 18806+ p->h_mnt = au_br_mnt(p->br);
b4510431 18807+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 18808+ if (unlikely(err)) {
4a4d8108 18809+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
18810+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18811+ di_read_unlock(p->parent, AuLock_IR);
18812+ dput(p->parent);
18813+ p->parent = NULL;
18814+ goto out_err;
dece6358
AM
18815+ }
18816+ }
4a4d8108 18817+
86dc4139
AM
18818+ au_igrab(h_dir);
18819+ err = au_pin_hdir_lock(p);
18820+ if (!err)
18821+ goto out; /* success */
18822+
076b876e
AM
18823+ au_unpin(p);
18824+
4f0767ce 18825+out_err:
4a4d8108
AM
18826+ pr_err("err %d\n", err);
18827+ err = au_busy_or_stale();
4f0767ce 18828+out:
1facf9fc 18829+ return err;
18830+}
18831+
4a4d8108
AM
18832+void au_pin_init(struct au_pin *p, struct dentry *dentry,
18833+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
18834+ unsigned int udba, unsigned char flags)
18835+{
18836+ p->dentry = dentry;
18837+ p->udba = udba;
18838+ p->lsc_di = lsc_di;
18839+ p->lsc_hi = lsc_hi;
18840+ p->flags = flags;
18841+ p->bindex = bindex;
18842+
18843+ p->parent = NULL;
18844+ p->hdir = NULL;
18845+ p->h_mnt = NULL;
86dc4139
AM
18846+
18847+ p->h_dentry = NULL;
18848+ p->h_parent = NULL;
18849+ p->br = NULL;
18850+ p->task = current;
4a4d8108
AM
18851+}
18852+
18853+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
18854+ unsigned int udba, unsigned char flags)
18855+{
18856+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
18857+ udba, flags);
18858+ return au_do_pin(pin);
18859+}
18860+
dece6358
AM
18861+/* ---------------------------------------------------------------------- */
18862+
1308ab2a 18863+/*
4a4d8108
AM
18864+ * ->setattr() and ->getattr() are called in various cases.
18865+ * chmod, stat: dentry is revalidated.
18866+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
18867+ * unhashed.
18868+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 18869+ */
027c5e7a 18870+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
c1595e42 18871+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 18872+{
4a4d8108 18873+ int err;
4a4d8108 18874+ struct dentry *parent;
1facf9fc 18875+
1308ab2a 18876+ err = 0;
027c5e7a 18877+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
18878+ parent = dget_parent(dentry);
18879+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 18880+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
18881+ di_read_unlock(parent, AuLock_IR);
18882+ dput(parent);
dece6358 18883+ }
1facf9fc 18884+
4a4d8108 18885+ AuTraceErr(err);
1308ab2a 18886+ return err;
18887+}
dece6358 18888+
c1595e42
JR
18889+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
18890+ struct au_icpup_args *a)
1308ab2a 18891+{
18892+ int err;
4a4d8108 18893+ loff_t sz;
e49829fe 18894+ aufs_bindex_t bstart, ibstart;
4a4d8108
AM
18895+ struct dentry *hi_wh, *parent;
18896+ struct inode *inode;
4a4d8108
AM
18897+ struct au_wr_dir_args wr_dir_args = {
18898+ .force_btgt = -1,
18899+ .flags = 0
18900+ };
18901+
2000de60 18902+ if (d_is_dir(dentry))
4a4d8108
AM
18903+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
18904+ /* plink or hi_wh() case */
2000de60 18905+ bstart = au_dbstart(dentry);
5527c038 18906+ inode = d_inode(dentry);
e49829fe 18907+ ibstart = au_ibstart(inode);
027c5e7a 18908+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
e49829fe 18909+ wr_dir_args.force_btgt = ibstart;
4a4d8108
AM
18910+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
18911+ if (unlikely(err < 0))
18912+ goto out;
18913+ a->btgt = err;
18914+ if (err != bstart)
18915+ au_fset_icpup(a->flags, DID_CPUP);
18916+
18917+ err = 0;
18918+ a->pin_flags = AuPin_MNT_WRITE;
18919+ parent = NULL;
18920+ if (!IS_ROOT(dentry)) {
18921+ au_fset_pin(a->pin_flags, DI_LOCKED);
18922+ parent = dget_parent(dentry);
18923+ di_write_lock_parent(parent);
18924+ }
18925+
18926+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
18927+ if (unlikely(err))
18928+ goto out_parent;
18929+
18930+ a->h_path.dentry = au_h_dptr(dentry, bstart);
4a4d8108 18931+ sz = -1;
5527c038 18932+ a->h_inode = d_inode(a->h_path.dentry);
c1595e42
JR
18933+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
18934+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
18935+ if (ia->ia_size < i_size_read(a->h_inode))
18936+ sz = ia->ia_size;
18937+ mutex_unlock(&a->h_inode->i_mutex);
18938+ }
4a4d8108 18939+
4a4d8108 18940+ hi_wh = NULL;
027c5e7a 18941+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
18942+ hi_wh = au_hi_wh(inode, a->btgt);
18943+ if (!hi_wh) {
c2b27bf2
AM
18944+ struct au_cp_generic cpg = {
18945+ .dentry = dentry,
18946+ .bdst = a->btgt,
18947+ .bsrc = -1,
18948+ .len = sz,
18949+ .pin = &a->pin
18950+ };
18951+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
18952+ if (unlikely(err))
18953+ goto out_unlock;
18954+ hi_wh = au_hi_wh(inode, a->btgt);
18955+ /* todo: revalidate hi_wh? */
18956+ }
18957+ }
18958+
18959+ if (parent) {
18960+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
18961+ di_downgrade_lock(parent, AuLock_IR);
18962+ dput(parent);
18963+ parent = NULL;
18964+ }
18965+ if (!au_ftest_icpup(a->flags, DID_CPUP))
18966+ goto out; /* success */
18967+
18968+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
18969+ struct au_cp_generic cpg = {
18970+ .dentry = dentry,
18971+ .bdst = a->btgt,
18972+ .bsrc = bstart,
18973+ .len = sz,
18974+ .pin = &a->pin,
18975+ .flags = AuCpup_DTIME | AuCpup_HOPEN
18976+ };
18977+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
18978+ if (!err)
18979+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
18980+ } else if (!hi_wh)
18981+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
18982+ else
18983+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 18984+
4f0767ce 18985+out_unlock:
5527c038 18986+ a->h_inode = d_inode(a->h_path.dentry);
86dc4139 18987+ if (!err)
dece6358 18988+ goto out; /* success */
4a4d8108 18989+ au_unpin(&a->pin);
4f0767ce 18990+out_parent:
4a4d8108
AM
18991+ if (parent) {
18992+ di_write_unlock(parent);
18993+ dput(parent);
18994+ }
4f0767ce 18995+out:
86dc4139
AM
18996+ if (!err)
18997+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
1facf9fc 18998+ return err;
18999+}
19000+
4a4d8108 19001+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 19002+{
4a4d8108 19003+ int err;
523b37e3 19004+ struct inode *inode, *delegated;
4a4d8108
AM
19005+ struct super_block *sb;
19006+ struct file *file;
19007+ struct au_icpup_args *a;
1facf9fc 19008+
5527c038 19009+ inode = d_inode(dentry);
4a4d8108 19010+ IMustLock(inode);
dece6358 19011+
4a4d8108
AM
19012+ err = -ENOMEM;
19013+ a = kzalloc(sizeof(*a), GFP_NOFS);
19014+ if (unlikely(!a))
19015+ goto out;
1facf9fc 19016+
4a4d8108
AM
19017+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
19018+ ia->ia_valid &= ~ATTR_MODE;
dece6358 19019+
4a4d8108
AM
19020+ file = NULL;
19021+ sb = dentry->d_sb;
e49829fe
JR
19022+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
19023+ if (unlikely(err))
19024+ goto out_kfree;
19025+
4a4d8108
AM
19026+ if (ia->ia_valid & ATTR_FILE) {
19027+ /* currently ftruncate(2) only */
7e9cd9fe 19028+ AuDebugOn(!d_is_reg(dentry));
4a4d8108
AM
19029+ file = ia->ia_file;
19030+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
19031+ if (unlikely(err))
19032+ goto out_si;
19033+ ia->ia_file = au_hf_top(file);
19034+ a->udba = AuOpt_UDBA_NONE;
19035+ } else {
19036+ /* fchmod() doesn't pass ia_file */
19037+ a->udba = au_opt_udba(sb);
027c5e7a
AM
19038+ di_write_lock_child(dentry);
19039+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
19040+ if (d_unhashed(dentry))
19041+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
19042+ if (a->udba != AuOpt_UDBA_NONE) {
19043+ AuDebugOn(IS_ROOT(dentry));
19044+ err = au_reval_for_attr(dentry, au_sigen(sb));
19045+ if (unlikely(err))
19046+ goto out_dentry;
19047+ }
dece6358 19048+ }
dece6358 19049+
4a4d8108
AM
19050+ err = au_pin_and_icpup(dentry, ia, a);
19051+ if (unlikely(err < 0))
19052+ goto out_dentry;
19053+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
19054+ ia->ia_file = NULL;
19055+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 19056+ }
dece6358 19057+
4a4d8108
AM
19058+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
19059+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
19060+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 19061+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
19062+ if (unlikely(err))
19063+ goto out_unlock;
19064+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
19065+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 19066+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
19067+ if (unlikely(err))
19068+ goto out_unlock;
19069+ }
dece6358 19070+
4a4d8108
AM
19071+ if (ia->ia_valid & ATTR_SIZE) {
19072+ struct file *f;
1308ab2a 19073+
953406b4 19074+ if (ia->ia_size < i_size_read(inode))
4a4d8108 19075+ /* unmap only */
953406b4 19076+ truncate_setsize(inode, ia->ia_size);
1308ab2a 19077+
4a4d8108
AM
19078+ f = NULL;
19079+ if (ia->ia_valid & ATTR_FILE)
19080+ f = ia->ia_file;
19081+ mutex_unlock(&a->h_inode->i_mutex);
19082+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
19083+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
523b37e3
AM
19084+ } else {
19085+ delegated = NULL;
19086+ while (1) {
19087+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
19088+ if (delegated) {
19089+ err = break_deleg_wait(&delegated);
19090+ if (!err)
19091+ continue;
19092+ }
19093+ break;
19094+ }
19095+ }
4a4d8108
AM
19096+ if (!err)
19097+ au_cpup_attr_changeable(inode);
1308ab2a 19098+
4f0767ce 19099+out_unlock:
4a4d8108
AM
19100+ mutex_unlock(&a->h_inode->i_mutex);
19101+ au_unpin(&a->pin);
027c5e7a
AM
19102+ if (unlikely(err))
19103+ au_update_dbstart(dentry);
4f0767ce 19104+out_dentry:
4a4d8108
AM
19105+ di_write_unlock(dentry);
19106+ if (file) {
19107+ fi_write_unlock(file);
19108+ ia->ia_file = file;
19109+ ia->ia_valid |= ATTR_FILE;
19110+ }
4f0767ce 19111+out_si:
4a4d8108 19112+ si_read_unlock(sb);
e49829fe 19113+out_kfree:
4a4d8108 19114+ kfree(a);
4f0767ce 19115+out:
4a4d8108
AM
19116+ AuTraceErr(err);
19117+ return err;
1facf9fc 19118+}
19119+
c1595e42
JR
19120+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
19121+static int au_h_path_to_set_attr(struct dentry *dentry,
19122+ struct au_icpup_args *a, struct path *h_path)
19123+{
19124+ int err;
19125+ struct super_block *sb;
19126+
19127+ sb = dentry->d_sb;
19128+ a->udba = au_opt_udba(sb);
19129+ /* no d_unlinked(), to set UDBA_NONE for root */
19130+ if (d_unhashed(dentry))
19131+ a->udba = AuOpt_UDBA_NONE;
19132+ if (a->udba != AuOpt_UDBA_NONE) {
19133+ AuDebugOn(IS_ROOT(dentry));
19134+ err = au_reval_for_attr(dentry, au_sigen(sb));
19135+ if (unlikely(err))
19136+ goto out;
19137+ }
19138+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a);
19139+ if (unlikely(err < 0))
19140+ goto out;
19141+
19142+ h_path->dentry = a->h_path.dentry;
19143+ h_path->mnt = au_sbr_mnt(sb, a->btgt);
19144+
19145+out:
19146+ return err;
19147+}
19148+
19149+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg)
19150+{
19151+ int err;
19152+ struct path h_path;
19153+ struct super_block *sb;
19154+ struct au_icpup_args *a;
19155+ struct inode *inode, *h_inode;
19156+
5527c038 19157+ inode = d_inode(dentry);
c1595e42
JR
19158+ IMustLock(inode);
19159+
19160+ err = -ENOMEM;
19161+ a = kzalloc(sizeof(*a), GFP_NOFS);
19162+ if (unlikely(!a))
19163+ goto out;
19164+
19165+ sb = dentry->d_sb;
19166+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
19167+ if (unlikely(err))
19168+ goto out_kfree;
19169+
19170+ h_path.dentry = NULL; /* silence gcc */
19171+ di_write_lock_child(dentry);
19172+ err = au_h_path_to_set_attr(dentry, a, &h_path);
19173+ if (unlikely(err))
19174+ goto out_di;
19175+
19176+ mutex_unlock(&a->h_inode->i_mutex);
19177+ switch (arg->type) {
19178+ case AU_XATTR_SET:
19179+ err = vfsub_setxattr(h_path.dentry,
19180+ arg->u.set.name, arg->u.set.value,
19181+ arg->u.set.size, arg->u.set.flags);
19182+ break;
19183+ case AU_XATTR_REMOVE:
19184+ err = vfsub_removexattr(h_path.dentry, arg->u.remove.name);
19185+ break;
19186+ case AU_ACL_SET:
19187+ err = -EOPNOTSUPP;
5527c038 19188+ h_inode = d_inode(h_path.dentry);
c1595e42
JR
19189+ if (h_inode->i_op->set_acl)
19190+ err = h_inode->i_op->set_acl(h_inode,
19191+ arg->u.acl_set.acl,
19192+ arg->u.acl_set.type);
19193+ break;
19194+ }
19195+ if (!err)
19196+ au_cpup_attr_timesizes(inode);
19197+
19198+ au_unpin(&a->pin);
19199+ if (unlikely(err))
19200+ au_update_dbstart(dentry);
19201+
19202+out_di:
19203+ di_write_unlock(dentry);
19204+ si_read_unlock(sb);
19205+out_kfree:
19206+ kfree(a);
19207+out:
19208+ AuTraceErr(err);
19209+ return err;
19210+}
19211+#endif
19212+
4a4d8108
AM
19213+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
19214+ unsigned int nlink)
1facf9fc 19215+{
9dbd164d
AM
19216+ unsigned int n;
19217+
4a4d8108 19218+ inode->i_mode = st->mode;
86dc4139
AM
19219+ /* don't i_[ug]id_write() here */
19220+ inode->i_uid = st->uid;
19221+ inode->i_gid = st->gid;
4a4d8108
AM
19222+ inode->i_atime = st->atime;
19223+ inode->i_mtime = st->mtime;
19224+ inode->i_ctime = st->ctime;
1facf9fc 19225+
4a4d8108
AM
19226+ au_cpup_attr_nlink(inode, /*force*/0);
19227+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
19228+ n = inode->i_nlink;
19229+ n -= nlink;
19230+ n += st->nlink;
f6b6e03d 19231+ smp_mb(); /* for i_nlink */
7eafdf33 19232+ /* 0 can happen */
92d182d2 19233+ set_nlink(inode, n);
4a4d8108 19234+ }
1facf9fc 19235+
4a4d8108
AM
19236+ spin_lock(&inode->i_lock);
19237+ inode->i_blocks = st->blocks;
19238+ i_size_write(inode, st->size);
19239+ spin_unlock(&inode->i_lock);
1facf9fc 19240+}
19241+
c1595e42
JR
19242+/*
19243+ * common routine for aufs_getattr() and aufs_getxattr().
19244+ * returns zero or negative (an error).
19245+ * @dentry will be read-locked in success.
19246+ */
19247+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path)
1facf9fc 19248+{
4a4d8108 19249+ int err;
076b876e 19250+ unsigned int mnt_flags, sigen;
c1595e42 19251+ unsigned char udba_none;
4a4d8108 19252+ aufs_bindex_t bindex;
4a4d8108
AM
19253+ struct super_block *sb, *h_sb;
19254+ struct inode *inode;
1facf9fc 19255+
c1595e42
JR
19256+ h_path->mnt = NULL;
19257+ h_path->dentry = NULL;
19258+
19259+ err = 0;
4a4d8108 19260+ sb = dentry->d_sb;
4a4d8108
AM
19261+ mnt_flags = au_mntflags(sb);
19262+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 19263+
4a4d8108 19264+ /* support fstat(2) */
027c5e7a 19265+ if (!d_unlinked(dentry) && !udba_none) {
076b876e 19266+ sigen = au_sigen(sb);
027c5e7a
AM
19267+ err = au_digen_test(dentry, sigen);
19268+ if (!err) {
4a4d8108 19269+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a 19270+ err = au_dbrange_test(dentry);
c1595e42
JR
19271+ if (unlikely(err)) {
19272+ di_read_unlock(dentry, AuLock_IR);
19273+ goto out;
19274+ }
027c5e7a 19275+ } else {
4a4d8108
AM
19276+ AuDebugOn(IS_ROOT(dentry));
19277+ di_write_lock_child(dentry);
027c5e7a
AM
19278+ err = au_dbrange_test(dentry);
19279+ if (!err)
19280+ err = au_reval_for_attr(dentry, sigen);
c1595e42
JR
19281+ if (!err)
19282+ di_downgrade_lock(dentry, AuLock_IR);
19283+ else {
19284+ di_write_unlock(dentry);
19285+ goto out;
19286+ }
4a4d8108
AM
19287+ }
19288+ } else
19289+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 19290+
5527c038 19291+ inode = d_inode(dentry);
4a4d8108 19292+ bindex = au_ibstart(inode);
c1595e42
JR
19293+ h_path->mnt = au_sbr_mnt(sb, bindex);
19294+ h_sb = h_path->mnt->mnt_sb;
19295+ if (!force
19296+ && !au_test_fs_bad_iattr(h_sb)
19297+ && udba_none)
19298+ goto out; /* success */
1facf9fc 19299+
4a4d8108 19300+ if (au_dbstart(dentry) == bindex)
c1595e42 19301+ h_path->dentry = au_h_dptr(dentry, bindex);
4a4d8108 19302+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c1595e42
JR
19303+ h_path->dentry = au_plink_lkup(inode, bindex);
19304+ if (IS_ERR(h_path->dentry))
19305+ /* pretending success */
19306+ h_path->dentry = NULL;
19307+ else
19308+ dput(h_path->dentry);
4a4d8108 19309+ }
c1595e42
JR
19310+
19311+out:
19312+ return err;
19313+}
19314+
19315+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
19316+ struct dentry *dentry, struct kstat *st)
19317+{
19318+ int err;
19319+ unsigned char positive;
19320+ struct path h_path;
19321+ struct inode *inode;
19322+ struct super_block *sb;
19323+
5527c038 19324+ inode = d_inode(dentry);
c1595e42
JR
19325+ sb = dentry->d_sb;
19326+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
19327+ if (unlikely(err))
19328+ goto out;
19329+ err = au_h_path_getattr(dentry, /*force*/0, &h_path);
19330+ if (unlikely(err))
19331+ goto out_si;
c06a8ce3 19332+ if (unlikely(!h_path.dentry))
c1595e42 19333+ /* illegally overlapped or something */
4a4d8108
AM
19334+ goto out_fill; /* pretending success */
19335+
5527c038 19336+ positive = d_is_positive(h_path.dentry);
4a4d8108 19337+ if (positive)
c06a8ce3 19338+ err = vfs_getattr(&h_path, st);
4a4d8108
AM
19339+ if (!err) {
19340+ if (positive)
c06a8ce3 19341+ au_refresh_iattr(inode, st,
5527c038 19342+ d_inode(h_path.dentry)->i_nlink);
4a4d8108 19343+ goto out_fill; /* success */
1facf9fc 19344+ }
7f207e10 19345+ AuTraceErr(err);
c1595e42 19346+ goto out_di;
4a4d8108 19347+
4f0767ce 19348+out_fill:
4a4d8108 19349+ generic_fillattr(inode, st);
c1595e42 19350+out_di:
4a4d8108 19351+ di_read_unlock(dentry, AuLock_IR);
c1595e42 19352+out_si:
4a4d8108 19353+ si_read_unlock(sb);
7f207e10
AM
19354+out:
19355+ AuTraceErr(err);
4a4d8108 19356+ return err;
1facf9fc 19357+}
19358+
19359+/* ---------------------------------------------------------------------- */
19360+
c2c0f25c
AM
19361+/*
19362+ * Assumption:
19363+ * - the number of symlinks is not so many.
19364+ *
19365+ * Structure:
19366+ * - sbinfo (instead of iinfo) contains an hlist of struct au_symlink.
19367+ * If iinfo contained the hlist, then it would be rather large waste of memory
19368+ * I am afraid.
19369+ * - struct au_symlink contains the necessary info for h_inode follow_link() and
19370+ * put_link().
19371+ */
1facf9fc 19372+
c2c0f25c
AM
19373+struct au_symlink {
19374+ union {
19375+ struct hlist_node hlist;
19376+ struct rcu_head rcu;
19377+ };
1facf9fc 19378+
c2c0f25c
AM
19379+ struct inode *h_inode;
19380+ void *h_cookie;
19381+};
1facf9fc 19382+
c2c0f25c
AM
19383+static void au_symlink_add(struct super_block *sb, struct au_symlink *slink,
19384+ struct inode *h_inode, void *cookie)
19385+{
19386+ struct au_sbinfo *sbinfo;
1facf9fc 19387+
c2c0f25c
AM
19388+ ihold(h_inode);
19389+ slink->h_inode = h_inode;
19390+ slink->h_cookie = cookie;
19391+ sbinfo = au_sbi(sb);
19392+ au_sphl_add(&slink->hlist, &sbinfo->si_symlink);
4a4d8108 19393+}
1facf9fc 19394+
c2c0f25c 19395+static void au_symlink_del(struct super_block *sb, struct au_symlink *slink)
4a4d8108 19396+{
c2c0f25c 19397+ struct au_sbinfo *sbinfo;
1facf9fc 19398+
c2c0f25c
AM
19399+ /* do not iput() within rcu */
19400+ iput(slink->h_inode);
19401+ slink->h_inode = NULL;
19402+ sbinfo = au_sbi(sb);
19403+ au_sphl_del_rcu(&slink->hlist, &sbinfo->si_symlink);
19404+ kfree_rcu(slink, rcu);
4a4d8108 19405+}
1facf9fc 19406+
c2c0f25c 19407+static const char *aufs_follow_link(struct dentry *dentry, void **cookie)
4a4d8108 19408+{
c2c0f25c
AM
19409+ const char *ret;
19410+ struct inode *inode, *h_inode;
19411+ struct dentry *h_dentry;
19412+ struct au_symlink *slink;
4a4d8108 19413+ int err;
c2c0f25c 19414+ aufs_bindex_t bindex;
1facf9fc 19415+
79b8bda9 19416+ ret = NULL; /* suppress a warning */
027c5e7a
AM
19417+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
19418+ if (unlikely(err))
c2c0f25c 19419+ goto out;
027c5e7a
AM
19420+
19421+ err = au_d_hashed_positive(dentry);
c2c0f25c
AM
19422+ if (unlikely(err))
19423+ goto out_unlock;
19424+
19425+ err = -EINVAL;
19426+ inode = d_inode(dentry);
19427+ bindex = au_ibstart(inode);
19428+ h_inode = au_h_iptr(inode, bindex);
19429+ if (unlikely(!h_inode->i_op->follow_link))
19430+ goto out_unlock;
19431+
19432+ err = -ENOMEM;
19433+ slink = kmalloc(sizeof(*slink), GFP_NOFS);
19434+ if (unlikely(!slink))
19435+ goto out_unlock;
19436+
19437+ err = -EBUSY;
19438+ h_dentry = NULL;
19439+ if (au_dbstart(dentry) <= bindex) {
19440+ h_dentry = au_h_dptr(dentry, bindex);
19441+ if (h_dentry)
19442+ dget(h_dentry);
027c5e7a 19443+ }
c2c0f25c
AM
19444+ if (!h_dentry) {
19445+ h_dentry = d_find_any_alias(h_inode);
19446+ if (IS_ERR(h_dentry)) {
19447+ err = PTR_ERR(h_dentry);
19448+ goto out_free;
19449+ }
19450+ }
19451+ if (unlikely(!h_dentry))
19452+ goto out_free;
1facf9fc 19453+
c2c0f25c
AM
19454+ err = 0;
19455+ AuDbg("%pf\n", h_inode->i_op->follow_link);
19456+ AuDbgDentry(h_dentry);
19457+ ret = h_inode->i_op->follow_link(h_dentry, cookie);
19458+ dput(h_dentry);
19459+
19460+ if (!IS_ERR_OR_NULL(ret)) {
19461+ au_symlink_add(inode->i_sb, slink, h_inode, *cookie);
19462+ *cookie = slink;
19463+ AuDbg("slink %p\n", slink);
19464+ goto out_unlock; /* success */
1308ab2a 19465+ }
1facf9fc 19466+
c2c0f25c
AM
19467+out_free:
19468+ slink->h_inode = NULL;
19469+ kfree_rcu(slink, rcu);
19470+out_unlock:
19471+ aufs_read_unlock(dentry, AuLock_IR);
4f0767ce 19472+out:
c2c0f25c
AM
19473+ if (unlikely(err))
19474+ ret = ERR_PTR(err);
19475+ AuTraceErrPtr(ret);
19476+ return ret;
4a4d8108 19477+}
1facf9fc 19478+
c2c0f25c 19479+static void aufs_put_link(struct inode *inode, void *cookie)
4a4d8108 19480+{
c2c0f25c
AM
19481+ struct au_symlink *slink;
19482+ struct inode *h_inode;
537831f9 19483+
c2c0f25c
AM
19484+ slink = cookie;
19485+ AuDbg("slink %p\n", slink);
19486+ h_inode = slink->h_inode;
19487+ AuDbg("%pf\n", h_inode->i_op->put_link);
19488+ AuDbgInode(h_inode);
19489+ if (h_inode->i_op->put_link)
19490+ h_inode->i_op->put_link(h_inode, slink->h_cookie);
19491+ au_symlink_del(inode->i_sb, slink);
4a4d8108 19492+}
1facf9fc 19493+
4a4d8108 19494+/* ---------------------------------------------------------------------- */
1facf9fc 19495+
0c3ec466 19496+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 19497+{
0c3ec466
AM
19498+ int err;
19499+ struct super_block *sb;
19500+ struct inode *h_inode;
19501+
19502+ sb = inode->i_sb;
19503+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
19504+ lockdep_off();
19505+ si_read_lock(sb, AuLock_FLUSH);
19506+ ii_write_lock_child(inode);
19507+ lockdep_on();
19508+ h_inode = au_h_iptr(inode, au_ibstart(inode));
19509+ err = vfsub_update_time(h_inode, ts, flags);
19510+ lockdep_off();
38d290e6
JR
19511+ if (!err)
19512+ au_cpup_attr_timesizes(inode);
0c3ec466
AM
19513+ ii_write_unlock(inode);
19514+ si_read_unlock(sb);
19515+ lockdep_on();
38d290e6
JR
19516+
19517+ if (!err && (flags & S_VERSION))
19518+ inode_inc_iversion(inode);
19519+
0c3ec466 19520+ return err;
4a4d8108 19521+}
1facf9fc 19522+
4a4d8108 19523+/* ---------------------------------------------------------------------- */
1308ab2a 19524+
4a4d8108
AM
19525+struct inode_operations aufs_symlink_iop = {
19526+ .permission = aufs_permission,
c1595e42
JR
19527+#ifdef CONFIG_FS_POSIX_ACL
19528+ .get_acl = aufs_get_acl,
19529+ .set_acl = aufs_set_acl, /* unsupport for symlink? */
19530+#endif
19531+
4a4d8108
AM
19532+ .setattr = aufs_setattr,
19533+ .getattr = aufs_getattr,
0c3ec466 19534+
c1595e42
JR
19535+#ifdef CONFIG_AUFS_XATTR
19536+ .setxattr = aufs_setxattr,
19537+ .getxattr = aufs_getxattr,
19538+ .listxattr = aufs_listxattr,
19539+ .removexattr = aufs_removexattr,
19540+#endif
19541+
c2c0f25c 19542+ .readlink = generic_readlink,
4a4d8108 19543+ .follow_link = aufs_follow_link,
0c3ec466
AM
19544+ .put_link = aufs_put_link,
19545+
19546+ /* .update_time = aufs_update_time */
4a4d8108
AM
19547+};
19548+
19549+struct inode_operations aufs_dir_iop = {
19550+ .create = aufs_create,
19551+ .lookup = aufs_lookup,
19552+ .link = aufs_link,
19553+ .unlink = aufs_unlink,
19554+ .symlink = aufs_symlink,
19555+ .mkdir = aufs_mkdir,
19556+ .rmdir = aufs_rmdir,
19557+ .mknod = aufs_mknod,
19558+ .rename = aufs_rename,
19559+
19560+ .permission = aufs_permission,
c1595e42
JR
19561+#ifdef CONFIG_FS_POSIX_ACL
19562+ .get_acl = aufs_get_acl,
19563+ .set_acl = aufs_set_acl,
19564+#endif
19565+
4a4d8108 19566+ .setattr = aufs_setattr,
0c3ec466
AM
19567+ .getattr = aufs_getattr,
19568+
c1595e42
JR
19569+#ifdef CONFIG_AUFS_XATTR
19570+ .setxattr = aufs_setxattr,
19571+ .getxattr = aufs_getxattr,
19572+ .listxattr = aufs_listxattr,
19573+ .removexattr = aufs_removexattr,
19574+#endif
19575+
38d290e6 19576+ .update_time = aufs_update_time,
b912730e 19577+ .atomic_open = aufs_atomic_open,
38d290e6 19578+ .tmpfile = aufs_tmpfile
4a4d8108
AM
19579+};
19580+
19581+struct inode_operations aufs_iop = {
19582+ .permission = aufs_permission,
c1595e42
JR
19583+#ifdef CONFIG_FS_POSIX_ACL
19584+ .get_acl = aufs_get_acl,
19585+ .set_acl = aufs_set_acl,
19586+#endif
19587+
4a4d8108
AM
19588+ .setattr = aufs_setattr,
19589+ .getattr = aufs_getattr,
0c3ec466 19590+
c1595e42
JR
19591+#ifdef CONFIG_AUFS_XATTR
19592+ .setxattr = aufs_setxattr,
19593+ .getxattr = aufs_getxattr,
19594+ .listxattr = aufs_listxattr,
19595+ .removexattr = aufs_removexattr,
19596+#endif
19597+
0c3ec466 19598+ .update_time = aufs_update_time
4a4d8108 19599+};
7f207e10
AM
19600diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
19601--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 19602+++ linux/fs/aufs/i_op_del.c 2015-09-24 10:47:58.254719746 +0200
5527c038 19603@@ -0,0 +1,510 @@
1facf9fc 19604+/*
2000de60 19605+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 19606+ *
19607+ * This program, aufs is free software; you can redistribute it and/or modify
19608+ * it under the terms of the GNU General Public License as published by
19609+ * the Free Software Foundation; either version 2 of the License, or
19610+ * (at your option) any later version.
dece6358
AM
19611+ *
19612+ * This program is distributed in the hope that it will be useful,
19613+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19614+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19615+ * GNU General Public License for more details.
19616+ *
19617+ * You should have received a copy of the GNU General Public License
523b37e3 19618+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19619+ */
19620+
19621+/*
4a4d8108 19622+ * inode operations (del entry)
1308ab2a 19623+ */
dece6358 19624+
1308ab2a 19625+#include "aufs.h"
dece6358 19626+
4a4d8108
AM
19627+/*
19628+ * decide if a new whiteout for @dentry is necessary or not.
19629+ * when it is necessary, prepare the parent dir for the upper branch whose
19630+ * branch index is @bcpup for creation. the actual creation of the whiteout will
19631+ * be done by caller.
19632+ * return value:
19633+ * 0: wh is unnecessary
19634+ * plus: wh is necessary
19635+ * minus: error
19636+ */
19637+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 19638+{
4a4d8108
AM
19639+ int need_wh, err;
19640+ aufs_bindex_t bstart;
19641+ struct super_block *sb;
dece6358 19642+
4a4d8108
AM
19643+ sb = dentry->d_sb;
19644+ bstart = au_dbstart(dentry);
19645+ if (*bcpup < 0) {
19646+ *bcpup = bstart;
5527c038 19647+ if (au_test_ro(sb, bstart, d_inode(dentry))) {
4a4d8108
AM
19648+ err = AuWbrCopyup(au_sbi(sb), dentry);
19649+ *bcpup = err;
19650+ if (unlikely(err < 0))
19651+ goto out;
19652+ }
19653+ } else
19654+ AuDebugOn(bstart < *bcpup
5527c038 19655+ || au_test_ro(sb, *bcpup, d_inode(dentry)));
4a4d8108 19656+ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
1308ab2a 19657+
4a4d8108
AM
19658+ if (*bcpup != bstart) {
19659+ err = au_cpup_dirs(dentry, *bcpup);
19660+ if (unlikely(err))
19661+ goto out;
19662+ need_wh = 1;
19663+ } else {
027c5e7a 19664+ struct au_dinfo *dinfo, *tmp;
4a4d8108 19665+
027c5e7a
AM
19666+ need_wh = -ENOMEM;
19667+ dinfo = au_di(dentry);
19668+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
19669+ if (tmp) {
19670+ au_di_cp(tmp, dinfo);
19671+ au_di_swap(tmp, dinfo);
19672+ /* returns the number of positive dentries */
537831f9 19673+ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
027c5e7a
AM
19674+ au_di_swap(tmp, dinfo);
19675+ au_rw_write_unlock(&tmp->di_rwsem);
19676+ au_di_free(tmp);
4a4d8108
AM
19677+ }
19678+ }
19679+ AuDbg("need_wh %d\n", need_wh);
19680+ err = need_wh;
19681+
4f0767ce 19682+out:
4a4d8108 19683+ return err;
1facf9fc 19684+}
19685+
4a4d8108
AM
19686+/*
19687+ * simple tests for the del-entry operations.
19688+ * following the checks in vfs, plus the parent-child relationship.
19689+ */
19690+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
19691+ struct dentry *h_parent, int isdir)
1facf9fc 19692+{
4a4d8108
AM
19693+ int err;
19694+ umode_t h_mode;
19695+ struct dentry *h_dentry, *h_latest;
1308ab2a 19696+ struct inode *h_inode;
1facf9fc 19697+
4a4d8108 19698+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 19699+ if (d_really_is_positive(dentry)) {
4a4d8108 19700+ err = -ENOENT;
5527c038
JR
19701+ if (unlikely(d_is_negative(h_dentry)))
19702+ goto out;
19703+ h_inode = d_inode(h_dentry);
19704+ if (unlikely(!h_inode->i_nlink))
4a4d8108 19705+ goto out;
1facf9fc 19706+
4a4d8108
AM
19707+ h_mode = h_inode->i_mode;
19708+ if (!isdir) {
19709+ err = -EISDIR;
19710+ if (unlikely(S_ISDIR(h_mode)))
19711+ goto out;
19712+ } else if (unlikely(!S_ISDIR(h_mode))) {
19713+ err = -ENOTDIR;
19714+ goto out;
19715+ }
19716+ } else {
19717+ /* rename(2) case */
19718+ err = -EIO;
5527c038 19719+ if (unlikely(d_is_positive(h_dentry)))
4a4d8108
AM
19720+ goto out;
19721+ }
1facf9fc 19722+
4a4d8108
AM
19723+ err = -ENOENT;
19724+ /* expected parent dir is locked */
19725+ if (unlikely(h_parent != h_dentry->d_parent))
19726+ goto out;
19727+ err = 0;
19728+
19729+ /*
19730+ * rmdir a dir may break the consistency on some filesystem.
19731+ * let's try heavy test.
19732+ */
19733+ err = -EACCES;
076b876e 19734+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
5527c038 19735+ && au_test_h_perm(d_inode(h_parent),
076b876e 19736+ MAY_EXEC | MAY_WRITE)))
4a4d8108
AM
19737+ goto out;
19738+
076b876e 19739+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
4a4d8108
AM
19740+ err = -EIO;
19741+ if (IS_ERR(h_latest))
19742+ goto out;
19743+ if (h_latest == h_dentry)
19744+ err = 0;
19745+ dput(h_latest);
19746+
4f0767ce 19747+out:
4a4d8108 19748+ return err;
1308ab2a 19749+}
1facf9fc 19750+
4a4d8108
AM
19751+/*
19752+ * decide the branch where we operate for @dentry. the branch index will be set
19753+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
19754+ * dir for reverting.
19755+ * when a new whiteout is necessary, create it.
19756+ */
19757+static struct dentry*
19758+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
19759+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 19760+{
4a4d8108
AM
19761+ struct dentry *wh_dentry;
19762+ struct super_block *sb;
19763+ struct path h_path;
19764+ int err, need_wh;
19765+ unsigned int udba;
19766+ aufs_bindex_t bcpup;
dece6358 19767+
4a4d8108
AM
19768+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
19769+ wh_dentry = ERR_PTR(need_wh);
19770+ if (unlikely(need_wh < 0))
19771+ goto out;
19772+
19773+ sb = dentry->d_sb;
19774+ udba = au_opt_udba(sb);
19775+ bcpup = *rbcpup;
19776+ err = au_pin(pin, dentry, bcpup, udba,
19777+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
19778+ wh_dentry = ERR_PTR(err);
19779+ if (unlikely(err))
19780+ goto out;
19781+
19782+ h_path.dentry = au_pinned_h_parent(pin);
19783+ if (udba != AuOpt_UDBA_NONE
19784+ && au_dbstart(dentry) == bcpup) {
19785+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
19786+ wh_dentry = ERR_PTR(err);
19787+ if (unlikely(err))
19788+ goto out_unpin;
19789+ }
19790+
19791+ h_path.mnt = au_sbr_mnt(sb, bcpup);
19792+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
19793+ wh_dentry = NULL;
19794+ if (!need_wh)
19795+ goto out; /* success, no need to create whiteout */
19796+
19797+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
19798+ if (IS_ERR(wh_dentry))
19799+ goto out_unpin;
19800+
19801+ /* returns with the parent is locked and wh_dentry is dget-ed */
19802+ goto out; /* success */
19803+
4f0767ce 19804+out_unpin:
4a4d8108 19805+ au_unpin(pin);
4f0767ce 19806+out:
4a4d8108 19807+ return wh_dentry;
1facf9fc 19808+}
19809+
4a4d8108
AM
19810+/*
19811+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
19812+ * in order to be revertible and save time for removing many child whiteouts
19813+ * under the dir.
19814+ * returns 1 when there are too many child whiteout and caller should remove
19815+ * them asynchronously. returns 0 when the number of children is enough small to
19816+ * remove now or the branch fs is a remote fs.
19817+ * otherwise return an error.
19818+ */
19819+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
19820+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 19821+{
4a4d8108
AM
19822+ int rmdir_later, err, dirwh;
19823+ struct dentry *h_dentry;
19824+ struct super_block *sb;
5527c038 19825+ struct inode *inode;
4a4d8108
AM
19826+
19827+ sb = dentry->d_sb;
19828+ SiMustAnyLock(sb);
19829+ h_dentry = au_h_dptr(dentry, bindex);
19830+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
19831+ if (unlikely(err))
19832+ goto out;
19833+
19834+ /* stop monitoring */
5527c038
JR
19835+ inode = d_inode(dentry);
19836+ au_hn_free(au_hi(inode, bindex));
4a4d8108
AM
19837+
19838+ if (!au_test_fs_remote(h_dentry->d_sb)) {
19839+ dirwh = au_sbi(sb)->si_dirwh;
19840+ rmdir_later = (dirwh <= 1);
19841+ if (!rmdir_later)
19842+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
19843+ dirwh);
19844+ if (rmdir_later)
19845+ return rmdir_later;
19846+ }
1facf9fc 19847+
4a4d8108
AM
19848+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
19849+ if (unlikely(err)) {
523b37e3
AM
19850+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
19851+ h_dentry, bindex, err);
4a4d8108
AM
19852+ err = 0;
19853+ }
dece6358 19854+
4f0767ce 19855+out:
4a4d8108
AM
19856+ AuTraceErr(err);
19857+ return err;
19858+}
1308ab2a 19859+
4a4d8108
AM
19860+/*
19861+ * final procedure for deleting a entry.
19862+ * maintain dentry and iattr.
19863+ */
19864+static void epilog(struct inode *dir, struct dentry *dentry,
19865+ aufs_bindex_t bindex)
19866+{
19867+ struct inode *inode;
1308ab2a 19868+
5527c038 19869+ inode = d_inode(dentry);
4a4d8108
AM
19870+ d_drop(dentry);
19871+ inode->i_ctime = dir->i_ctime;
1308ab2a 19872+
b912730e 19873+ au_dir_ts(dir, bindex);
4a4d8108 19874+ dir->i_version++;
1facf9fc 19875+}
19876+
4a4d8108
AM
19877+/*
19878+ * when an error happened, remove the created whiteout and revert everything.
19879+ */
7f207e10
AM
19880+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
19881+ aufs_bindex_t bwh, struct dentry *wh_dentry,
19882+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 19883+{
4a4d8108
AM
19884+ int rerr;
19885+ struct path h_path = {
19886+ .dentry = wh_dentry,
7f207e10 19887+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 19888+ };
dece6358 19889+
7f207e10 19890+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
19891+ if (!rerr) {
19892+ au_set_dbwh(dentry, bwh);
19893+ au_dtime_revert(dt);
19894+ return 0;
19895+ }
dece6358 19896+
523b37e3 19897+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 19898+ return -EIO;
1facf9fc 19899+}
19900+
4a4d8108 19901+/* ---------------------------------------------------------------------- */
1facf9fc 19902+
4a4d8108 19903+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 19904+{
4a4d8108
AM
19905+ int err;
19906+ aufs_bindex_t bwh, bindex, bstart;
523b37e3 19907+ struct inode *inode, *h_dir, *delegated;
4a4d8108 19908+ struct dentry *parent, *wh_dentry;
c2b27bf2
AM
19909+ /* to reuduce stack size */
19910+ struct {
19911+ struct au_dtime dt;
19912+ struct au_pin pin;
19913+ struct path h_path;
19914+ } *a;
1facf9fc 19915+
4a4d8108 19916+ IMustLock(dir);
027c5e7a 19917+
c2b27bf2
AM
19918+ err = -ENOMEM;
19919+ a = kmalloc(sizeof(*a), GFP_NOFS);
19920+ if (unlikely(!a))
19921+ goto out;
19922+
027c5e7a
AM
19923+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
19924+ if (unlikely(err))
c2b27bf2 19925+ goto out_free;
027c5e7a
AM
19926+ err = au_d_hashed_positive(dentry);
19927+ if (unlikely(err))
19928+ goto out_unlock;
5527c038 19929+ inode = d_inode(dentry);
4a4d8108 19930+ IMustLock(inode);
027c5e7a 19931+ err = -EISDIR;
2000de60 19932+ if (unlikely(d_is_dir(dentry)))
027c5e7a 19933+ goto out_unlock; /* possible? */
1facf9fc 19934+
4a4d8108
AM
19935+ bstart = au_dbstart(dentry);
19936+ bwh = au_dbwh(dentry);
19937+ bindex = -1;
027c5e7a
AM
19938+ parent = dentry->d_parent; /* dir inode is locked */
19939+ di_write_lock_parent(parent);
c2b27bf2
AM
19940+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
19941+ &a->pin);
4a4d8108
AM
19942+ err = PTR_ERR(wh_dentry);
19943+ if (IS_ERR(wh_dentry))
027c5e7a 19944+ goto out_parent;
1facf9fc 19945+
c2b27bf2
AM
19946+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
19947+ a->h_path.dentry = au_h_dptr(dentry, bstart);
19948+ dget(a->h_path.dentry);
4a4d8108 19949+ if (bindex == bstart) {
c2b27bf2 19950+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
19951+ delegated = NULL;
19952+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
19953+ if (unlikely(err == -EWOULDBLOCK)) {
19954+ pr_warn("cannot retry for NFSv4 delegation"
19955+ " for an internal unlink\n");
19956+ iput(delegated);
19957+ }
4a4d8108
AM
19958+ } else {
19959+ /* dir inode is locked */
5527c038 19960+ h_dir = d_inode(wh_dentry->d_parent);
4a4d8108
AM
19961+ IMustLock(h_dir);
19962+ err = 0;
19963+ }
dece6358 19964+
4a4d8108 19965+ if (!err) {
7f207e10 19966+ vfsub_drop_nlink(inode);
4a4d8108
AM
19967+ epilog(dir, dentry, bindex);
19968+
19969+ /* update target timestamps */
19970+ if (bindex == bstart) {
c2b27bf2
AM
19971+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
19972+ /*ignore*/
5527c038 19973+ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
4a4d8108
AM
19974+ } else
19975+ /* todo: this timestamp may be reverted later */
19976+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 19977+ goto out_unpin; /* success */
1facf9fc 19978+ }
19979+
4a4d8108
AM
19980+ /* revert */
19981+ if (wh_dentry) {
19982+ int rerr;
19983+
c2b27bf2
AM
19984+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
19985+ &a->dt);
4a4d8108
AM
19986+ if (rerr)
19987+ err = rerr;
dece6358 19988+ }
1facf9fc 19989+
027c5e7a 19990+out_unpin:
c2b27bf2 19991+ au_unpin(&a->pin);
4a4d8108 19992+ dput(wh_dentry);
c2b27bf2 19993+ dput(a->h_path.dentry);
027c5e7a 19994+out_parent:
4a4d8108 19995+ di_write_unlock(parent);
027c5e7a 19996+out_unlock:
4a4d8108 19997+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
19998+out_free:
19999+ kfree(a);
027c5e7a 20000+out:
4a4d8108 20001+ return err;
dece6358
AM
20002+}
20003+
4a4d8108 20004+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 20005+{
4a4d8108
AM
20006+ int err, rmdir_later;
20007+ aufs_bindex_t bwh, bindex, bstart;
4a4d8108
AM
20008+ struct inode *inode;
20009+ struct dentry *parent, *wh_dentry, *h_dentry;
20010+ struct au_whtmp_rmdir *args;
c2b27bf2
AM
20011+ /* to reuduce stack size */
20012+ struct {
20013+ struct au_dtime dt;
20014+ struct au_pin pin;
20015+ } *a;
1facf9fc 20016+
4a4d8108 20017+ IMustLock(dir);
027c5e7a 20018+
c2b27bf2
AM
20019+ err = -ENOMEM;
20020+ a = kmalloc(sizeof(*a), GFP_NOFS);
20021+ if (unlikely(!a))
20022+ goto out;
20023+
027c5e7a
AM
20024+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
20025+ if (unlikely(err))
c2b27bf2 20026+ goto out_free;
53392da6
AM
20027+ err = au_alive_dir(dentry);
20028+ if (unlikely(err))
027c5e7a 20029+ goto out_unlock;
5527c038 20030+ inode = d_inode(dentry);
4a4d8108 20031+ IMustLock(inode);
027c5e7a 20032+ err = -ENOTDIR;
2000de60 20033+ if (unlikely(!d_is_dir(dentry)))
027c5e7a 20034+ goto out_unlock; /* possible? */
dece6358 20035+
4a4d8108
AM
20036+ err = -ENOMEM;
20037+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
20038+ if (unlikely(!args))
20039+ goto out_unlock;
dece6358 20040+
4a4d8108
AM
20041+ parent = dentry->d_parent; /* dir inode is locked */
20042+ di_write_lock_parent(parent);
20043+ err = au_test_empty(dentry, &args->whlist);
20044+ if (unlikely(err))
027c5e7a 20045+ goto out_parent;
1facf9fc 20046+
4a4d8108
AM
20047+ bstart = au_dbstart(dentry);
20048+ bwh = au_dbwh(dentry);
20049+ bindex = -1;
c2b27bf2
AM
20050+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
20051+ &a->pin);
4a4d8108
AM
20052+ err = PTR_ERR(wh_dentry);
20053+ if (IS_ERR(wh_dentry))
027c5e7a 20054+ goto out_parent;
1facf9fc 20055+
4a4d8108
AM
20056+ h_dentry = au_h_dptr(dentry, bstart);
20057+ dget(h_dentry);
20058+ rmdir_later = 0;
20059+ if (bindex == bstart) {
20060+ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
20061+ if (err > 0) {
20062+ rmdir_later = err;
20063+ err = 0;
20064+ }
20065+ } else {
20066+ /* stop monitoring */
20067+ au_hn_free(au_hi(inode, bstart));
20068+
20069+ /* dir inode is locked */
5527c038 20070+ IMustLock(d_inode(wh_dentry->d_parent));
1facf9fc 20071+ err = 0;
20072+ }
20073+
4a4d8108 20074+ if (!err) {
027c5e7a 20075+ vfsub_dead_dir(inode);
4a4d8108
AM
20076+ au_set_dbdiropq(dentry, -1);
20077+ epilog(dir, dentry, bindex);
1308ab2a 20078+
4a4d8108
AM
20079+ if (rmdir_later) {
20080+ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
20081+ args = NULL;
20082+ }
1308ab2a 20083+
4a4d8108 20084+ goto out_unpin; /* success */
1facf9fc 20085+ }
20086+
4a4d8108
AM
20087+ /* revert */
20088+ AuLabel(revert);
20089+ if (wh_dentry) {
20090+ int rerr;
1308ab2a 20091+
c2b27bf2
AM
20092+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
20093+ &a->dt);
4a4d8108
AM
20094+ if (rerr)
20095+ err = rerr;
1facf9fc 20096+ }
20097+
4f0767ce 20098+out_unpin:
c2b27bf2 20099+ au_unpin(&a->pin);
4a4d8108
AM
20100+ dput(wh_dentry);
20101+ dput(h_dentry);
027c5e7a 20102+out_parent:
4a4d8108
AM
20103+ di_write_unlock(parent);
20104+ if (args)
20105+ au_whtmp_rmdir_free(args);
4f0767ce 20106+out_unlock:
4a4d8108 20107+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
20108+out_free:
20109+ kfree(a);
4f0767ce 20110+out:
4a4d8108
AM
20111+ AuTraceErr(err);
20112+ return err;
dece6358 20113+}
7f207e10
AM
20114diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
20115--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9 20116+++ linux/fs/aufs/i_op_ren.c 2015-11-11 17:21:46.918863802 +0100
5527c038 20117@@ -0,0 +1,1017 @@
1facf9fc 20118+/*
2000de60 20119+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 20120+ *
20121+ * This program, aufs is free software; you can redistribute it and/or modify
20122+ * it under the terms of the GNU General Public License as published by
20123+ * the Free Software Foundation; either version 2 of the License, or
20124+ * (at your option) any later version.
dece6358
AM
20125+ *
20126+ * This program is distributed in the hope that it will be useful,
20127+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20128+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20129+ * GNU General Public License for more details.
20130+ *
20131+ * You should have received a copy of the GNU General Public License
523b37e3 20132+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 20133+ */
20134+
20135+/*
4a4d8108
AM
20136+ * inode operation (rename entry)
20137+ * todo: this is crazy monster
1facf9fc 20138+ */
20139+
20140+#include "aufs.h"
20141+
4a4d8108
AM
20142+enum { AuSRC, AuDST, AuSrcDst };
20143+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 20144+
4a4d8108
AM
20145+#define AuRen_ISDIR 1
20146+#define AuRen_ISSAMEDIR (1 << 1)
20147+#define AuRen_WHSRC (1 << 2)
20148+#define AuRen_WHDST (1 << 3)
20149+#define AuRen_MNT_WRITE (1 << 4)
20150+#define AuRen_DT_DSTDIR (1 << 5)
20151+#define AuRen_DIROPQ (1 << 6)
4a4d8108 20152+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
20153+#define au_fset_ren(flags, name) \
20154+ do { (flags) |= AuRen_##name; } while (0)
20155+#define au_fclr_ren(flags, name) \
20156+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 20157+
4a4d8108
AM
20158+struct au_ren_args {
20159+ struct {
20160+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
20161+ *wh_dentry;
20162+ struct inode *dir, *inode;
20163+ struct au_hinode *hdir;
20164+ struct au_dtime dt[AuParentChild];
20165+ aufs_bindex_t bstart;
20166+ } sd[AuSrcDst];
1facf9fc 20167+
4a4d8108
AM
20168+#define src_dentry sd[AuSRC].dentry
20169+#define src_dir sd[AuSRC].dir
20170+#define src_inode sd[AuSRC].inode
20171+#define src_h_dentry sd[AuSRC].h_dentry
20172+#define src_parent sd[AuSRC].parent
20173+#define src_h_parent sd[AuSRC].h_parent
20174+#define src_wh_dentry sd[AuSRC].wh_dentry
20175+#define src_hdir sd[AuSRC].hdir
20176+#define src_h_dir sd[AuSRC].hdir->hi_inode
20177+#define src_dt sd[AuSRC].dt
20178+#define src_bstart sd[AuSRC].bstart
1facf9fc 20179+
4a4d8108
AM
20180+#define dst_dentry sd[AuDST].dentry
20181+#define dst_dir sd[AuDST].dir
20182+#define dst_inode sd[AuDST].inode
20183+#define dst_h_dentry sd[AuDST].h_dentry
20184+#define dst_parent sd[AuDST].parent
20185+#define dst_h_parent sd[AuDST].h_parent
20186+#define dst_wh_dentry sd[AuDST].wh_dentry
20187+#define dst_hdir sd[AuDST].hdir
20188+#define dst_h_dir sd[AuDST].hdir->hi_inode
20189+#define dst_dt sd[AuDST].dt
20190+#define dst_bstart sd[AuDST].bstart
20191+
20192+ struct dentry *h_trap;
20193+ struct au_branch *br;
20194+ struct au_hinode *src_hinode;
20195+ struct path h_path;
20196+ struct au_nhash whlist;
027c5e7a 20197+ aufs_bindex_t btgt, src_bwh, src_bdiropq;
1facf9fc 20198+
1308ab2a 20199+ unsigned int flags;
1facf9fc 20200+
4a4d8108
AM
20201+ struct au_whtmp_rmdir *thargs;
20202+ struct dentry *h_dst;
20203+};
1308ab2a 20204+
4a4d8108 20205+/* ---------------------------------------------------------------------- */
1308ab2a 20206+
4a4d8108
AM
20207+/*
20208+ * functions for reverting.
20209+ * when an error happened in a single rename systemcall, we should revert
79b8bda9 20210+ * everything as if nothing happened.
4a4d8108
AM
20211+ * we don't need to revert the copied-up/down the parent dir since they are
20212+ * harmless.
20213+ */
1facf9fc 20214+
4a4d8108
AM
20215+#define RevertFailure(fmt, ...) do { \
20216+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
20217+ ##__VA_ARGS__, err, rerr); \
20218+ err = -EIO; \
20219+} while (0)
1facf9fc 20220+
4a4d8108 20221+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
1facf9fc 20222+{
4a4d8108 20223+ int rerr;
1facf9fc 20224+
4a4d8108
AM
20225+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
20226+ rerr = au_diropq_remove(a->src_dentry, a->btgt);
20227+ au_hn_imtx_unlock(a->src_hinode);
027c5e7a 20228+ au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
4a4d8108 20229+ if (rerr)
523b37e3 20230+ RevertFailure("remove diropq %pd", a->src_dentry);
4a4d8108 20231+}
1facf9fc 20232+
4a4d8108
AM
20233+static void au_ren_rev_rename(int err, struct au_ren_args *a)
20234+{
20235+ int rerr;
523b37e3 20236+ struct inode *delegated;
1facf9fc 20237+
b4510431
AM
20238+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
20239+ a->src_h_parent);
4a4d8108
AM
20240+ rerr = PTR_ERR(a->h_path.dentry);
20241+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 20242+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 20243+ return;
1facf9fc 20244+ }
20245+
523b37e3 20246+ delegated = NULL;
4a4d8108
AM
20247+ rerr = vfsub_rename(a->dst_h_dir,
20248+ au_h_dptr(a->src_dentry, a->btgt),
523b37e3
AM
20249+ a->src_h_dir, &a->h_path, &delegated);
20250+ if (unlikely(rerr == -EWOULDBLOCK)) {
20251+ pr_warn("cannot retry for NFSv4 delegation"
20252+ " for an internal rename\n");
20253+ iput(delegated);
20254+ }
4a4d8108
AM
20255+ d_drop(a->h_path.dentry);
20256+ dput(a->h_path.dentry);
20257+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
20258+ if (rerr)
523b37e3 20259+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 20260+}
20261+
4a4d8108 20262+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 20263+{
4a4d8108 20264+ int rerr;
523b37e3 20265+ struct inode *delegated;
dece6358 20266+
b4510431
AM
20267+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
20268+ a->dst_h_parent);
4a4d8108
AM
20269+ rerr = PTR_ERR(a->h_path.dentry);
20270+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 20271+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
20272+ return;
20273+ }
5527c038 20274+ if (d_is_positive(a->h_path.dentry)) {
4a4d8108
AM
20275+ d_drop(a->h_path.dentry);
20276+ dput(a->h_path.dentry);
20277+ return;
dece6358
AM
20278+ }
20279+
523b37e3
AM
20280+ delegated = NULL;
20281+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
20282+ &delegated);
20283+ if (unlikely(rerr == -EWOULDBLOCK)) {
20284+ pr_warn("cannot retry for NFSv4 delegation"
20285+ " for an internal rename\n");
20286+ iput(delegated);
20287+ }
4a4d8108
AM
20288+ d_drop(a->h_path.dentry);
20289+ dput(a->h_path.dentry);
20290+ if (!rerr)
20291+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
20292+ else
523b37e3 20293+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 20294+}
1308ab2a 20295+
4a4d8108
AM
20296+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
20297+{
20298+ int rerr;
1308ab2a 20299+
4a4d8108
AM
20300+ a->h_path.dentry = a->src_wh_dentry;
20301+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 20302+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 20303+ if (rerr)
523b37e3 20304+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 20305+}
4a4d8108 20306+#undef RevertFailure
1facf9fc 20307+
1308ab2a 20308+/* ---------------------------------------------------------------------- */
20309+
4a4d8108
AM
20310+/*
20311+ * when we have to copyup the renaming entry, do it with the rename-target name
20312+ * in order to minimize the cost (the later actual rename is unnecessary).
20313+ * otherwise rename it on the target branch.
20314+ */
20315+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 20316+{
dece6358 20317+ int err;
4a4d8108 20318+ struct dentry *d;
523b37e3 20319+ struct inode *delegated;
1facf9fc 20320+
4a4d8108
AM
20321+ d = a->src_dentry;
20322+ if (au_dbstart(d) == a->btgt) {
20323+ a->h_path.dentry = a->dst_h_dentry;
20324+ if (au_ftest_ren(a->flags, DIROPQ)
20325+ && au_dbdiropq(d) == a->btgt)
20326+ au_fclr_ren(a->flags, DIROPQ);
20327+ AuDebugOn(au_dbstart(d) != a->btgt);
523b37e3 20328+ delegated = NULL;
4a4d8108 20329+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
523b37e3
AM
20330+ a->dst_h_dir, &a->h_path, &delegated);
20331+ if (unlikely(err == -EWOULDBLOCK)) {
20332+ pr_warn("cannot retry for NFSv4 delegation"
20333+ " for an internal rename\n");
20334+ iput(delegated);
20335+ }
c2b27bf2 20336+ } else
86dc4139 20337+ BUG();
1308ab2a 20338+
027c5e7a
AM
20339+ if (!err && a->h_dst)
20340+ /* it will be set to dinfo later */
20341+ dget(a->h_dst);
1facf9fc 20342+
dece6358
AM
20343+ return err;
20344+}
1facf9fc 20345+
4a4d8108
AM
20346+/* cf. aufs_rmdir() */
20347+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 20348+{
4a4d8108
AM
20349+ int err;
20350+ struct inode *dir;
1facf9fc 20351+
4a4d8108
AM
20352+ dir = a->dst_dir;
20353+ SiMustAnyLock(dir->i_sb);
20354+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
20355+ au_sbi(dir->i_sb)->si_dirwh)
20356+ || au_test_fs_remote(a->h_dst->d_sb)) {
20357+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
20358+ if (unlikely(err))
523b37e3
AM
20359+ pr_warn("failed removing whtmp dir %pd (%d), "
20360+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
20361+ } else {
20362+ au_nhash_wh_free(&a->thargs->whlist);
20363+ a->thargs->whlist = a->whlist;
20364+ a->whlist.nh_num = 0;
20365+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
20366+ dput(a->h_dst);
20367+ a->thargs = NULL;
20368+ }
20369+
20370+ return 0;
1308ab2a 20371+}
1facf9fc 20372+
4a4d8108
AM
20373+/* make it 'opaque' dir. */
20374+static int au_ren_diropq(struct au_ren_args *a)
20375+{
20376+ int err;
20377+ struct dentry *diropq;
1facf9fc 20378+
4a4d8108 20379+ err = 0;
027c5e7a 20380+ a->src_bdiropq = au_dbdiropq(a->src_dentry);
4a4d8108
AM
20381+ a->src_hinode = au_hi(a->src_inode, a->btgt);
20382+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
20383+ diropq = au_diropq_create(a->src_dentry, a->btgt);
20384+ au_hn_imtx_unlock(a->src_hinode);
20385+ if (IS_ERR(diropq))
20386+ err = PTR_ERR(diropq);
076b876e
AM
20387+ else
20388+ dput(diropq);
1facf9fc 20389+
4a4d8108
AM
20390+ return err;
20391+}
1facf9fc 20392+
4a4d8108
AM
20393+static int do_rename(struct au_ren_args *a)
20394+{
20395+ int err;
20396+ struct dentry *d, *h_d;
1facf9fc 20397+
4a4d8108
AM
20398+ /* prepare workqueue args for asynchronous rmdir */
20399+ h_d = a->dst_h_dentry;
5527c038 20400+ if (au_ftest_ren(a->flags, ISDIR) && d_is_positive(h_d)) {
4a4d8108
AM
20401+ err = -ENOMEM;
20402+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
20403+ if (unlikely(!a->thargs))
20404+ goto out;
20405+ a->h_dst = dget(h_d);
20406+ }
1facf9fc 20407+
4a4d8108
AM
20408+ /* create whiteout for src_dentry */
20409+ if (au_ftest_ren(a->flags, WHSRC)) {
027c5e7a
AM
20410+ a->src_bwh = au_dbwh(a->src_dentry);
20411+ AuDebugOn(a->src_bwh >= 0);
4a4d8108
AM
20412+ a->src_wh_dentry
20413+ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
20414+ err = PTR_ERR(a->src_wh_dentry);
20415+ if (IS_ERR(a->src_wh_dentry))
20416+ goto out_thargs;
20417+ }
1facf9fc 20418+
4a4d8108
AM
20419+ /* lookup whiteout for dentry */
20420+ if (au_ftest_ren(a->flags, WHDST)) {
20421+ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
20422+ a->br);
20423+ err = PTR_ERR(h_d);
20424+ if (IS_ERR(h_d))
20425+ goto out_whsrc;
5527c038 20426+ if (d_is_negative(h_d))
4a4d8108
AM
20427+ dput(h_d);
20428+ else
20429+ a->dst_wh_dentry = h_d;
20430+ }
1facf9fc 20431+
4a4d8108
AM
20432+ /* rename dentry to tmpwh */
20433+ if (a->thargs) {
20434+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
20435+ if (unlikely(err))
20436+ goto out_whdst;
dece6358 20437+
4a4d8108
AM
20438+ d = a->dst_dentry;
20439+ au_set_h_dptr(d, a->btgt, NULL);
86dc4139 20440+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
4a4d8108
AM
20441+ if (unlikely(err))
20442+ goto out_whtmp;
20443+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
20444+ }
1facf9fc 20445+
5527c038 20446+ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_bstart != a->btgt);
1facf9fc 20447+
4a4d8108
AM
20448+ /* rename by vfs_rename or cpup */
20449+ d = a->dst_dentry;
20450+ if (au_ftest_ren(a->flags, ISDIR)
20451+ && (a->dst_wh_dentry
20452+ || au_dbdiropq(d) == a->btgt
20453+ /* hide the lower to keep xino */
20454+ || a->btgt < au_dbend(d)
20455+ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
20456+ au_fset_ren(a->flags, DIROPQ);
20457+ err = au_ren_or_cpup(a);
20458+ if (unlikely(err))
20459+ /* leave the copied-up one */
20460+ goto out_whtmp;
1308ab2a 20461+
4a4d8108
AM
20462+ /* make dir opaque */
20463+ if (au_ftest_ren(a->flags, DIROPQ)) {
20464+ err = au_ren_diropq(a);
20465+ if (unlikely(err))
20466+ goto out_rename;
20467+ }
1308ab2a 20468+
4a4d8108
AM
20469+ /* update target timestamps */
20470+ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
20471+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
20472+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
5527c038 20473+ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime;
1facf9fc 20474+
4a4d8108
AM
20475+ /* remove whiteout for dentry */
20476+ if (a->dst_wh_dentry) {
20477+ a->h_path.dentry = a->dst_wh_dentry;
20478+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
20479+ a->dst_dentry);
20480+ if (unlikely(err))
20481+ goto out_diropq;
20482+ }
1facf9fc 20483+
4a4d8108
AM
20484+ /* remove whtmp */
20485+ if (a->thargs)
20486+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 20487+
076b876e 20488+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
4a4d8108
AM
20489+ err = 0;
20490+ goto out_success;
20491+
4f0767ce 20492+out_diropq:
4a4d8108
AM
20493+ if (au_ftest_ren(a->flags, DIROPQ))
20494+ au_ren_rev_diropq(err, a);
4f0767ce 20495+out_rename:
7e9cd9fe 20496+ au_ren_rev_rename(err, a);
027c5e7a 20497+ dput(a->h_dst);
4f0767ce 20498+out_whtmp:
4a4d8108
AM
20499+ if (a->thargs)
20500+ au_ren_rev_whtmp(err, a);
4f0767ce 20501+out_whdst:
4a4d8108
AM
20502+ dput(a->dst_wh_dentry);
20503+ a->dst_wh_dentry = NULL;
4f0767ce 20504+out_whsrc:
4a4d8108
AM
20505+ if (a->src_wh_dentry)
20506+ au_ren_rev_whsrc(err, a);
4f0767ce 20507+out_success:
4a4d8108
AM
20508+ dput(a->src_wh_dentry);
20509+ dput(a->dst_wh_dentry);
4f0767ce 20510+out_thargs:
4a4d8108
AM
20511+ if (a->thargs) {
20512+ dput(a->h_dst);
20513+ au_whtmp_rmdir_free(a->thargs);
20514+ a->thargs = NULL;
20515+ }
4f0767ce 20516+out:
4a4d8108 20517+ return err;
dece6358 20518+}
1facf9fc 20519+
1308ab2a 20520+/* ---------------------------------------------------------------------- */
1facf9fc 20521+
4a4d8108
AM
20522+/*
20523+ * test if @dentry dir can be rename destination or not.
20524+ * success means, it is a logically empty dir.
20525+ */
20526+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 20527+{
4a4d8108 20528+ return au_test_empty(dentry, whlist);
1308ab2a 20529+}
1facf9fc 20530+
4a4d8108
AM
20531+/*
20532+ * test if @dentry dir can be rename source or not.
20533+ * if it can, return 0 and @children is filled.
20534+ * success means,
20535+ * - it is a logically empty dir.
20536+ * - or, it exists on writable branch and has no children including whiteouts
20537+ * on the lower branch.
20538+ */
20539+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
20540+{
20541+ int err;
20542+ unsigned int rdhash;
20543+ aufs_bindex_t bstart;
1facf9fc 20544+
4a4d8108
AM
20545+ bstart = au_dbstart(dentry);
20546+ if (bstart != btgt) {
20547+ struct au_nhash whlist;
dece6358 20548+
4a4d8108
AM
20549+ SiMustAnyLock(dentry->d_sb);
20550+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
20551+ if (!rdhash)
20552+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
20553+ dentry));
20554+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
20555+ if (unlikely(err))
20556+ goto out;
20557+ err = au_test_empty(dentry, &whlist);
20558+ au_nhash_wh_free(&whlist);
20559+ goto out;
20560+ }
dece6358 20561+
4a4d8108
AM
20562+ if (bstart == au_dbtaildir(dentry))
20563+ return 0; /* success */
dece6358 20564+
4a4d8108 20565+ err = au_test_empty_lower(dentry);
1facf9fc 20566+
4f0767ce 20567+out:
4a4d8108
AM
20568+ if (err == -ENOTEMPTY) {
20569+ AuWarn1("renaming dir who has child(ren) on multiple branches,"
20570+ " is not supported\n");
20571+ err = -EXDEV;
20572+ }
20573+ return err;
20574+}
1308ab2a 20575+
4a4d8108
AM
20576+/* side effect: sets whlist and h_dentry */
20577+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 20578+{
4a4d8108
AM
20579+ int err;
20580+ unsigned int rdhash;
20581+ struct dentry *d;
1facf9fc 20582+
4a4d8108
AM
20583+ d = a->dst_dentry;
20584+ SiMustAnyLock(d->d_sb);
1facf9fc 20585+
4a4d8108
AM
20586+ err = 0;
20587+ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
20588+ rdhash = au_sbi(d->d_sb)->si_rdhash;
20589+ if (!rdhash)
20590+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
20591+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
20592+ if (unlikely(err))
20593+ goto out;
1308ab2a 20594+
4a4d8108
AM
20595+ au_set_dbstart(d, a->dst_bstart);
20596+ err = may_rename_dstdir(d, &a->whlist);
20597+ au_set_dbstart(d, a->btgt);
20598+ }
20599+ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
20600+ if (unlikely(err))
20601+ goto out;
20602+
20603+ d = a->src_dentry;
20604+ a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
20605+ if (au_ftest_ren(a->flags, ISDIR)) {
20606+ err = may_rename_srcdir(d, a->btgt);
20607+ if (unlikely(err)) {
20608+ au_nhash_wh_free(&a->whlist);
20609+ a->whlist.nh_num = 0;
20610+ }
20611+ }
4f0767ce 20612+out:
4a4d8108 20613+ return err;
1facf9fc 20614+}
20615+
4a4d8108 20616+/* ---------------------------------------------------------------------- */
1facf9fc 20617+
4a4d8108
AM
20618+/*
20619+ * simple tests for rename.
20620+ * following the checks in vfs, plus the parent-child relationship.
20621+ */
20622+static int au_may_ren(struct au_ren_args *a)
20623+{
20624+ int err, isdir;
20625+ struct inode *h_inode;
1facf9fc 20626+
4a4d8108
AM
20627+ if (a->src_bstart == a->btgt) {
20628+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
20629+ au_ftest_ren(a->flags, ISDIR));
20630+ if (unlikely(err))
20631+ goto out;
20632+ err = -EINVAL;
20633+ if (unlikely(a->src_h_dentry == a->h_trap))
20634+ goto out;
20635+ }
1facf9fc 20636+
4a4d8108
AM
20637+ err = 0;
20638+ if (a->dst_bstart != a->btgt)
20639+ goto out;
1facf9fc 20640+
027c5e7a
AM
20641+ err = -ENOTEMPTY;
20642+ if (unlikely(a->dst_h_dentry == a->h_trap))
20643+ goto out;
20644+
4a4d8108 20645+ err = -EIO;
4a4d8108 20646+ isdir = !!au_ftest_ren(a->flags, ISDIR);
5527c038
JR
20647+ if (d_really_is_negative(a->dst_dentry)) {
20648+ if (d_is_negative(a->dst_h_dentry))
20649+ err = au_may_add(a->dst_dentry, a->btgt,
20650+ a->dst_h_parent, isdir);
4a4d8108 20651+ } else {
5527c038 20652+ if (unlikely(d_is_negative(a->dst_h_dentry)))
4a4d8108 20653+ goto out;
5527c038
JR
20654+ h_inode = d_inode(a->dst_h_dentry);
20655+ if (h_inode->i_nlink)
20656+ err = au_may_del(a->dst_dentry, a->btgt,
20657+ a->dst_h_parent, isdir);
4a4d8108 20658+ }
1facf9fc 20659+
4f0767ce 20660+out:
4a4d8108
AM
20661+ if (unlikely(err == -ENOENT || err == -EEXIST))
20662+ err = -EIO;
20663+ AuTraceErr(err);
20664+ return err;
20665+}
1facf9fc 20666+
1308ab2a 20667+/* ---------------------------------------------------------------------- */
1facf9fc 20668+
4a4d8108
AM
20669+/*
20670+ * locking order
20671+ * (VFS)
20672+ * - src_dir and dir by lock_rename()
20673+ * - inode if exitsts
20674+ * (aufs)
20675+ * - lock all
20676+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
20677+ * + si_read_lock
20678+ * + di_write_lock2_child()
20679+ * + di_write_lock_child()
20680+ * + ii_write_lock_child()
20681+ * + di_write_lock_child2()
20682+ * + ii_write_lock_child2()
20683+ * + src_parent and parent
20684+ * + di_write_lock_parent()
20685+ * + ii_write_lock_parent()
20686+ * + di_write_lock_parent2()
20687+ * + ii_write_lock_parent2()
20688+ * + lower src_dir and dir by vfsub_lock_rename()
20689+ * + verify the every relationships between child and parent. if any
20690+ * of them failed, unlock all and return -EBUSY.
20691+ */
20692+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 20693+{
4a4d8108
AM
20694+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
20695+ a->dst_h_parent, a->dst_hdir);
86dc4139
AM
20696+ if (au_ftest_ren(a->flags, MNT_WRITE))
20697+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 20698+}
20699+
4a4d8108 20700+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 20701+{
4a4d8108
AM
20702+ int err;
20703+ unsigned int udba;
1308ab2a 20704+
4a4d8108
AM
20705+ err = 0;
20706+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
20707+ a->src_hdir = au_hi(a->src_dir, a->btgt);
20708+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
20709+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
20710+
20711+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
20712+ if (unlikely(err))
20713+ goto out;
20714+ au_fset_ren(a->flags, MNT_WRITE);
4a4d8108
AM
20715+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
20716+ a->dst_h_parent, a->dst_hdir);
20717+ udba = au_opt_udba(a->src_dentry->d_sb);
5527c038
JR
20718+ if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent)
20719+ || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent)))
4a4d8108
AM
20720+ err = au_busy_or_stale();
20721+ if (!err && au_dbstart(a->src_dentry) == a->btgt)
20722+ err = au_h_verify(a->src_h_dentry, udba,
5527c038 20723+ d_inode(a->src_h_parent), a->src_h_parent,
4a4d8108
AM
20724+ a->br);
20725+ if (!err && au_dbstart(a->dst_dentry) == a->btgt)
20726+ err = au_h_verify(a->dst_h_dentry, udba,
5527c038 20727+ d_inode(a->dst_h_parent), a->dst_h_parent,
4a4d8108 20728+ a->br);
86dc4139 20729+ if (!err)
4a4d8108 20730+ goto out; /* success */
4a4d8108
AM
20731+
20732+ err = au_busy_or_stale();
4a4d8108 20733+ au_ren_unlock(a);
86dc4139 20734+
4f0767ce 20735+out:
4a4d8108 20736+ return err;
1facf9fc 20737+}
20738+
20739+/* ---------------------------------------------------------------------- */
20740+
4a4d8108 20741+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 20742+{
4a4d8108 20743+ struct inode *dir;
dece6358 20744+
4a4d8108
AM
20745+ dir = a->dst_dir;
20746+ dir->i_version++;
20747+ if (au_ftest_ren(a->flags, ISDIR)) {
20748+ /* is this updating defined in POSIX? */
20749+ au_cpup_attr_timesizes(a->src_inode);
20750+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 20751+ }
027c5e7a 20752+
b912730e 20753+ au_dir_ts(dir, a->btgt);
dece6358 20754+
4a4d8108
AM
20755+ if (au_ftest_ren(a->flags, ISSAMEDIR))
20756+ return;
dece6358 20757+
4a4d8108
AM
20758+ dir = a->src_dir;
20759+ dir->i_version++;
20760+ if (au_ftest_ren(a->flags, ISDIR))
20761+ au_cpup_attr_nlink(dir, /*force*/1);
b912730e 20762+ au_dir_ts(dir, a->btgt);
1facf9fc 20763+}
20764+
4a4d8108 20765+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 20766+{
4a4d8108
AM
20767+ aufs_bindex_t bend, bindex;
20768+ struct dentry *d, *h_d;
20769+ struct inode *i, *h_i;
20770+ struct super_block *sb;
dece6358 20771+
027c5e7a
AM
20772+ d = a->dst_dentry;
20773+ d_drop(d);
20774+ if (a->h_dst)
20775+ /* already dget-ed by au_ren_or_cpup() */
20776+ au_set_h_dptr(d, a->btgt, a->h_dst);
20777+
20778+ i = a->dst_inode;
20779+ if (i) {
20780+ if (!au_ftest_ren(a->flags, ISDIR))
20781+ vfsub_drop_nlink(i);
20782+ else {
20783+ vfsub_dead_dir(i);
20784+ au_cpup_attr_timesizes(i);
20785+ }
20786+ au_update_dbrange(d, /*do_put_zero*/1);
20787+ } else {
20788+ bend = a->btgt;
20789+ for (bindex = au_dbstart(d); bindex < bend; bindex++)
20790+ au_set_h_dptr(d, bindex, NULL);
20791+ bend = au_dbend(d);
20792+ for (bindex = a->btgt + 1; bindex <= bend; bindex++)
20793+ au_set_h_dptr(d, bindex, NULL);
20794+ au_update_dbrange(d, /*do_put_zero*/0);
20795+ }
20796+
4a4d8108
AM
20797+ d = a->src_dentry;
20798+ au_set_dbwh(d, -1);
20799+ bend = au_dbend(d);
20800+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
20801+ h_d = au_h_dptr(d, bindex);
20802+ if (h_d)
20803+ au_set_h_dptr(d, bindex, NULL);
20804+ }
20805+ au_set_dbend(d, a->btgt);
20806+
20807+ sb = d->d_sb;
20808+ i = a->src_inode;
20809+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
20810+ return; /* success */
20811+
20812+ bend = au_ibend(i);
20813+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
20814+ h_i = au_h_iptr(i, bindex);
20815+ if (h_i) {
20816+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
20817+ /* ignore this error */
20818+ au_set_h_iptr(i, bindex, NULL, 0);
20819+ }
20820+ }
20821+ au_set_ibend(i, a->btgt);
1308ab2a 20822+}
dece6358 20823+
4a4d8108
AM
20824+/* ---------------------------------------------------------------------- */
20825+
20826+/* mainly for link(2) and rename(2) */
20827+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 20828+{
4a4d8108
AM
20829+ aufs_bindex_t bdiropq, bwh;
20830+ struct dentry *parent;
20831+ struct au_branch *br;
20832+
20833+ parent = dentry->d_parent;
5527c038 20834+ IMustLock(d_inode(parent)); /* dir is locked */
4a4d8108
AM
20835+
20836+ bdiropq = au_dbdiropq(parent);
20837+ bwh = au_dbwh(dentry);
20838+ br = au_sbr(dentry->d_sb, btgt);
20839+ if (au_br_rdonly(br)
20840+ || (0 <= bdiropq && bdiropq < btgt)
20841+ || (0 <= bwh && bwh < btgt))
20842+ btgt = -1;
20843+
20844+ AuDbg("btgt %d\n", btgt);
20845+ return btgt;
1facf9fc 20846+}
20847+
4a4d8108
AM
20848+/* sets src_bstart, dst_bstart and btgt */
20849+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 20850+{
4a4d8108
AM
20851+ int err;
20852+ struct au_wr_dir_args wr_dir_args = {
20853+ /* .force_btgt = -1, */
20854+ .flags = AuWrDir_ADD_ENTRY
20855+ };
dece6358 20856+
4a4d8108
AM
20857+ a->src_bstart = au_dbstart(a->src_dentry);
20858+ a->dst_bstart = au_dbstart(a->dst_dentry);
20859+ if (au_ftest_ren(a->flags, ISDIR))
20860+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
20861+ wr_dir_args.force_btgt = a->src_bstart;
20862+ if (a->dst_inode && a->dst_bstart < a->src_bstart)
20863+ wr_dir_args.force_btgt = a->dst_bstart;
20864+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
20865+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
20866+ a->btgt = err;
dece6358 20867+
4a4d8108 20868+ return err;
1facf9fc 20869+}
20870+
4a4d8108 20871+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 20872+{
4a4d8108
AM
20873+ a->h_path.dentry = a->src_h_parent;
20874+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
20875+ if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
20876+ a->h_path.dentry = a->dst_h_parent;
20877+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
20878+ }
1facf9fc 20879+
4a4d8108
AM
20880+ au_fclr_ren(a->flags, DT_DSTDIR);
20881+ if (!au_ftest_ren(a->flags, ISDIR))
20882+ return;
dece6358 20883+
4a4d8108
AM
20884+ a->h_path.dentry = a->src_h_dentry;
20885+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
5527c038 20886+ if (d_is_positive(a->dst_h_dentry)) {
4a4d8108
AM
20887+ au_fset_ren(a->flags, DT_DSTDIR);
20888+ a->h_path.dentry = a->dst_h_dentry;
20889+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
20890+ }
1308ab2a 20891+}
dece6358 20892+
4a4d8108 20893+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 20894+{
4a4d8108
AM
20895+ struct dentry *h_d;
20896+ struct mutex *h_mtx;
20897+
20898+ au_dtime_revert(a->src_dt + AuPARENT);
20899+ if (!au_ftest_ren(a->flags, ISSAMEDIR))
20900+ au_dtime_revert(a->dst_dt + AuPARENT);
20901+
20902+ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
20903+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
5527c038 20904+ h_mtx = &d_inode(h_d)->i_mutex;
4a4d8108
AM
20905+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
20906+ au_dtime_revert(a->src_dt + AuCHILD);
20907+ mutex_unlock(h_mtx);
20908+
20909+ if (au_ftest_ren(a->flags, DT_DSTDIR)) {
20910+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
5527c038 20911+ h_mtx = &d_inode(h_d)->i_mutex;
4a4d8108
AM
20912+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
20913+ au_dtime_revert(a->dst_dt + AuCHILD);
20914+ mutex_unlock(h_mtx);
1facf9fc 20915+ }
20916+ }
20917+}
20918+
4a4d8108
AM
20919+/* ---------------------------------------------------------------------- */
20920+
20921+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
20922+ struct inode *_dst_dir, struct dentry *_dst_dentry)
1facf9fc 20923+{
e49829fe 20924+ int err, flags;
4a4d8108
AM
20925+ /* reduce stack space */
20926+ struct au_ren_args *a;
20927+
523b37e3 20928+ AuDbg("%pd, %pd\n", _src_dentry, _dst_dentry);
4a4d8108
AM
20929+ IMustLock(_src_dir);
20930+ IMustLock(_dst_dir);
20931+
20932+ err = -ENOMEM;
20933+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
20934+ a = kzalloc(sizeof(*a), GFP_NOFS);
20935+ if (unlikely(!a))
20936+ goto out;
20937+
20938+ a->src_dir = _src_dir;
20939+ a->src_dentry = _src_dentry;
5527c038
JR
20940+ a->src_inode = NULL;
20941+ if (d_really_is_positive(a->src_dentry))
20942+ a->src_inode = d_inode(a->src_dentry);
4a4d8108
AM
20943+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
20944+ a->dst_dir = _dst_dir;
20945+ a->dst_dentry = _dst_dentry;
5527c038
JR
20946+ a->dst_inode = NULL;
20947+ if (d_really_is_positive(a->dst_dentry))
20948+ a->dst_inode = d_inode(a->dst_dentry);
4a4d8108
AM
20949+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
20950+ if (a->dst_inode) {
20951+ IMustLock(a->dst_inode);
20952+ au_igrab(a->dst_inode);
1facf9fc 20953+ }
1facf9fc 20954+
4a4d8108 20955+ err = -ENOTDIR;
027c5e7a 20956+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
2000de60 20957+ if (d_is_dir(a->src_dentry)) {
4a4d8108 20958+ au_fset_ren(a->flags, ISDIR);
5527c038 20959+ if (unlikely(d_really_is_positive(a->dst_dentry)
2000de60 20960+ && !d_is_dir(a->dst_dentry)))
4a4d8108 20961+ goto out_free;
e49829fe
JR
20962+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
20963+ AuLock_DIR | flags);
4a4d8108 20964+ } else
e49829fe
JR
20965+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
20966+ flags);
20967+ if (unlikely(err))
20968+ goto out_free;
1facf9fc 20969+
027c5e7a
AM
20970+ err = au_d_hashed_positive(a->src_dentry);
20971+ if (unlikely(err))
20972+ goto out_unlock;
20973+ err = -ENOENT;
20974+ if (a->dst_inode) {
20975+ /*
20976+ * If it is a dir, VFS unhash dst_dentry before this
20977+ * function. It means we cannot rely upon d_unhashed().
20978+ */
20979+ if (unlikely(!a->dst_inode->i_nlink))
20980+ goto out_unlock;
20981+ if (!S_ISDIR(a->dst_inode->i_mode)) {
20982+ err = au_d_hashed_positive(a->dst_dentry);
20983+ if (unlikely(err))
20984+ goto out_unlock;
20985+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
20986+ goto out_unlock;
20987+ } else if (unlikely(d_unhashed(a->dst_dentry)))
20988+ goto out_unlock;
20989+
7eafdf33
AM
20990+ /*
20991+ * is it possible?
79b8bda9 20992+ * yes, it happened (in linux-3.3-rcN) but I don't know why.
7eafdf33
AM
20993+ * there may exist a problem somewhere else.
20994+ */
20995+ err = -EINVAL;
5527c038 20996+ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry)))
7eafdf33
AM
20997+ goto out_unlock;
20998+
4a4d8108
AM
20999+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
21000+ di_write_lock_parent(a->dst_parent);
1facf9fc 21001+
4a4d8108
AM
21002+ /* which branch we process */
21003+ err = au_ren_wbr(a);
21004+ if (unlikely(err < 0))
027c5e7a 21005+ goto out_parent;
4a4d8108 21006+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 21007+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 21008+
4a4d8108
AM
21009+ /* are they available to be renamed */
21010+ err = au_ren_may_dir(a);
21011+ if (unlikely(err))
21012+ goto out_children;
1facf9fc 21013+
4a4d8108
AM
21014+ /* prepare the writable parent dir on the same branch */
21015+ if (a->dst_bstart == a->btgt) {
21016+ au_fset_ren(a->flags, WHDST);
21017+ } else {
21018+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
21019+ if (unlikely(err))
21020+ goto out_children;
21021+ }
1facf9fc 21022+
4a4d8108
AM
21023+ if (a->src_dir != a->dst_dir) {
21024+ /*
21025+ * this temporary unlock is safe,
21026+ * because both dir->i_mutex are locked.
21027+ */
21028+ di_write_unlock(a->dst_parent);
21029+ di_write_lock_parent(a->src_parent);
21030+ err = au_wr_dir_need_wh(a->src_dentry,
21031+ au_ftest_ren(a->flags, ISDIR),
21032+ &a->btgt);
21033+ di_write_unlock(a->src_parent);
21034+ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
21035+ au_fclr_ren(a->flags, ISSAMEDIR);
21036+ } else
21037+ err = au_wr_dir_need_wh(a->src_dentry,
21038+ au_ftest_ren(a->flags, ISDIR),
21039+ &a->btgt);
21040+ if (unlikely(err < 0))
21041+ goto out_children;
21042+ if (err)
21043+ au_fset_ren(a->flags, WHSRC);
1facf9fc 21044+
86dc4139
AM
21045+ /* cpup src */
21046+ if (a->src_bstart != a->btgt) {
86dc4139
AM
21047+ struct au_pin pin;
21048+
21049+ err = au_pin(&pin, a->src_dentry, a->btgt,
21050+ au_opt_udba(a->src_dentry->d_sb),
21051+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 21052+ if (!err) {
c2b27bf2
AM
21053+ struct au_cp_generic cpg = {
21054+ .dentry = a->src_dentry,
21055+ .bdst = a->btgt,
21056+ .bsrc = a->src_bstart,
21057+ .len = -1,
21058+ .pin = &pin,
21059+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21060+ };
367653fa 21061+ AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
c2b27bf2 21062+ err = au_sio_cpup_simple(&cpg);
367653fa 21063+ au_unpin(&pin);
86dc4139 21064+ }
86dc4139
AM
21065+ if (unlikely(err))
21066+ goto out_children;
21067+ a->src_bstart = a->btgt;
21068+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
21069+ au_fset_ren(a->flags, WHSRC);
21070+ }
21071+
4a4d8108
AM
21072+ /* lock them all */
21073+ err = au_ren_lock(a);
21074+ if (unlikely(err))
86dc4139 21075+ /* leave the copied-up one */
4a4d8108 21076+ goto out_children;
1facf9fc 21077+
4a4d8108
AM
21078+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
21079+ err = au_may_ren(a);
21080+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
21081+ err = -ENAMETOOLONG;
21082+ if (unlikely(err))
21083+ goto out_hdir;
1facf9fc 21084+
4a4d8108
AM
21085+ /* store timestamps to be revertible */
21086+ au_ren_dt(a);
1facf9fc 21087+
4a4d8108
AM
21088+ /* here we go */
21089+ err = do_rename(a);
21090+ if (unlikely(err))
21091+ goto out_dt;
21092+
21093+ /* update dir attributes */
21094+ au_ren_refresh_dir(a);
21095+
21096+ /* dput/iput all lower dentries */
21097+ au_ren_refresh(a);
21098+
21099+ goto out_hdir; /* success */
21100+
4f0767ce 21101+out_dt:
4a4d8108 21102+ au_ren_rev_dt(err, a);
4f0767ce 21103+out_hdir:
4a4d8108 21104+ au_ren_unlock(a);
4f0767ce 21105+out_children:
4a4d8108 21106+ au_nhash_wh_free(&a->whlist);
027c5e7a
AM
21107+ if (err && a->dst_inode && a->dst_bstart != a->btgt) {
21108+ AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
21109+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
21110+ au_set_dbstart(a->dst_dentry, a->dst_bstart);
4a4d8108 21111+ }
027c5e7a 21112+out_parent:
4a4d8108
AM
21113+ if (!err)
21114+ d_move(a->src_dentry, a->dst_dentry);
027c5e7a
AM
21115+ else {
21116+ au_update_dbstart(a->dst_dentry);
21117+ if (!a->dst_inode)
21118+ d_drop(a->dst_dentry);
21119+ }
4a4d8108
AM
21120+ if (au_ftest_ren(a->flags, ISSAMEDIR))
21121+ di_write_unlock(a->dst_parent);
21122+ else
21123+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 21124+out_unlock:
4a4d8108 21125+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 21126+out_free:
4a4d8108
AM
21127+ iput(a->dst_inode);
21128+ if (a->thargs)
21129+ au_whtmp_rmdir_free(a->thargs);
21130+ kfree(a);
4f0767ce 21131+out:
4a4d8108
AM
21132+ AuTraceErr(err);
21133+ return err;
1308ab2a 21134+}
7f207e10
AM
21135diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
21136--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 21137+++ linux/fs/aufs/Kconfig 2015-09-24 10:47:58.248052907 +0200
c1595e42 21138@@ -0,0 +1,185 @@
4a4d8108
AM
21139+config AUFS_FS
21140+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
21141+ help
21142+ Aufs is a stackable unification filesystem such as Unionfs,
21143+ which unifies several directories and provides a merged single
21144+ directory.
21145+ In the early days, aufs was entirely re-designed and
21146+ re-implemented Unionfs Version 1.x series. Introducing many
21147+ original ideas, approaches and improvements, it becomes totally
21148+ different from Unionfs while keeping the basic features.
1facf9fc 21149+
4a4d8108
AM
21150+if AUFS_FS
21151+choice
21152+ prompt "Maximum number of branches"
21153+ default AUFS_BRANCH_MAX_127
21154+ help
21155+ Specifies the maximum number of branches (or member directories)
21156+ in a single aufs. The larger value consumes more system
21157+ resources and has a minor impact to performance.
21158+config AUFS_BRANCH_MAX_127
21159+ bool "127"
21160+ help
21161+ Specifies the maximum number of branches (or member directories)
21162+ in a single aufs. The larger value consumes more system
21163+ resources and has a minor impact to performance.
21164+config AUFS_BRANCH_MAX_511
21165+ bool "511"
21166+ help
21167+ Specifies the maximum number of branches (or member directories)
21168+ in a single aufs. The larger value consumes more system
21169+ resources and has a minor impact to performance.
21170+config AUFS_BRANCH_MAX_1023
21171+ bool "1023"
21172+ help
21173+ Specifies the maximum number of branches (or member directories)
21174+ in a single aufs. The larger value consumes more system
21175+ resources and has a minor impact to performance.
21176+config AUFS_BRANCH_MAX_32767
21177+ bool "32767"
21178+ help
21179+ Specifies the maximum number of branches (or member directories)
21180+ in a single aufs. The larger value consumes more system
21181+ resources and has a minor impact to performance.
21182+endchoice
1facf9fc 21183+
e49829fe
JR
21184+config AUFS_SBILIST
21185+ bool
21186+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
21187+ default y
21188+ help
21189+ Automatic configuration for internal use.
21190+ When aufs supports Magic SysRq or /proc, enabled automatically.
21191+
4a4d8108
AM
21192+config AUFS_HNOTIFY
21193+ bool "Detect direct branch access (bypassing aufs)"
21194+ help
21195+ If you want to modify files on branches directly, eg. bypassing aufs,
21196+ and want aufs to detect the changes of them fully, then enable this
21197+ option and use 'udba=notify' mount option.
7f207e10 21198+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
21199+ It will have a negative impact to the performance.
21200+ See detail in aufs.5.
dece6358 21201+
4a4d8108
AM
21202+choice
21203+ prompt "method" if AUFS_HNOTIFY
21204+ default AUFS_HFSNOTIFY
21205+config AUFS_HFSNOTIFY
21206+ bool "fsnotify"
21207+ select FSNOTIFY
4a4d8108 21208+endchoice
1facf9fc 21209+
4a4d8108
AM
21210+config AUFS_EXPORT
21211+ bool "NFS-exportable aufs"
2cbb1c4b 21212+ depends on EXPORTFS
4a4d8108
AM
21213+ help
21214+ If you want to export your mounted aufs via NFS, then enable this
21215+ option. There are several requirements for this configuration.
21216+ See detail in aufs.5.
1facf9fc 21217+
4a4d8108
AM
21218+config AUFS_INO_T_64
21219+ bool
21220+ depends on AUFS_EXPORT
21221+ depends on 64BIT && !(ALPHA || S390)
21222+ default y
21223+ help
21224+ Automatic configuration for internal use.
21225+ /* typedef unsigned long/int __kernel_ino_t */
21226+ /* alpha and s390x are int */
1facf9fc 21227+
c1595e42
JR
21228+config AUFS_XATTR
21229+ bool "support for XATTR/EA (including Security Labels)"
21230+ help
21231+ If your branch fs supports XATTR/EA and you want to make them
21232+ available in aufs too, then enable this opsion and specify the
21233+ branch attributes for EA.
21234+ See detail in aufs.5.
21235+
076b876e
AM
21236+config AUFS_FHSM
21237+ bool "File-based Hierarchical Storage Management"
21238+ help
21239+ Hierarchical Storage Management (or HSM) is a well-known feature
21240+ in the storage world. Aufs provides this feature as file-based.
21241+ with multiple branches.
21242+ These multiple branches are prioritized, ie. the topmost one
21243+ should be the fastest drive and be used heavily.
21244+
4a4d8108
AM
21245+config AUFS_RDU
21246+ bool "Readdir in userspace"
21247+ help
21248+ Aufs has two methods to provide a merged view for a directory,
21249+ by a user-space library and by kernel-space natively. The latter
21250+ is always enabled but sometimes large and slow.
21251+ If you enable this option, install the library in aufs2-util
21252+ package, and set some environment variables for your readdir(3),
21253+ then the work will be handled in user-space which generally
21254+ shows better performance in most cases.
21255+ See detail in aufs.5.
1facf9fc 21256+
4a4d8108
AM
21257+config AUFS_SHWH
21258+ bool "Show whiteouts"
21259+ help
21260+ If you want to make the whiteouts in aufs visible, then enable
21261+ this option and specify 'shwh' mount option. Although it may
21262+ sounds like philosophy or something, but in technically it
21263+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 21264+
4a4d8108
AM
21265+config AUFS_BR_RAMFS
21266+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
21267+ help
21268+ If you want to use ramfs as an aufs branch fs, then enable this
21269+ option. Generally tmpfs is recommended.
21270+ Aufs prohibited them to be a branch fs by default, because
21271+ initramfs becomes unusable after switch_root or something
21272+ generally. If you sets initramfs as an aufs branch and boot your
21273+ system by switch_root, you will meet a problem easily since the
21274+ files in initramfs may be inaccessible.
21275+ Unless you are going to use ramfs as an aufs branch fs without
21276+ switch_root or something, leave it N.
1facf9fc 21277+
4a4d8108
AM
21278+config AUFS_BR_FUSE
21279+ bool "Fuse fs as an aufs branch"
21280+ depends on FUSE_FS
21281+ select AUFS_POLL
21282+ help
21283+ If you want to use fuse-based userspace filesystem as an aufs
21284+ branch fs, then enable this option.
21285+ It implements the internal poll(2) operation which is
21286+ implemented by fuse only (curretnly).
1facf9fc 21287+
4a4d8108
AM
21288+config AUFS_POLL
21289+ bool
21290+ help
21291+ Automatic configuration for internal use.
1facf9fc 21292+
4a4d8108
AM
21293+config AUFS_BR_HFSPLUS
21294+ bool "Hfsplus as an aufs branch"
21295+ depends on HFSPLUS_FS
21296+ default y
21297+ help
21298+ If you want to use hfsplus fs as an aufs branch fs, then enable
21299+ this option. This option introduces a small overhead at
21300+ copying-up a file on hfsplus.
1facf9fc 21301+
4a4d8108
AM
21302+config AUFS_BDEV_LOOP
21303+ bool
21304+ depends on BLK_DEV_LOOP
21305+ default y
21306+ help
21307+ Automatic configuration for internal use.
21308+ Convert =[ym] into =y.
1308ab2a 21309+
4a4d8108
AM
21310+config AUFS_DEBUG
21311+ bool "Debug aufs"
21312+ help
21313+ Enable this to compile aufs internal debug code.
21314+ It will have a negative impact to the performance.
21315+
21316+config AUFS_MAGIC_SYSRQ
21317+ bool
21318+ depends on AUFS_DEBUG && MAGIC_SYSRQ
21319+ default y
21320+ help
21321+ Automatic configuration for internal use.
21322+ When aufs supports Magic SysRq, enabled automatically.
21323+endif
7f207e10
AM
21324diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
21325--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
21326+++ linux/fs/aufs/loop.c 2015-11-11 17:21:46.918863802 +0100
21327@@ -0,0 +1,146 @@
1facf9fc 21328+/*
2000de60 21329+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 21330+ *
21331+ * This program, aufs is free software; you can redistribute it and/or modify
21332+ * it under the terms of the GNU General Public License as published by
21333+ * the Free Software Foundation; either version 2 of the License, or
21334+ * (at your option) any later version.
dece6358
AM
21335+ *
21336+ * This program is distributed in the hope that it will be useful,
21337+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21338+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21339+ * GNU General Public License for more details.
21340+ *
21341+ * You should have received a copy of the GNU General Public License
523b37e3 21342+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21343+ */
21344+
21345+/*
21346+ * support for loopback block device as a branch
21347+ */
21348+
1facf9fc 21349+#include "aufs.h"
21350+
392086de
AM
21351+/* added into drivers/block/loop.c */
21352+static struct file *(*backing_file_func)(struct super_block *sb);
21353+
1facf9fc 21354+/*
21355+ * test if two lower dentries have overlapping branches.
21356+ */
b752ccd1 21357+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 21358+{
b752ccd1 21359+ struct super_block *h_sb;
392086de
AM
21360+ struct file *backing_file;
21361+
21362+ if (unlikely(!backing_file_func)) {
21363+ /* don't load "loop" module here */
21364+ backing_file_func = symbol_get(loop_backing_file);
21365+ if (unlikely(!backing_file_func))
21366+ /* "loop" module is not loaded */
21367+ return 0;
21368+ }
1facf9fc 21369+
b752ccd1 21370+ h_sb = h_adding->d_sb;
392086de
AM
21371+ backing_file = backing_file_func(h_sb);
21372+ if (!backing_file)
1facf9fc 21373+ return 0;
21374+
2000de60 21375+ h_adding = backing_file->f_path.dentry;
b752ccd1
AM
21376+ /*
21377+ * h_adding can be local NFS.
21378+ * in this case aufs cannot detect the loop.
21379+ */
21380+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 21381+ return 1;
b752ccd1 21382+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 21383+}
21384+
21385+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
21386+int au_test_loopback_kthread(void)
21387+{
b752ccd1
AM
21388+ int ret;
21389+ struct task_struct *tsk = current;
a2a7ad62 21390+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
21391+
21392+ ret = 0;
21393+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
21394+ get_task_comm(comm, tsk);
21395+ c = comm[4];
b752ccd1 21396+ ret = ('0' <= c && c <= '9'
a2a7ad62 21397+ && !strncmp(comm, "loop", 4));
b752ccd1 21398+ }
1facf9fc 21399+
b752ccd1 21400+ return ret;
1facf9fc 21401+}
87a755f4
AM
21402+
21403+/* ---------------------------------------------------------------------- */
21404+
21405+#define au_warn_loopback_step 16
21406+static int au_warn_loopback_nelem = au_warn_loopback_step;
21407+static unsigned long *au_warn_loopback_array;
21408+
21409+void au_warn_loopback(struct super_block *h_sb)
21410+{
21411+ int i, new_nelem;
21412+ unsigned long *a, magic;
21413+ static DEFINE_SPINLOCK(spin);
21414+
21415+ magic = h_sb->s_magic;
21416+ spin_lock(&spin);
21417+ a = au_warn_loopback_array;
21418+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
21419+ if (a[i] == magic) {
21420+ spin_unlock(&spin);
21421+ return;
21422+ }
21423+
21424+ /* h_sb is new to us, print it */
21425+ if (i < au_warn_loopback_nelem) {
21426+ a[i] = magic;
21427+ goto pr;
21428+ }
21429+
21430+ /* expand the array */
21431+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
21432+ a = au_kzrealloc(au_warn_loopback_array,
21433+ au_warn_loopback_nelem * sizeof(unsigned long),
21434+ new_nelem * sizeof(unsigned long), GFP_ATOMIC);
21435+ if (a) {
21436+ au_warn_loopback_nelem = new_nelem;
21437+ au_warn_loopback_array = a;
21438+ a[i] = magic;
21439+ goto pr;
21440+ }
21441+
21442+ spin_unlock(&spin);
21443+ AuWarn1("realloc failed, ignored\n");
21444+ return;
21445+
21446+pr:
21447+ spin_unlock(&spin);
0c3ec466
AM
21448+ pr_warn("you may want to try another patch for loopback file "
21449+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
21450+}
21451+
21452+int au_loopback_init(void)
21453+{
21454+ int err;
21455+ struct super_block *sb __maybe_unused;
21456+
79b8bda9 21457+ BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(unsigned long));
87a755f4
AM
21458+
21459+ err = 0;
21460+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
21461+ sizeof(unsigned long), GFP_NOFS);
21462+ if (unlikely(!au_warn_loopback_array))
21463+ err = -ENOMEM;
21464+
21465+ return err;
21466+}
21467+
21468+void au_loopback_fin(void)
21469+{
79b8bda9
AM
21470+ if (backing_file_func)
21471+ symbol_put(loop_backing_file);
87a755f4
AM
21472+ kfree(au_warn_loopback_array);
21473+}
7f207e10
AM
21474diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
21475--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 21476+++ linux/fs/aufs/loop.h 2015-09-24 10:47:58.254719746 +0200
523b37e3 21477@@ -0,0 +1,52 @@
1facf9fc 21478+/*
2000de60 21479+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 21480+ *
21481+ * This program, aufs is free software; you can redistribute it and/or modify
21482+ * it under the terms of the GNU General Public License as published by
21483+ * the Free Software Foundation; either version 2 of the License, or
21484+ * (at your option) any later version.
dece6358
AM
21485+ *
21486+ * This program is distributed in the hope that it will be useful,
21487+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21488+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21489+ * GNU General Public License for more details.
21490+ *
21491+ * You should have received a copy of the GNU General Public License
523b37e3 21492+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21493+ */
21494+
21495+/*
21496+ * support for loopback mount as a branch
21497+ */
21498+
21499+#ifndef __AUFS_LOOP_H__
21500+#define __AUFS_LOOP_H__
21501+
21502+#ifdef __KERNEL__
21503+
dece6358
AM
21504+struct dentry;
21505+struct super_block;
1facf9fc 21506+
21507+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
21508+/* drivers/block/loop.c */
21509+struct file *loop_backing_file(struct super_block *sb);
21510+
1facf9fc 21511+/* loop.c */
b752ccd1 21512+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 21513+int au_test_loopback_kthread(void);
87a755f4
AM
21514+void au_warn_loopback(struct super_block *h_sb);
21515+
21516+int au_loopback_init(void);
21517+void au_loopback_fin(void);
1facf9fc 21518+#else
4a4d8108 21519+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 21520+ struct dentry *h_adding)
4a4d8108 21521+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
21522+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
21523+
21524+AuStubInt0(au_loopback_init, void)
21525+AuStubVoid(au_loopback_fin, void)
1facf9fc 21526+#endif /* BLK_DEV_LOOP */
21527+
21528+#endif /* __KERNEL__ */
21529+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
21530diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
21531--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 21532+++ linux/fs/aufs/magic.mk 2015-09-24 10:47:58.254719746 +0200
7e9cd9fe 21533@@ -0,0 +1,30 @@
1facf9fc 21534+
21535+# defined in ${srctree}/fs/fuse/inode.c
21536+# tristate
21537+ifdef CONFIG_FUSE_FS
21538+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
21539+endif
21540+
1facf9fc 21541+# defined in ${srctree}/fs/xfs/xfs_sb.h
21542+# tristate
21543+ifdef CONFIG_XFS_FS
21544+ccflags-y += -DXFS_SB_MAGIC=0x58465342
21545+endif
21546+
21547+# defined in ${srctree}/fs/configfs/mount.c
21548+# tristate
21549+ifdef CONFIG_CONFIGFS_FS
21550+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
21551+endif
21552+
1facf9fc 21553+# defined in ${srctree}/fs/ubifs/ubifs.h
21554+# tristate
21555+ifdef CONFIG_UBIFS_FS
21556+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
21557+endif
4a4d8108
AM
21558+
21559+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
21560+# tristate
21561+ifdef CONFIG_HFSPLUS_FS
21562+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
21563+endif
7f207e10
AM
21564diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
21565--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 21566+++ linux/fs/aufs/Makefile 2015-09-24 10:47:58.248052907 +0200
c1595e42 21567@@ -0,0 +1,44 @@
4a4d8108
AM
21568+
21569+include ${src}/magic.mk
21570+ifeq (${CONFIG_AUFS_FS},m)
21571+include ${src}/conf.mk
21572+endif
21573+-include ${src}/priv_def.mk
21574+
21575+# cf. include/linux/kernel.h
21576+# enable pr_debug
21577+ccflags-y += -DDEBUG
f6c5ef8b
AM
21578+# sparse requires the full pathname
21579+ifdef M
523b37e3 21580+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 21581+else
523b37e3 21582+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 21583+endif
4a4d8108
AM
21584+
21585+obj-$(CONFIG_AUFS_FS) += aufs.o
21586+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
21587+ wkq.o vfsub.o dcsub.o \
e49829fe 21588+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
21589+ dinfo.o dentry.o \
21590+ dynop.o \
21591+ finfo.o file.o f_op.o \
21592+ dir.o vdir.o \
21593+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 21594+ mvdown.o ioctl.o
4a4d8108
AM
21595+
21596+# all are boolean
e49829fe 21597+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
21598+aufs-$(CONFIG_SYSFS) += sysfs.o
21599+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
21600+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
21601+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
21602+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108 21603+aufs-$(CONFIG_AUFS_EXPORT) += export.o
c1595e42
JR
21604+aufs-$(CONFIG_AUFS_XATTR) += xattr.o
21605+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
076b876e 21606+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
4a4d8108
AM
21607+aufs-$(CONFIG_AUFS_POLL) += poll.o
21608+aufs-$(CONFIG_AUFS_RDU) += rdu.o
4a4d8108
AM
21609+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
21610+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
21611+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
21612diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
21613--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
21614+++ linux/fs/aufs/module.c 2015-11-11 17:21:46.918863802 +0100
21615@@ -0,0 +1,217 @@
1facf9fc 21616+/*
2000de60 21617+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 21618+ *
21619+ * This program, aufs is free software; you can redistribute it and/or modify
21620+ * it under the terms of the GNU General Public License as published by
21621+ * the Free Software Foundation; either version 2 of the License, or
21622+ * (at your option) any later version.
dece6358
AM
21623+ *
21624+ * This program is distributed in the hope that it will be useful,
21625+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21626+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21627+ * GNU General Public License for more details.
21628+ *
21629+ * You should have received a copy of the GNU General Public License
523b37e3 21630+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21631+ */
21632+
21633+/*
21634+ * module global variables and operations
21635+ */
21636+
21637+#include <linux/module.h>
21638+#include <linux/seq_file.h>
21639+#include "aufs.h"
21640+
21641+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
21642+{
21643+ if (new_sz <= nused)
21644+ return p;
21645+
21646+ p = krealloc(p, new_sz, gfp);
21647+ if (p)
21648+ memset(p + nused, 0, new_sz - nused);
21649+ return p;
21650+}
21651+
21652+/* ---------------------------------------------------------------------- */
21653+
21654+/*
21655+ * aufs caches
21656+ */
21657+struct kmem_cache *au_cachep[AuCache_Last];
21658+static int __init au_cache_init(void)
21659+{
4a4d8108 21660+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
1facf9fc 21661+ if (au_cachep[AuCache_DINFO])
027c5e7a 21662+ /* SLAB_DESTROY_BY_RCU */
4a4d8108
AM
21663+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
21664+ au_icntnr_init_once);
1facf9fc 21665+ if (au_cachep[AuCache_ICNTNR])
4a4d8108
AM
21666+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
21667+ au_fi_init_once);
1facf9fc 21668+ if (au_cachep[AuCache_FINFO])
21669+ au_cachep[AuCache_VDIR] = AuCache(au_vdir);
21670+ if (au_cachep[AuCache_VDIR])
21671+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
21672+ if (au_cachep[AuCache_DEHSTR])
21673+ return 0;
21674+
21675+ return -ENOMEM;
21676+}
21677+
21678+static void au_cache_fin(void)
21679+{
21680+ int i;
4a4d8108 21681+
537831f9
AM
21682+ /*
21683+ * Make sure all delayed rcu free inodes are flushed before we
21684+ * destroy cache.
21685+ */
21686+ rcu_barrier();
21687+
7eafdf33
AM
21688+ /* excluding AuCache_HNOTIFY */
21689+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
79b8bda9
AM
21690+ for (i = 0; i < AuCache_HNOTIFY; i++) {
21691+ kmem_cache_destroy(au_cachep[i]);
21692+ au_cachep[i] = NULL;
21693+ }
1facf9fc 21694+}
21695+
21696+/* ---------------------------------------------------------------------- */
21697+
21698+int au_dir_roflags;
21699+
e49829fe 21700+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
21701+/*
21702+ * iterate_supers_type() doesn't protect us from
21703+ * remounting (branch management)
21704+ */
e49829fe
JR
21705+struct au_splhead au_sbilist;
21706+#endif
21707+
9dbd164d
AM
21708+struct lock_class_key au_lc_key[AuLcKey_Last];
21709+
1facf9fc 21710+/*
21711+ * functions for module interface.
21712+ */
21713+MODULE_LICENSE("GPL");
21714+/* MODULE_LICENSE("GPL v2"); */
dece6358 21715+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 21716+MODULE_DESCRIPTION(AUFS_NAME
21717+ " -- Advanced multi layered unification filesystem");
21718+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 21719+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 21720+
1facf9fc 21721+/* this module parameter has no meaning when SYSFS is disabled */
21722+int sysaufs_brs = 1;
21723+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
21724+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
21725+
076b876e
AM
21726+/* this module parameter has no meaning when USER_NS is disabled */
21727+static bool au_userns;
21728+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
21729+module_param_named(allow_userns, au_userns, bool, S_IRUGO);
21730+
1facf9fc 21731+/* ---------------------------------------------------------------------- */
21732+
21733+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
21734+
21735+int au_seq_path(struct seq_file *seq, struct path *path)
21736+{
79b8bda9
AM
21737+ int err;
21738+
21739+ err = seq_path(seq, path, au_esc_chars);
21740+ if (err > 0)
21741+ err = 0;
21742+ else if (err < 0)
21743+ err = -ENOMEM;
21744+
21745+ return err;
1facf9fc 21746+}
21747+
21748+/* ---------------------------------------------------------------------- */
21749+
21750+static int __init aufs_init(void)
21751+{
21752+ int err, i;
21753+ char *p;
21754+
21755+ p = au_esc_chars;
21756+ for (i = 1; i <= ' '; i++)
21757+ *p++ = i;
21758+ *p++ = '\\';
21759+ *p++ = '\x7f';
21760+ *p = 0;
21761+
21762+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
21763+
e49829fe 21764+ au_sbilist_init();
1facf9fc 21765+ sysaufs_brs_init();
21766+ au_debug_init();
4a4d8108 21767+ au_dy_init();
1facf9fc 21768+ err = sysaufs_init();
21769+ if (unlikely(err))
21770+ goto out;
e49829fe 21771+ err = au_procfs_init();
4f0767ce 21772+ if (unlikely(err))
953406b4 21773+ goto out_sysaufs;
e49829fe
JR
21774+ err = au_wkq_init();
21775+ if (unlikely(err))
21776+ goto out_procfs;
87a755f4 21777+ err = au_loopback_init();
1facf9fc 21778+ if (unlikely(err))
21779+ goto out_wkq;
87a755f4
AM
21780+ err = au_hnotify_init();
21781+ if (unlikely(err))
21782+ goto out_loopback;
1facf9fc 21783+ err = au_sysrq_init();
21784+ if (unlikely(err))
21785+ goto out_hin;
21786+ err = au_cache_init();
21787+ if (unlikely(err))
21788+ goto out_sysrq;
076b876e
AM
21789+
21790+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
1facf9fc 21791+ err = register_filesystem(&aufs_fs_type);
21792+ if (unlikely(err))
21793+ goto out_cache;
076b876e 21794+
4a4d8108
AM
21795+ /* since we define pr_fmt, call printk directly */
21796+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 21797+ goto out; /* success */
21798+
4f0767ce 21799+out_cache:
1facf9fc 21800+ au_cache_fin();
4f0767ce 21801+out_sysrq:
1facf9fc 21802+ au_sysrq_fin();
4f0767ce 21803+out_hin:
4a4d8108 21804+ au_hnotify_fin();
87a755f4
AM
21805+out_loopback:
21806+ au_loopback_fin();
4f0767ce 21807+out_wkq:
1facf9fc 21808+ au_wkq_fin();
e49829fe
JR
21809+out_procfs:
21810+ au_procfs_fin();
4f0767ce 21811+out_sysaufs:
1facf9fc 21812+ sysaufs_fin();
4a4d8108 21813+ au_dy_fin();
4f0767ce 21814+out:
1facf9fc 21815+ return err;
21816+}
21817+
21818+static void __exit aufs_exit(void)
21819+{
21820+ unregister_filesystem(&aufs_fs_type);
21821+ au_cache_fin();
21822+ au_sysrq_fin();
4a4d8108 21823+ au_hnotify_fin();
87a755f4 21824+ au_loopback_fin();
1facf9fc 21825+ au_wkq_fin();
e49829fe 21826+ au_procfs_fin();
1facf9fc 21827+ sysaufs_fin();
4a4d8108 21828+ au_dy_fin();
1facf9fc 21829+}
21830+
21831+module_init(aufs_init);
21832+module_exit(aufs_exit);
7f207e10
AM
21833diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
21834--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 21835+++ linux/fs/aufs/module.h 2015-09-24 10:47:58.254719746 +0200
523b37e3 21836@@ -0,0 +1,104 @@
1facf9fc 21837+/*
2000de60 21838+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 21839+ *
21840+ * This program, aufs is free software; you can redistribute it and/or modify
21841+ * it under the terms of the GNU General Public License as published by
21842+ * the Free Software Foundation; either version 2 of the License, or
21843+ * (at your option) any later version.
dece6358
AM
21844+ *
21845+ * This program is distributed in the hope that it will be useful,
21846+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21847+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21848+ * GNU General Public License for more details.
21849+ *
21850+ * You should have received a copy of the GNU General Public License
523b37e3 21851+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21852+ */
21853+
21854+/*
21855+ * module initialization and module-global
21856+ */
21857+
21858+#ifndef __AUFS_MODULE_H__
21859+#define __AUFS_MODULE_H__
21860+
21861+#ifdef __KERNEL__
21862+
21863+#include <linux/slab.h>
21864+
dece6358
AM
21865+struct path;
21866+struct seq_file;
21867+
1facf9fc 21868+/* module parameters */
1facf9fc 21869+extern int sysaufs_brs;
21870+
21871+/* ---------------------------------------------------------------------- */
21872+
21873+extern int au_dir_roflags;
21874+
9dbd164d
AM
21875+enum {
21876+ AuLcNonDir_FIINFO,
21877+ AuLcNonDir_DIINFO,
21878+ AuLcNonDir_IIINFO,
21879+
21880+ AuLcDir_FIINFO,
21881+ AuLcDir_DIINFO,
21882+ AuLcDir_IIINFO,
21883+
21884+ AuLcSymlink_DIINFO,
21885+ AuLcSymlink_IIINFO,
21886+
21887+ AuLcKey_Last
21888+};
21889+extern struct lock_class_key au_lc_key[AuLcKey_Last];
21890+
1facf9fc 21891+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
21892+int au_seq_path(struct seq_file *seq, struct path *path);
21893+
e49829fe
JR
21894+#ifdef CONFIG_PROC_FS
21895+/* procfs.c */
21896+int __init au_procfs_init(void);
21897+void au_procfs_fin(void);
21898+#else
21899+AuStubInt0(au_procfs_init, void);
21900+AuStubVoid(au_procfs_fin, void);
21901+#endif
21902+
4f0767ce
JR
21903+/* ---------------------------------------------------------------------- */
21904+
21905+/* kmem cache */
1facf9fc 21906+enum {
21907+ AuCache_DINFO,
21908+ AuCache_ICNTNR,
21909+ AuCache_FINFO,
21910+ AuCache_VDIR,
21911+ AuCache_DEHSTR,
7eafdf33 21912+ AuCache_HNOTIFY, /* must be last */
1facf9fc 21913+ AuCache_Last
21914+};
21915+
4a4d8108
AM
21916+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
21917+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
21918+#define AuCacheCtor(type, ctor) \
21919+ kmem_cache_create(#type, sizeof(struct type), \
21920+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 21921+
21922+extern struct kmem_cache *au_cachep[];
21923+
21924+#define AuCacheFuncs(name, index) \
4a4d8108 21925+static inline struct au_##name *au_cache_alloc_##name(void) \
1facf9fc 21926+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
4a4d8108 21927+static inline void au_cache_free_##name(struct au_##name *p) \
1facf9fc 21928+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
21929+
21930+AuCacheFuncs(dinfo, DINFO);
21931+AuCacheFuncs(icntnr, ICNTNR);
21932+AuCacheFuncs(finfo, FINFO);
21933+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
21934+AuCacheFuncs(vdir_dehstr, DEHSTR);
21935+#ifdef CONFIG_AUFS_HNOTIFY
21936+AuCacheFuncs(hnotify, HNOTIFY);
21937+#endif
1facf9fc 21938+
4a4d8108
AM
21939+#endif /* __KERNEL__ */
21940+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
21941diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
21942--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
21943+++ linux/fs/aufs/mvdown.c 2015-11-11 17:21:46.918863802 +0100
21944@@ -0,0 +1,703 @@
c2b27bf2 21945+/*
2000de60 21946+ * Copyright (C) 2011-2015 Junjiro R. Okajima
c2b27bf2
AM
21947+ *
21948+ * This program, aufs is free software; you can redistribute it and/or modify
21949+ * it under the terms of the GNU General Public License as published by
21950+ * the Free Software Foundation; either version 2 of the License, or
21951+ * (at your option) any later version.
21952+ *
21953+ * This program is distributed in the hope that it will be useful,
21954+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21955+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21956+ * GNU General Public License for more details.
21957+ *
21958+ * You should have received a copy of the GNU General Public License
523b37e3
AM
21959+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
21960+ */
21961+
21962+/*
21963+ * move-down, opposite of copy-up
c2b27bf2
AM
21964+ */
21965+
21966+#include "aufs.h"
21967+
c2b27bf2
AM
21968+struct au_mvd_args {
21969+ struct {
c2b27bf2
AM
21970+ struct super_block *h_sb;
21971+ struct dentry *h_parent;
21972+ struct au_hinode *hdir;
392086de 21973+ struct inode *h_dir, *h_inode;
c1595e42 21974+ struct au_pin pin;
c2b27bf2
AM
21975+ } info[AUFS_MVDOWN_NARRAY];
21976+
21977+ struct aufs_mvdown mvdown;
21978+ struct dentry *dentry, *parent;
21979+ struct inode *inode, *dir;
21980+ struct super_block *sb;
21981+ aufs_bindex_t bopq, bwh, bfound;
21982+ unsigned char rename_lock;
c2b27bf2
AM
21983+};
21984+
392086de 21985+#define mvd_errno mvdown.au_errno
076b876e
AM
21986+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
21987+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid
21988+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
21989+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid
c2b27bf2 21990+
392086de
AM
21991+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
21992+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
21993+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
21994+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
21995+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
c1595e42 21996+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin
392086de
AM
21997+
21998+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
21999+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
22000+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
22001+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
22002+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c1595e42 22003+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin
c2b27bf2
AM
22004+
22005+#define AU_MVD_PR(flag, ...) do { \
22006+ if (flag) \
22007+ pr_err(__VA_ARGS__); \
22008+ } while (0)
22009+
076b876e
AM
22010+static int find_lower_writable(struct au_mvd_args *a)
22011+{
22012+ struct super_block *sb;
22013+ aufs_bindex_t bindex, bend;
22014+ struct au_branch *br;
22015+
22016+ sb = a->sb;
22017+ bindex = a->mvd_bsrc;
22018+ bend = au_sbend(sb);
22019+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
22020+ for (bindex++; bindex <= bend; bindex++) {
22021+ br = au_sbr(sb, bindex);
22022+ if (au_br_fhsm(br->br_perm)
22023+ && (!(au_br_sb(br)->s_flags & MS_RDONLY)))
22024+ return bindex;
22025+ }
22026+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
22027+ for (bindex++; bindex <= bend; bindex++) {
22028+ br = au_sbr(sb, bindex);
22029+ if (!au_br_rdonly(br))
22030+ return bindex;
22031+ }
22032+ else
22033+ for (bindex++; bindex <= bend; bindex++) {
22034+ br = au_sbr(sb, bindex);
22035+ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
22036+ if (au_br_rdonly(br))
22037+ a->mvdown.flags
22038+ |= AUFS_MVDOWN_ROLOWER_R;
22039+ return bindex;
22040+ }
22041+ }
22042+
22043+ return -1;
22044+}
22045+
c2b27bf2 22046+/* make the parent dir on bdst */
392086de 22047+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22048+{
22049+ int err;
22050+
22051+ err = 0;
22052+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
22053+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
22054+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
22055+ a->mvd_h_dst_parent = NULL;
22056+ if (au_dbend(a->parent) >= a->mvd_bdst)
22057+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
22058+ if (!a->mvd_h_dst_parent) {
22059+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
22060+ if (unlikely(err)) {
392086de 22061+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
22062+ goto out;
22063+ }
22064+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
22065+ }
22066+
22067+out:
22068+ AuTraceErr(err);
22069+ return err;
22070+}
22071+
22072+/* lock them all */
392086de 22073+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22074+{
22075+ int err;
22076+ struct dentry *h_trap;
22077+
22078+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
22079+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
c1595e42
JR
22080+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst,
22081+ au_opt_udba(a->sb),
22082+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
22083+ AuTraceErr(err);
22084+ if (unlikely(err)) {
22085+ AU_MVD_PR(dmsg, "pin_dst failed\n");
22086+ goto out;
22087+ }
22088+
c2b27bf2
AM
22089+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
22090+ a->rename_lock = 0;
c1595e42
JR
22091+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
22092+ AuLsc_DI_PARENT, AuLsc_I_PARENT3,
22093+ au_opt_udba(a->sb),
22094+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
22095+ err = au_do_pin(&a->mvd_pin_src);
22096+ AuTraceErr(err);
5527c038 22097+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
c1595e42
JR
22098+ if (unlikely(err)) {
22099+ AU_MVD_PR(dmsg, "pin_src failed\n");
22100+ goto out_dst;
22101+ }
22102+ goto out; /* success */
c2b27bf2
AM
22103+ }
22104+
c2b27bf2 22105+ a->rename_lock = 1;
c1595e42
JR
22106+ au_pin_hdir_unlock(&a->mvd_pin_dst);
22107+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
22108+ au_opt_udba(a->sb),
22109+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
22110+ AuTraceErr(err);
5527c038 22111+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent);
c1595e42
JR
22112+ if (unlikely(err)) {
22113+ AU_MVD_PR(dmsg, "pin_src failed\n");
22114+ au_pin_hdir_lock(&a->mvd_pin_dst);
22115+ goto out_dst;
22116+ }
22117+ au_pin_hdir_unlock(&a->mvd_pin_src);
c2b27bf2
AM
22118+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
22119+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
22120+ if (h_trap) {
22121+ err = (h_trap != a->mvd_h_src_parent);
22122+ if (err)
22123+ err = (h_trap != a->mvd_h_dst_parent);
22124+ }
22125+ BUG_ON(err); /* it should never happen */
c1595e42
JR
22126+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) {
22127+ err = -EBUSY;
22128+ AuTraceErr(err);
22129+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
22130+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
22131+ au_pin_hdir_lock(&a->mvd_pin_src);
22132+ au_unpin(&a->mvd_pin_src);
22133+ au_pin_hdir_lock(&a->mvd_pin_dst);
22134+ goto out_dst;
22135+ }
22136+ goto out; /* success */
c2b27bf2 22137+
c1595e42
JR
22138+out_dst:
22139+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
22140+out:
22141+ AuTraceErr(err);
22142+ return err;
22143+}
22144+
392086de 22145+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2 22146+{
c1595e42
JR
22147+ if (!a->rename_lock)
22148+ au_unpin(&a->mvd_pin_src);
22149+ else {
c2b27bf2
AM
22150+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
22151+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
c1595e42
JR
22152+ au_pin_hdir_lock(&a->mvd_pin_src);
22153+ au_unpin(&a->mvd_pin_src);
22154+ au_pin_hdir_lock(&a->mvd_pin_dst);
22155+ }
22156+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
22157+}
22158+
22159+/* copy-down the file */
392086de 22160+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22161+{
22162+ int err;
22163+ struct au_cp_generic cpg = {
22164+ .dentry = a->dentry,
22165+ .bdst = a->mvd_bdst,
22166+ .bsrc = a->mvd_bsrc,
22167+ .len = -1,
c1595e42 22168+ .pin = &a->mvd_pin_dst,
c2b27bf2
AM
22169+ .flags = AuCpup_DTIME | AuCpup_HOPEN
22170+ };
22171+
22172+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
22173+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
22174+ au_fset_cpup(cpg.flags, OVERWRITE);
22175+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
22176+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
22177+ err = au_sio_cpdown_simple(&cpg);
22178+ if (unlikely(err))
392086de 22179+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
22180+
22181+ AuTraceErr(err);
22182+ return err;
22183+}
22184+
22185+/*
22186+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
22187+ * were sleeping
22188+ */
392086de 22189+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22190+{
22191+ int err;
22192+ struct path h_path;
22193+ struct au_branch *br;
523b37e3 22194+ struct inode *delegated;
c2b27bf2
AM
22195+
22196+ br = au_sbr(a->sb, a->mvd_bdst);
22197+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
22198+ err = PTR_ERR(h_path.dentry);
22199+ if (IS_ERR(h_path.dentry)) {
392086de 22200+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
22201+ goto out;
22202+ }
22203+
22204+ err = 0;
5527c038 22205+ if (d_is_positive(h_path.dentry)) {
c2b27bf2 22206+ h_path.mnt = au_br_mnt(br);
523b37e3 22207+ delegated = NULL;
5527c038 22208+ err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path,
523b37e3
AM
22209+ &delegated, /*force*/0);
22210+ if (unlikely(err == -EWOULDBLOCK)) {
22211+ pr_warn("cannot retry for NFSv4 delegation"
22212+ " for an internal unlink\n");
22213+ iput(delegated);
22214+ }
c2b27bf2 22215+ if (unlikely(err))
392086de 22216+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
22217+ }
22218+ dput(h_path.dentry);
22219+
22220+out:
22221+ AuTraceErr(err);
22222+ return err;
22223+}
22224+
22225+/*
22226+ * unlink the topmost h_dentry
c2b27bf2 22227+ */
392086de 22228+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22229+{
22230+ int err;
22231+ struct path h_path;
523b37e3 22232+ struct inode *delegated;
c2b27bf2
AM
22233+
22234+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
22235+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
22236+ delegated = NULL;
22237+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
22238+ if (unlikely(err == -EWOULDBLOCK)) {
22239+ pr_warn("cannot retry for NFSv4 delegation"
22240+ " for an internal unlink\n");
22241+ iput(delegated);
22242+ }
c2b27bf2 22243+ if (unlikely(err))
392086de 22244+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
22245+
22246+ AuTraceErr(err);
22247+ return err;
22248+}
22249+
076b876e
AM
22250+/* Since mvdown succeeded, we ignore an error of this function */
22251+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
22252+{
22253+ int err;
22254+ struct au_branch *br;
22255+
22256+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
22257+ br = au_sbr(a->sb, a->mvd_bsrc);
22258+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
22259+ if (!err) {
22260+ br = au_sbr(a->sb, a->mvd_bdst);
22261+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
22262+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
22263+ }
22264+ if (!err)
22265+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
22266+ else
22267+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
22268+}
22269+
c2b27bf2
AM
22270+/*
22271+ * copy-down the file and unlink the bsrc file.
22272+ * - unlink the bdst whout if exist
22273+ * - copy-down the file (with whtmp name and rename)
22274+ * - unlink the bsrc file
22275+ */
392086de 22276+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22277+{
22278+ int err;
22279+
392086de 22280+ err = au_do_mkdir(dmsg, a);
c2b27bf2 22281+ if (!err)
392086de 22282+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
22283+ if (unlikely(err))
22284+ goto out;
22285+
22286+ /*
22287+ * do not revert the activities we made on bdst since they should be
22288+ * harmless in aufs.
22289+ */
22290+
392086de 22291+ err = au_do_cpdown(dmsg, a);
c2b27bf2 22292+ if (!err)
392086de
AM
22293+ err = au_do_unlink_wh(dmsg, a);
22294+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
22295+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
22296+ if (unlikely(err))
22297+ goto out_unlock;
22298+
c1595e42
JR
22299+ AuDbg("%pd2, 0x%x, %d --> %d\n",
22300+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst);
076b876e
AM
22301+ if (find_lower_writable(a) < 0)
22302+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
22303+
22304+ if (a->mvdown.flags & AUFS_MVDOWN_STFS)
22305+ au_do_stfs(dmsg, a);
22306+
c2b27bf2 22307+ /* maintain internal array */
392086de
AM
22308+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
22309+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
22310+ au_set_dbstart(a->dentry, a->mvd_bdst);
22311+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
22312+ au_set_ibstart(a->inode, a->mvd_bdst);
79b8bda9
AM
22313+ } else {
22314+ /* hide the lower */
22315+ au_set_h_dptr(a->dentry, a->mvd_bdst, NULL);
22316+ au_set_dbend(a->dentry, a->mvd_bsrc);
22317+ au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0);
22318+ au_set_ibend(a->inode, a->mvd_bsrc);
392086de 22319+ }
c2b27bf2
AM
22320+ if (au_dbend(a->dentry) < a->mvd_bdst)
22321+ au_set_dbend(a->dentry, a->mvd_bdst);
c2b27bf2
AM
22322+ if (au_ibend(a->inode) < a->mvd_bdst)
22323+ au_set_ibend(a->inode, a->mvd_bdst);
22324+
22325+out_unlock:
392086de 22326+ au_do_unlock(dmsg, a);
c2b27bf2
AM
22327+out:
22328+ AuTraceErr(err);
22329+ return err;
22330+}
22331+
22332+/* ---------------------------------------------------------------------- */
22333+
c2b27bf2 22334+/* make sure the file is idle */
392086de 22335+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22336+{
22337+ int err, plinked;
c2b27bf2
AM
22338+
22339+ err = 0;
c2b27bf2
AM
22340+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
22341+ if (au_dbstart(a->dentry) == a->mvd_bsrc
c1595e42 22342+ && au_dcount(a->dentry) == 1
c2b27bf2 22343+ && atomic_read(&a->inode->i_count) == 1
392086de 22344+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
22345+ && (!plinked || !au_plink_test(a->inode))
22346+ && a->inode->i_nlink == 1)
22347+ goto out;
22348+
22349+ err = -EBUSY;
392086de 22350+ AU_MVD_PR(dmsg,
c1595e42
JR
22351+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
22352+ a->mvd_bsrc, au_dbstart(a->dentry), au_dcount(a->dentry),
c2b27bf2 22353+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 22354+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
22355+ plinked, plinked ? au_plink_test(a->inode) : 0);
22356+
22357+out:
22358+ AuTraceErr(err);
22359+ return err;
22360+}
22361+
22362+/* make sure the parent dir is fine */
392086de 22363+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
22364+ struct au_mvd_args *a)
22365+{
22366+ int err;
22367+ aufs_bindex_t bindex;
22368+
22369+ err = 0;
22370+ if (unlikely(au_alive_dir(a->parent))) {
22371+ err = -ENOENT;
392086de 22372+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
22373+ goto out;
22374+ }
22375+
22376+ a->bopq = au_dbdiropq(a->parent);
22377+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
22378+ AuDbg("b%d\n", bindex);
22379+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
22380+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
22381+ err = -EINVAL;
392086de
AM
22382+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
22383+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
22384+ a->bopq, a->mvd_bdst);
22385+ }
22386+
22387+out:
22388+ AuTraceErr(err);
22389+ return err;
22390+}
22391+
392086de 22392+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
22393+ struct au_mvd_args *a)
22394+{
22395+ int err;
22396+ struct au_dinfo *dinfo, *tmp;
22397+
22398+ /* lookup the next lower positive entry */
22399+ err = -ENOMEM;
22400+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
22401+ if (unlikely(!tmp))
22402+ goto out;
22403+
22404+ a->bfound = -1;
22405+ a->bwh = -1;
22406+ dinfo = au_di(a->dentry);
22407+ au_di_cp(tmp, dinfo);
22408+ au_di_swap(tmp, dinfo);
22409+
22410+ /* returns the number of positive dentries */
22411+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0);
22412+ if (!err)
22413+ a->bwh = au_dbwh(a->dentry);
22414+ else if (err > 0)
22415+ a->bfound = au_dbstart(a->dentry);
22416+
22417+ au_di_swap(tmp, dinfo);
22418+ au_rw_write_unlock(&tmp->di_rwsem);
22419+ au_di_free(tmp);
22420+ if (unlikely(err < 0))
392086de 22421+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
22422+
22423+ /*
22424+ * here, we have these cases.
22425+ * bfound == -1
22426+ * no positive dentry under bsrc. there are more sub-cases.
22427+ * bwh < 0
22428+ * there no whiteout, we can safely move-down.
22429+ * bwh <= bsrc
22430+ * impossible
22431+ * bsrc < bwh && bwh < bdst
22432+ * there is a whiteout on RO branch. cannot proceed.
22433+ * bwh == bdst
22434+ * there is a whiteout on the RW target branch. it should
22435+ * be removed.
22436+ * bdst < bwh
22437+ * there is a whiteout somewhere unrelated branch.
22438+ * -1 < bfound && bfound <= bsrc
22439+ * impossible.
22440+ * bfound < bdst
22441+ * found, but it is on RO branch between bsrc and bdst. cannot
22442+ * proceed.
22443+ * bfound == bdst
22444+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
22445+ * error.
22446+ * bdst < bfound
22447+ * found, after we create the file on bdst, it will be hidden.
22448+ */
22449+
22450+ AuDebugOn(a->bfound == -1
22451+ && a->bwh != -1
22452+ && a->bwh <= a->mvd_bsrc);
22453+ AuDebugOn(-1 < a->bfound
22454+ && a->bfound <= a->mvd_bsrc);
22455+
22456+ err = -EINVAL;
22457+ if (a->bfound == -1
22458+ && a->mvd_bsrc < a->bwh
22459+ && a->bwh != -1
22460+ && a->bwh < a->mvd_bdst) {
392086de
AM
22461+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
22462+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
22463+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
22464+ goto out;
22465+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
22466+ a->mvd_errno = EAU_MVDOWN_UPPER;
22467+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
22468+ a->mvd_bdst, a->bfound);
22469+ goto out;
22470+ }
22471+
22472+ err = 0; /* success */
22473+
22474+out:
22475+ AuTraceErr(err);
22476+ return err;
22477+}
22478+
392086de 22479+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22480+{
22481+ int err;
22482+
392086de
AM
22483+ err = 0;
22484+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
22485+ && a->bfound == a->mvd_bdst)
22486+ err = -EEXIST;
c2b27bf2
AM
22487+ AuTraceErr(err);
22488+ return err;
22489+}
22490+
392086de 22491+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22492+{
22493+ int err;
22494+ struct au_branch *br;
22495+
22496+ err = -EISDIR;
22497+ if (unlikely(S_ISDIR(a->inode->i_mode)))
22498+ goto out;
22499+
22500+ err = -EINVAL;
392086de
AM
22501+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
22502+ a->mvd_bsrc = au_ibstart(a->inode);
22503+ else {
22504+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
22505+ if (unlikely(a->mvd_bsrc < 0
22506+ || (a->mvd_bsrc < au_dbstart(a->dentry)
22507+ || au_dbend(a->dentry) < a->mvd_bsrc
22508+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
22509+ || (a->mvd_bsrc < au_ibstart(a->inode)
22510+ || au_ibend(a->inode) < a->mvd_bsrc
22511+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
22512+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
22513+ AU_MVD_PR(dmsg, "no upper\n");
22514+ goto out;
22515+ }
22516+ }
c2b27bf2 22517+ if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) {
392086de
AM
22518+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
22519+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
22520+ goto out;
22521+ }
392086de 22522+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
22523+ br = au_sbr(a->sb, a->mvd_bsrc);
22524+ err = au_br_rdonly(br);
392086de
AM
22525+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
22526+ if (unlikely(err))
22527+ goto out;
22528+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
22529+ || IS_APPEND(a->mvd_h_src_inode))) {
22530+ if (err)
22531+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
22532+ /* go on */
22533+ } else
c2b27bf2
AM
22534+ goto out;
22535+
22536+ err = -EINVAL;
392086de
AM
22537+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
22538+ a->mvd_bdst = find_lower_writable(a);
22539+ if (unlikely(a->mvd_bdst < 0)) {
22540+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
22541+ AU_MVD_PR(dmsg, "no writable lower branch\n");
22542+ goto out;
22543+ }
22544+ } else {
22545+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
22546+ if (unlikely(a->mvd_bdst < 0
22547+ || au_sbend(a->sb) < a->mvd_bdst)) {
22548+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
22549+ AU_MVD_PR(dmsg, "no lower brid\n");
22550+ goto out;
22551+ }
c2b27bf2
AM
22552+ }
22553+
392086de 22554+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 22555+ if (!err)
392086de 22556+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 22557+ if (!err)
392086de 22558+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 22559+ if (!err)
392086de 22560+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
22561+ if (!err)
22562+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
22563+
22564+out:
22565+ AuTraceErr(err);
22566+ return err;
22567+}
22568+
22569+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
22570+{
392086de
AM
22571+ int err, e;
22572+ unsigned char dmsg;
22573+ struct au_mvd_args *args;
79b8bda9 22574+ struct inode *inode;
c2b27bf2 22575+
79b8bda9 22576+ inode = d_inode(dentry);
c2b27bf2
AM
22577+ err = -EPERM;
22578+ if (unlikely(!capable(CAP_SYS_ADMIN)))
22579+ goto out;
22580+
392086de
AM
22581+ err = -ENOMEM;
22582+ args = kmalloc(sizeof(*args), GFP_NOFS);
22583+ if (unlikely(!args))
22584+ goto out;
22585+
22586+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
22587+ if (!err)
22588+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
22589+ if (unlikely(err)) {
22590+ err = -EFAULT;
392086de
AM
22591+ AuTraceErr(err);
22592+ goto out_free;
c2b27bf2 22593+ }
392086de
AM
22594+ AuDbg("flags 0x%x\n", args->mvdown.flags);
22595+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
22596+ args->mvdown.au_errno = 0;
22597+ args->dentry = dentry;
79b8bda9 22598+ args->inode = inode;
392086de 22599+ args->sb = dentry->d_sb;
c2b27bf2 22600+
392086de
AM
22601+ err = -ENOENT;
22602+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
22603+ args->parent = dget_parent(dentry);
5527c038 22604+ args->dir = d_inode(args->parent);
392086de
AM
22605+ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
22606+ dput(args->parent);
22607+ if (unlikely(args->parent != dentry->d_parent)) {
22608+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
22609+ goto out_dir;
22610+ }
22611+
79b8bda9 22612+ mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
c2b27bf2
AM
22613+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
22614+ if (unlikely(err))
22615+ goto out_inode;
22616+
392086de
AM
22617+ di_write_lock_parent(args->parent);
22618+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
22619+ if (unlikely(err))
22620+ goto out_parent;
22621+
392086de 22622+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
22623+ if (unlikely(err))
22624+ goto out_parent;
c2b27bf2 22625+
392086de 22626+ au_cpup_attr_timesizes(args->dir);
79b8bda9
AM
22627+ au_cpup_attr_timesizes(inode);
22628+ if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER))
22629+ au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst));
c2b27bf2
AM
22630+ /* au_digen_dec(dentry); */
22631+
22632+out_parent:
392086de 22633+ di_write_unlock(args->parent);
c2b27bf2
AM
22634+ aufs_read_unlock(dentry, AuLock_DW);
22635+out_inode:
79b8bda9 22636+ mutex_unlock(&inode->i_mutex);
c2b27bf2 22637+out_dir:
392086de
AM
22638+ mutex_unlock(&args->dir->i_mutex);
22639+out_free:
22640+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
22641+ if (unlikely(e))
22642+ err = -EFAULT;
22643+ kfree(args);
c2b27bf2
AM
22644+out:
22645+ AuTraceErr(err);
22646+ return err;
22647+}
22648diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
22649--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
22650+++ linux/fs/aufs/opts.c 2015-11-11 17:21:46.918863802 +0100
22651@@ -0,0 +1,1859 @@
1facf9fc 22652+/*
2000de60 22653+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 22654+ *
22655+ * This program, aufs is free software; you can redistribute it and/or modify
22656+ * it under the terms of the GNU General Public License as published by
22657+ * the Free Software Foundation; either version 2 of the License, or
22658+ * (at your option) any later version.
dece6358
AM
22659+ *
22660+ * This program is distributed in the hope that it will be useful,
22661+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22662+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22663+ * GNU General Public License for more details.
22664+ *
22665+ * You should have received a copy of the GNU General Public License
523b37e3 22666+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22667+ */
22668+
22669+/*
22670+ * mount options/flags
22671+ */
22672+
dece6358 22673+#include <linux/namei.h>
1facf9fc 22674+#include <linux/types.h> /* a distribution requires */
22675+#include <linux/parser.h>
22676+#include "aufs.h"
22677+
22678+/* ---------------------------------------------------------------------- */
22679+
22680+enum {
22681+ Opt_br,
7e9cd9fe
AM
22682+ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
22683+ Opt_idel, Opt_imod,
22684+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
dece6358 22685+ Opt_rdblk_def, Opt_rdhash_def,
7e9cd9fe 22686+ Opt_xino, Opt_noxino,
1facf9fc 22687+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
22688+ Opt_trunc_xino_path, Opt_itrunc_xino,
22689+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 22690+ Opt_shwh, Opt_noshwh,
1facf9fc 22691+ Opt_plink, Opt_noplink, Opt_list_plink,
22692+ Opt_udba,
4a4d8108 22693+ Opt_dio, Opt_nodio,
1facf9fc 22694+ Opt_diropq_a, Opt_diropq_w,
22695+ Opt_warn_perm, Opt_nowarn_perm,
22696+ Opt_wbr_copyup, Opt_wbr_create,
076b876e 22697+ Opt_fhsm_sec,
1facf9fc 22698+ Opt_verbose, Opt_noverbose,
22699+ Opt_sum, Opt_nosum, Opt_wsum,
076b876e 22700+ Opt_dirperm1, Opt_nodirperm1,
c1595e42 22701+ Opt_acl, Opt_noacl,
1facf9fc 22702+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
22703+};
22704+
22705+static match_table_t options = {
22706+ {Opt_br, "br=%s"},
22707+ {Opt_br, "br:%s"},
22708+
22709+ {Opt_add, "add=%d:%s"},
22710+ {Opt_add, "add:%d:%s"},
22711+ {Opt_add, "ins=%d:%s"},
22712+ {Opt_add, "ins:%d:%s"},
22713+ {Opt_append, "append=%s"},
22714+ {Opt_append, "append:%s"},
22715+ {Opt_prepend, "prepend=%s"},
22716+ {Opt_prepend, "prepend:%s"},
22717+
22718+ {Opt_del, "del=%s"},
22719+ {Opt_del, "del:%s"},
22720+ /* {Opt_idel, "idel:%d"}, */
22721+ {Opt_mod, "mod=%s"},
22722+ {Opt_mod, "mod:%s"},
22723+ /* {Opt_imod, "imod:%d:%s"}, */
22724+
22725+ {Opt_dirwh, "dirwh=%d"},
22726+
22727+ {Opt_xino, "xino=%s"},
22728+ {Opt_noxino, "noxino"},
22729+ {Opt_trunc_xino, "trunc_xino"},
22730+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
22731+ {Opt_notrunc_xino, "notrunc_xino"},
22732+ {Opt_trunc_xino_path, "trunc_xino=%s"},
22733+ {Opt_itrunc_xino, "itrunc_xino=%d"},
22734+ /* {Opt_zxino, "zxino=%s"}, */
22735+ {Opt_trunc_xib, "trunc_xib"},
22736+ {Opt_notrunc_xib, "notrunc_xib"},
22737+
e49829fe 22738+#ifdef CONFIG_PROC_FS
1facf9fc 22739+ {Opt_plink, "plink"},
e49829fe
JR
22740+#else
22741+ {Opt_ignore_silent, "plink"},
22742+#endif
22743+
1facf9fc 22744+ {Opt_noplink, "noplink"},
e49829fe 22745+
1facf9fc 22746+#ifdef CONFIG_AUFS_DEBUG
22747+ {Opt_list_plink, "list_plink"},
22748+#endif
22749+
22750+ {Opt_udba, "udba=%s"},
22751+
4a4d8108
AM
22752+ {Opt_dio, "dio"},
22753+ {Opt_nodio, "nodio"},
22754+
076b876e
AM
22755+#ifdef CONFIG_AUFS_FHSM
22756+ {Opt_fhsm_sec, "fhsm_sec=%d"},
22757+#else
22758+ {Opt_ignore_silent, "fhsm_sec=%d"},
22759+#endif
22760+
1facf9fc 22761+ {Opt_diropq_a, "diropq=always"},
22762+ {Opt_diropq_a, "diropq=a"},
22763+ {Opt_diropq_w, "diropq=whiteouted"},
22764+ {Opt_diropq_w, "diropq=w"},
22765+
22766+ {Opt_warn_perm, "warn_perm"},
22767+ {Opt_nowarn_perm, "nowarn_perm"},
22768+
22769+ /* keep them temporary */
1facf9fc 22770+ {Opt_ignore_silent, "nodlgt"},
1facf9fc 22771+ {Opt_ignore_silent, "clean_plink"},
22772+
dece6358
AM
22773+#ifdef CONFIG_AUFS_SHWH
22774+ {Opt_shwh, "shwh"},
22775+#endif
22776+ {Opt_noshwh, "noshwh"},
22777+
076b876e
AM
22778+ {Opt_dirperm1, "dirperm1"},
22779+ {Opt_nodirperm1, "nodirperm1"},
22780+
1facf9fc 22781+ {Opt_verbose, "verbose"},
22782+ {Opt_verbose, "v"},
22783+ {Opt_noverbose, "noverbose"},
22784+ {Opt_noverbose, "quiet"},
22785+ {Opt_noverbose, "q"},
22786+ {Opt_noverbose, "silent"},
22787+
22788+ {Opt_sum, "sum"},
22789+ {Opt_nosum, "nosum"},
22790+ {Opt_wsum, "wsum"},
22791+
22792+ {Opt_rdcache, "rdcache=%d"},
22793+ {Opt_rdblk, "rdblk=%d"},
dece6358 22794+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 22795+ {Opt_rdhash, "rdhash=%d"},
dece6358 22796+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 22797+
22798+ {Opt_wbr_create, "create=%s"},
22799+ {Opt_wbr_create, "create_policy=%s"},
22800+ {Opt_wbr_copyup, "cpup=%s"},
22801+ {Opt_wbr_copyup, "copyup=%s"},
22802+ {Opt_wbr_copyup, "copyup_policy=%s"},
22803+
c1595e42
JR
22804+ /* generic VFS flag */
22805+#ifdef CONFIG_FS_POSIX_ACL
22806+ {Opt_acl, "acl"},
22807+ {Opt_noacl, "noacl"},
22808+#else
22809+ {Opt_ignore_silent, "acl"},
22810+ {Opt_ignore_silent, "noacl"},
22811+#endif
22812+
1facf9fc 22813+ /* internal use for the scripts */
22814+ {Opt_ignore_silent, "si=%s"},
22815+
22816+ {Opt_br, "dirs=%s"},
22817+ {Opt_ignore, "debug=%d"},
22818+ {Opt_ignore, "delete=whiteout"},
22819+ {Opt_ignore, "delete=all"},
22820+ {Opt_ignore, "imap=%s"},
22821+
1308ab2a 22822+ /* temporary workaround, due to old mount(8)? */
22823+ {Opt_ignore_silent, "relatime"},
22824+
1facf9fc 22825+ {Opt_err, NULL}
22826+};
22827+
22828+/* ---------------------------------------------------------------------- */
22829+
076b876e 22830+static const char *au_parser_pattern(int val, match_table_t tbl)
1facf9fc 22831+{
076b876e
AM
22832+ struct match_token *p;
22833+
22834+ p = tbl;
22835+ while (p->pattern) {
22836+ if (p->token == val)
22837+ return p->pattern;
22838+ p++;
1facf9fc 22839+ }
22840+ BUG();
22841+ return "??";
22842+}
22843+
076b876e
AM
22844+static const char *au_optstr(int *val, match_table_t tbl)
22845+{
22846+ struct match_token *p;
22847+ int v;
22848+
22849+ v = *val;
2000de60
JR
22850+ if (!v)
22851+ goto out;
076b876e 22852+ p = tbl;
2000de60
JR
22853+ while (p->pattern) {
22854+ if (p->token
22855+ && (v & p->token) == p->token) {
076b876e
AM
22856+ *val &= ~p->token;
22857+ return p->pattern;
22858+ }
22859+ p++;
22860+ }
2000de60
JR
22861+
22862+out:
076b876e
AM
22863+ return NULL;
22864+}
22865+
1facf9fc 22866+/* ---------------------------------------------------------------------- */
22867+
1e00d052 22868+static match_table_t brperm = {
1facf9fc 22869+ {AuBrPerm_RO, AUFS_BRPERM_RO},
22870+ {AuBrPerm_RR, AUFS_BRPERM_RR},
22871+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
22872+ {0, NULL}
22873+};
1facf9fc 22874+
86dc4139 22875+static match_table_t brattr = {
076b876e
AM
22876+ /* general */
22877+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
22878+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
c1595e42 22879+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
86dc4139 22880+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
2000de60 22881+#ifdef CONFIG_AUFS_FHSM
076b876e 22882+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
2000de60
JR
22883+#endif
22884+#ifdef CONFIG_AUFS_XATTR
c1595e42
JR
22885+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
22886+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
22887+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
22888+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
22889+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
22890+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
2000de60 22891+#endif
076b876e
AM
22892+
22893+ /* ro/rr branch */
1e00d052 22894+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
076b876e
AM
22895+
22896+ /* rw branch */
22897+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
1e00d052 22898+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
076b876e 22899+
1e00d052 22900+ {0, NULL}
1facf9fc 22901+};
22902+
1e00d052
AM
22903+static int br_attr_val(char *str, match_table_t table, substring_t args[])
22904+{
22905+ int attr, v;
22906+ char *p;
22907+
22908+ attr = 0;
22909+ do {
22910+ p = strchr(str, '+');
22911+ if (p)
22912+ *p = 0;
22913+ v = match_token(str, table, args);
076b876e
AM
22914+ if (v) {
22915+ if (v & AuBrAttr_CMOO_Mask)
22916+ attr &= ~AuBrAttr_CMOO_Mask;
1e00d052 22917+ attr |= v;
076b876e 22918+ } else {
1e00d052
AM
22919+ if (p)
22920+ *p = '+';
0c3ec466 22921+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
22922+ break;
22923+ }
22924+ if (p)
22925+ str = p + 1;
22926+ } while (p);
22927+
22928+ return attr;
22929+}
22930+
076b876e
AM
22931+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
22932+{
22933+ int sz;
22934+ const char *p;
22935+ char *q;
22936+
076b876e
AM
22937+ q = str->a;
22938+ *q = 0;
22939+ p = au_optstr(&perm, brattr);
22940+ if (p) {
22941+ sz = strlen(p);
22942+ memcpy(q, p, sz + 1);
22943+ q += sz;
22944+ } else
22945+ goto out;
22946+
22947+ do {
22948+ p = au_optstr(&perm, brattr);
22949+ if (p) {
22950+ *q++ = '+';
22951+ sz = strlen(p);
22952+ memcpy(q, p, sz + 1);
22953+ q += sz;
22954+ }
22955+ } while (p);
22956+
22957+out:
c1595e42 22958+ return q - str->a;
076b876e
AM
22959+}
22960+
4a4d8108 22961+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 22962+{
076b876e
AM
22963+ int val, bad, sz;
22964+ char *p;
1facf9fc 22965+ substring_t args[MAX_OPT_ARGS];
076b876e 22966+ au_br_perm_str_t attr;
1facf9fc 22967+
1e00d052
AM
22968+ p = strchr(perm, '+');
22969+ if (p)
22970+ *p = 0;
22971+ val = match_token(perm, brperm, args);
22972+ if (!val) {
22973+ if (p)
22974+ *p = '+';
0c3ec466 22975+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
22976+ val = AuBrPerm_RO;
22977+ goto out;
22978+ }
22979+ if (!p)
22980+ goto out;
22981+
076b876e
AM
22982+ val |= br_attr_val(p + 1, brattr, args);
22983+
22984+ bad = 0;
86dc4139 22985+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
22986+ case AuBrPerm_RO:
22987+ case AuBrPerm_RR:
076b876e
AM
22988+ bad = val & AuBrWAttr_Mask;
22989+ val &= ~AuBrWAttr_Mask;
1e00d052
AM
22990+ break;
22991+ case AuBrPerm_RW:
076b876e
AM
22992+ bad = val & AuBrRAttr_Mask;
22993+ val &= ~AuBrRAttr_Mask;
1e00d052
AM
22994+ break;
22995+ }
c1595e42
JR
22996+
22997+ /*
22998+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
22999+ * does not treat it as an error, just warning.
23000+ * this is a tiny guard for the user operation.
23001+ */
23002+ if (val & AuBrAttr_UNPIN) {
23003+ bad |= AuBrAttr_UNPIN;
23004+ val &= ~AuBrAttr_UNPIN;
23005+ }
23006+
076b876e
AM
23007+ if (unlikely(bad)) {
23008+ sz = au_do_optstr_br_attr(&attr, bad);
23009+ AuDebugOn(!sz);
23010+ pr_warn("ignored branch attribute %s\n", attr.a);
23011+ }
1e00d052
AM
23012+
23013+out:
1facf9fc 23014+ return val;
23015+}
23016+
076b876e 23017+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
1facf9fc 23018+{
076b876e
AM
23019+ au_br_perm_str_t attr;
23020+ const char *p;
23021+ char *q;
1e00d052
AM
23022+ int sz;
23023+
076b876e
AM
23024+ q = str->a;
23025+ p = au_optstr(&perm, brperm);
23026+ AuDebugOn(!p || !*p);
23027+ sz = strlen(p);
23028+ memcpy(q, p, sz + 1);
23029+ q += sz;
1e00d052 23030+
076b876e
AM
23031+ sz = au_do_optstr_br_attr(&attr, perm);
23032+ if (sz) {
23033+ *q++ = '+';
23034+ memcpy(q, attr.a, sz + 1);
1e00d052
AM
23035+ }
23036+
076b876e 23037+ AuDebugOn(strlen(str->a) >= sizeof(str->a));
1facf9fc 23038+}
23039+
23040+/* ---------------------------------------------------------------------- */
23041+
23042+static match_table_t udbalevel = {
23043+ {AuOpt_UDBA_REVAL, "reval"},
23044+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
23045+#ifdef CONFIG_AUFS_HNOTIFY
23046+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
23047+#ifdef CONFIG_AUFS_HFSNOTIFY
23048+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 23049+#endif
1facf9fc 23050+#endif
23051+ {-1, NULL}
23052+};
23053+
4a4d8108 23054+static int noinline_for_stack udba_val(char *str)
1facf9fc 23055+{
23056+ substring_t args[MAX_OPT_ARGS];
23057+
7f207e10 23058+ return match_token(str, udbalevel, args);
1facf9fc 23059+}
23060+
23061+const char *au_optstr_udba(int udba)
23062+{
076b876e 23063+ return au_parser_pattern(udba, udbalevel);
1facf9fc 23064+}
23065+
23066+/* ---------------------------------------------------------------------- */
23067+
23068+static match_table_t au_wbr_create_policy = {
23069+ {AuWbrCreate_TDP, "tdp"},
23070+ {AuWbrCreate_TDP, "top-down-parent"},
23071+ {AuWbrCreate_RR, "rr"},
23072+ {AuWbrCreate_RR, "round-robin"},
23073+ {AuWbrCreate_MFS, "mfs"},
23074+ {AuWbrCreate_MFS, "most-free-space"},
23075+ {AuWbrCreate_MFSV, "mfs:%d"},
23076+ {AuWbrCreate_MFSV, "most-free-space:%d"},
23077+
23078+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
23079+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
23080+ {AuWbrCreate_PMFS, "pmfs"},
23081+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
23082+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
23083+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 23084+
23085+ {-1, NULL}
23086+};
23087+
dece6358
AM
23088+/*
23089+ * cf. linux/lib/parser.c and cmdline.c
23090+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 23091+ * kstrto...().
dece6358 23092+ */
4a4d8108
AM
23093+static int noinline_for_stack
23094+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 23095+{
23096+ int err;
23097+ unsigned int len;
23098+ char a[32];
23099+
23100+ err = -ERANGE;
23101+ len = s->to - s->from;
23102+ if (len + 1 <= sizeof(a)) {
23103+ memcpy(a, s->from, len);
23104+ a[len] = '\0';
9dbd164d 23105+ err = kstrtoull(a, 0, result);
1facf9fc 23106+ }
23107+ return err;
23108+}
23109+
23110+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
23111+ struct au_opt_wbr_create *create)
23112+{
23113+ int err;
23114+ unsigned long long ull;
23115+
23116+ err = 0;
23117+ if (!au_match_ull(arg, &ull))
23118+ create->mfsrr_watermark = ull;
23119+ else {
4a4d8108 23120+ pr_err("bad integer in %s\n", str);
1facf9fc 23121+ err = -EINVAL;
23122+ }
23123+
23124+ return err;
23125+}
23126+
23127+static int au_wbr_mfs_sec(substring_t *arg, char *str,
23128+ struct au_opt_wbr_create *create)
23129+{
23130+ int n, err;
23131+
23132+ err = 0;
027c5e7a 23133+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 23134+ create->mfs_second = n;
23135+ else {
4a4d8108 23136+ pr_err("bad integer in %s\n", str);
1facf9fc 23137+ err = -EINVAL;
23138+ }
23139+
23140+ return err;
23141+}
23142+
4a4d8108
AM
23143+static int noinline_for_stack
23144+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 23145+{
23146+ int err, e;
23147+ substring_t args[MAX_OPT_ARGS];
23148+
23149+ err = match_token(str, au_wbr_create_policy, args);
23150+ create->wbr_create = err;
23151+ switch (err) {
23152+ case AuWbrCreate_MFSRRV:
392086de 23153+ case AuWbrCreate_PMFSRRV:
1facf9fc 23154+ e = au_wbr_mfs_wmark(&args[0], str, create);
23155+ if (!e)
23156+ e = au_wbr_mfs_sec(&args[1], str, create);
23157+ if (unlikely(e))
23158+ err = e;
23159+ break;
23160+ case AuWbrCreate_MFSRR:
392086de 23161+ case AuWbrCreate_PMFSRR:
1facf9fc 23162+ e = au_wbr_mfs_wmark(&args[0], str, create);
23163+ if (unlikely(e)) {
23164+ err = e;
23165+ break;
23166+ }
23167+ /*FALLTHROUGH*/
23168+ case AuWbrCreate_MFS:
23169+ case AuWbrCreate_PMFS:
027c5e7a 23170+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 23171+ break;
23172+ case AuWbrCreate_MFSV:
23173+ case AuWbrCreate_PMFSV:
23174+ e = au_wbr_mfs_sec(&args[0], str, create);
23175+ if (unlikely(e))
23176+ err = e;
23177+ break;
23178+ }
23179+
23180+ return err;
23181+}
23182+
23183+const char *au_optstr_wbr_create(int wbr_create)
23184+{
076b876e 23185+ return au_parser_pattern(wbr_create, au_wbr_create_policy);
1facf9fc 23186+}
23187+
23188+static match_table_t au_wbr_copyup_policy = {
23189+ {AuWbrCopyup_TDP, "tdp"},
23190+ {AuWbrCopyup_TDP, "top-down-parent"},
23191+ {AuWbrCopyup_BUP, "bup"},
23192+ {AuWbrCopyup_BUP, "bottom-up-parent"},
23193+ {AuWbrCopyup_BU, "bu"},
23194+ {AuWbrCopyup_BU, "bottom-up"},
23195+ {-1, NULL}
23196+};
23197+
4a4d8108 23198+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 23199+{
23200+ substring_t args[MAX_OPT_ARGS];
23201+
23202+ return match_token(str, au_wbr_copyup_policy, args);
23203+}
23204+
23205+const char *au_optstr_wbr_copyup(int wbr_copyup)
23206+{
076b876e 23207+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
1facf9fc 23208+}
23209+
23210+/* ---------------------------------------------------------------------- */
23211+
23212+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
23213+
23214+static void dump_opts(struct au_opts *opts)
23215+{
23216+#ifdef CONFIG_AUFS_DEBUG
23217+ /* reduce stack space */
23218+ union {
23219+ struct au_opt_add *add;
23220+ struct au_opt_del *del;
23221+ struct au_opt_mod *mod;
23222+ struct au_opt_xino *xino;
23223+ struct au_opt_xino_itrunc *xino_itrunc;
23224+ struct au_opt_wbr_create *create;
23225+ } u;
23226+ struct au_opt *opt;
23227+
23228+ opt = opts->opt;
23229+ while (opt->type != Opt_tail) {
23230+ switch (opt->type) {
23231+ case Opt_add:
23232+ u.add = &opt->add;
23233+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
23234+ u.add->bindex, u.add->pathname, u.add->perm,
23235+ u.add->path.dentry);
23236+ break;
23237+ case Opt_del:
23238+ case Opt_idel:
23239+ u.del = &opt->del;
23240+ AuDbg("del {%s, %p}\n",
23241+ u.del->pathname, u.del->h_path.dentry);
23242+ break;
23243+ case Opt_mod:
23244+ case Opt_imod:
23245+ u.mod = &opt->mod;
23246+ AuDbg("mod {%s, 0x%x, %p}\n",
23247+ u.mod->path, u.mod->perm, u.mod->h_root);
23248+ break;
23249+ case Opt_append:
23250+ u.add = &opt->add;
23251+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
23252+ u.add->bindex, u.add->pathname, u.add->perm,
23253+ u.add->path.dentry);
23254+ break;
23255+ case Opt_prepend:
23256+ u.add = &opt->add;
23257+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
23258+ u.add->bindex, u.add->pathname, u.add->perm,
23259+ u.add->path.dentry);
23260+ break;
23261+ case Opt_dirwh:
23262+ AuDbg("dirwh %d\n", opt->dirwh);
23263+ break;
23264+ case Opt_rdcache:
23265+ AuDbg("rdcache %d\n", opt->rdcache);
23266+ break;
23267+ case Opt_rdblk:
23268+ AuDbg("rdblk %u\n", opt->rdblk);
23269+ break;
dece6358
AM
23270+ case Opt_rdblk_def:
23271+ AuDbg("rdblk_def\n");
23272+ break;
1facf9fc 23273+ case Opt_rdhash:
23274+ AuDbg("rdhash %u\n", opt->rdhash);
23275+ break;
dece6358
AM
23276+ case Opt_rdhash_def:
23277+ AuDbg("rdhash_def\n");
23278+ break;
1facf9fc 23279+ case Opt_xino:
23280+ u.xino = &opt->xino;
523b37e3 23281+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 23282+ break;
23283+ case Opt_trunc_xino:
23284+ AuLabel(trunc_xino);
23285+ break;
23286+ case Opt_notrunc_xino:
23287+ AuLabel(notrunc_xino);
23288+ break;
23289+ case Opt_trunc_xino_path:
23290+ case Opt_itrunc_xino:
23291+ u.xino_itrunc = &opt->xino_itrunc;
23292+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
23293+ break;
1facf9fc 23294+ case Opt_noxino:
23295+ AuLabel(noxino);
23296+ break;
23297+ case Opt_trunc_xib:
23298+ AuLabel(trunc_xib);
23299+ break;
23300+ case Opt_notrunc_xib:
23301+ AuLabel(notrunc_xib);
23302+ break;
dece6358
AM
23303+ case Opt_shwh:
23304+ AuLabel(shwh);
23305+ break;
23306+ case Opt_noshwh:
23307+ AuLabel(noshwh);
23308+ break;
076b876e
AM
23309+ case Opt_dirperm1:
23310+ AuLabel(dirperm1);
23311+ break;
23312+ case Opt_nodirperm1:
23313+ AuLabel(nodirperm1);
23314+ break;
1facf9fc 23315+ case Opt_plink:
23316+ AuLabel(plink);
23317+ break;
23318+ case Opt_noplink:
23319+ AuLabel(noplink);
23320+ break;
23321+ case Opt_list_plink:
23322+ AuLabel(list_plink);
23323+ break;
23324+ case Opt_udba:
23325+ AuDbg("udba %d, %s\n",
23326+ opt->udba, au_optstr_udba(opt->udba));
23327+ break;
4a4d8108
AM
23328+ case Opt_dio:
23329+ AuLabel(dio);
23330+ break;
23331+ case Opt_nodio:
23332+ AuLabel(nodio);
23333+ break;
1facf9fc 23334+ case Opt_diropq_a:
23335+ AuLabel(diropq_a);
23336+ break;
23337+ case Opt_diropq_w:
23338+ AuLabel(diropq_w);
23339+ break;
23340+ case Opt_warn_perm:
23341+ AuLabel(warn_perm);
23342+ break;
23343+ case Opt_nowarn_perm:
23344+ AuLabel(nowarn_perm);
23345+ break;
1facf9fc 23346+ case Opt_verbose:
23347+ AuLabel(verbose);
23348+ break;
23349+ case Opt_noverbose:
23350+ AuLabel(noverbose);
23351+ break;
23352+ case Opt_sum:
23353+ AuLabel(sum);
23354+ break;
23355+ case Opt_nosum:
23356+ AuLabel(nosum);
23357+ break;
23358+ case Opt_wsum:
23359+ AuLabel(wsum);
23360+ break;
23361+ case Opt_wbr_create:
23362+ u.create = &opt->wbr_create;
23363+ AuDbg("create %d, %s\n", u.create->wbr_create,
23364+ au_optstr_wbr_create(u.create->wbr_create));
23365+ switch (u.create->wbr_create) {
23366+ case AuWbrCreate_MFSV:
23367+ case AuWbrCreate_PMFSV:
23368+ AuDbg("%d sec\n", u.create->mfs_second);
23369+ break;
23370+ case AuWbrCreate_MFSRR:
23371+ AuDbg("%llu watermark\n",
23372+ u.create->mfsrr_watermark);
23373+ break;
23374+ case AuWbrCreate_MFSRRV:
392086de 23375+ case AuWbrCreate_PMFSRRV:
1facf9fc 23376+ AuDbg("%llu watermark, %d sec\n",
23377+ u.create->mfsrr_watermark,
23378+ u.create->mfs_second);
23379+ break;
23380+ }
23381+ break;
23382+ case Opt_wbr_copyup:
23383+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
23384+ au_optstr_wbr_copyup(opt->wbr_copyup));
23385+ break;
076b876e
AM
23386+ case Opt_fhsm_sec:
23387+ AuDbg("fhsm_sec %u\n", opt->fhsm_second);
23388+ break;
c1595e42
JR
23389+ case Opt_acl:
23390+ AuLabel(acl);
23391+ break;
23392+ case Opt_noacl:
23393+ AuLabel(noacl);
23394+ break;
1facf9fc 23395+ default:
23396+ BUG();
23397+ }
23398+ opt++;
23399+ }
23400+#endif
23401+}
23402+
23403+void au_opts_free(struct au_opts *opts)
23404+{
23405+ struct au_opt *opt;
23406+
23407+ opt = opts->opt;
23408+ while (opt->type != Opt_tail) {
23409+ switch (opt->type) {
23410+ case Opt_add:
23411+ case Opt_append:
23412+ case Opt_prepend:
23413+ path_put(&opt->add.path);
23414+ break;
23415+ case Opt_del:
23416+ case Opt_idel:
23417+ path_put(&opt->del.h_path);
23418+ break;
23419+ case Opt_mod:
23420+ case Opt_imod:
23421+ dput(opt->mod.h_root);
23422+ break;
23423+ case Opt_xino:
23424+ fput(opt->xino.file);
23425+ break;
23426+ }
23427+ opt++;
23428+ }
23429+}
23430+
23431+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
23432+ aufs_bindex_t bindex)
23433+{
23434+ int err;
23435+ struct au_opt_add *add = &opt->add;
23436+ char *p;
23437+
23438+ add->bindex = bindex;
1e00d052 23439+ add->perm = AuBrPerm_RO;
1facf9fc 23440+ add->pathname = opt_str;
23441+ p = strchr(opt_str, '=');
23442+ if (p) {
23443+ *p++ = 0;
23444+ if (*p)
23445+ add->perm = br_perm_val(p);
23446+ }
23447+
23448+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
23449+ if (!err) {
23450+ if (!p) {
23451+ add->perm = AuBrPerm_RO;
23452+ if (au_test_fs_rr(add->path.dentry->d_sb))
23453+ add->perm = AuBrPerm_RR;
23454+ else if (!bindex && !(sb_flags & MS_RDONLY))
23455+ add->perm = AuBrPerm_RW;
23456+ }
23457+ opt->type = Opt_add;
23458+ goto out;
23459+ }
4a4d8108 23460+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 23461+ err = -EINVAL;
23462+
4f0767ce 23463+out:
1facf9fc 23464+ return err;
23465+}
23466+
23467+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
23468+{
23469+ int err;
23470+
23471+ del->pathname = args[0].from;
23472+ AuDbg("del path %s\n", del->pathname);
23473+
23474+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
23475+ if (unlikely(err))
4a4d8108 23476+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 23477+
23478+ return err;
23479+}
23480+
23481+#if 0 /* reserved for future use */
23482+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
23483+ struct au_opt_del *del, substring_t args[])
23484+{
23485+ int err;
23486+ struct dentry *root;
23487+
23488+ err = -EINVAL;
23489+ root = sb->s_root;
23490+ aufs_read_lock(root, AuLock_FLUSH);
23491+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 23492+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 23493+ goto out;
23494+ }
23495+
23496+ err = 0;
23497+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
23498+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
23499+
4f0767ce 23500+out:
1facf9fc 23501+ aufs_read_unlock(root, !AuLock_IR);
23502+ return err;
23503+}
23504+#endif
23505+
4a4d8108
AM
23506+static int noinline_for_stack
23507+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 23508+{
23509+ int err;
23510+ struct path path;
23511+ char *p;
23512+
23513+ err = -EINVAL;
23514+ mod->path = args[0].from;
23515+ p = strchr(mod->path, '=');
23516+ if (unlikely(!p)) {
4a4d8108 23517+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 23518+ goto out;
23519+ }
23520+
23521+ *p++ = 0;
23522+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
23523+ if (unlikely(err)) {
4a4d8108 23524+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 23525+ goto out;
23526+ }
23527+
23528+ mod->perm = br_perm_val(p);
23529+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
23530+ mod->h_root = dget(path.dentry);
23531+ path_put(&path);
23532+
4f0767ce 23533+out:
1facf9fc 23534+ return err;
23535+}
23536+
23537+#if 0 /* reserved for future use */
23538+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
23539+ struct au_opt_mod *mod, substring_t args[])
23540+{
23541+ int err;
23542+ struct dentry *root;
23543+
23544+ err = -EINVAL;
23545+ root = sb->s_root;
23546+ aufs_read_lock(root, AuLock_FLUSH);
23547+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 23548+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 23549+ goto out;
23550+ }
23551+
23552+ err = 0;
23553+ mod->perm = br_perm_val(args[1].from);
23554+ AuDbg("mod path %s, perm 0x%x, %s\n",
23555+ mod->path, mod->perm, args[1].from);
23556+ mod->h_root = dget(au_h_dptr(root, bindex));
23557+
4f0767ce 23558+out:
1facf9fc 23559+ aufs_read_unlock(root, !AuLock_IR);
23560+ return err;
23561+}
23562+#endif
23563+
23564+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
23565+ substring_t args[])
23566+{
23567+ int err;
23568+ struct file *file;
23569+
23570+ file = au_xino_create(sb, args[0].from, /*silent*/0);
23571+ err = PTR_ERR(file);
23572+ if (IS_ERR(file))
23573+ goto out;
23574+
23575+ err = -EINVAL;
2000de60 23576+ if (unlikely(file->f_path.dentry->d_sb == sb)) {
1facf9fc 23577+ fput(file);
4a4d8108 23578+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 23579+ goto out;
23580+ }
23581+
23582+ err = 0;
23583+ xino->file = file;
23584+ xino->path = args[0].from;
23585+
4f0767ce 23586+out:
1facf9fc 23587+ return err;
23588+}
23589+
4a4d8108
AM
23590+static int noinline_for_stack
23591+au_opts_parse_xino_itrunc_path(struct super_block *sb,
23592+ struct au_opt_xino_itrunc *xino_itrunc,
23593+ substring_t args[])
1facf9fc 23594+{
23595+ int err;
23596+ aufs_bindex_t bend, bindex;
23597+ struct path path;
23598+ struct dentry *root;
23599+
23600+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
23601+ if (unlikely(err)) {
4a4d8108 23602+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 23603+ goto out;
23604+ }
23605+
23606+ xino_itrunc->bindex = -1;
23607+ root = sb->s_root;
23608+ aufs_read_lock(root, AuLock_FLUSH);
23609+ bend = au_sbend(sb);
23610+ for (bindex = 0; bindex <= bend; bindex++) {
23611+ if (au_h_dptr(root, bindex) == path.dentry) {
23612+ xino_itrunc->bindex = bindex;
23613+ break;
23614+ }
23615+ }
23616+ aufs_read_unlock(root, !AuLock_IR);
23617+ path_put(&path);
23618+
23619+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 23620+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 23621+ err = -EINVAL;
23622+ }
23623+
4f0767ce 23624+out:
1facf9fc 23625+ return err;
23626+}
23627+
23628+/* called without aufs lock */
23629+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
23630+{
23631+ int err, n, token;
23632+ aufs_bindex_t bindex;
23633+ unsigned char skipped;
23634+ struct dentry *root;
23635+ struct au_opt *opt, *opt_tail;
23636+ char *opt_str;
23637+ /* reduce the stack space */
23638+ union {
23639+ struct au_opt_xino_itrunc *xino_itrunc;
23640+ struct au_opt_wbr_create *create;
23641+ } u;
23642+ struct {
23643+ substring_t args[MAX_OPT_ARGS];
23644+ } *a;
23645+
23646+ err = -ENOMEM;
23647+ a = kmalloc(sizeof(*a), GFP_NOFS);
23648+ if (unlikely(!a))
23649+ goto out;
23650+
23651+ root = sb->s_root;
23652+ err = 0;
23653+ bindex = 0;
23654+ opt = opts->opt;
23655+ opt_tail = opt + opts->max_opt - 1;
23656+ opt->type = Opt_tail;
23657+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
23658+ err = -EINVAL;
23659+ skipped = 0;
23660+ token = match_token(opt_str, options, a->args);
23661+ switch (token) {
23662+ case Opt_br:
23663+ err = 0;
23664+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
23665+ && *opt_str) {
23666+ err = opt_add(opt, opt_str, opts->sb_flags,
23667+ bindex++);
23668+ if (unlikely(!err && ++opt > opt_tail)) {
23669+ err = -E2BIG;
23670+ break;
23671+ }
23672+ opt->type = Opt_tail;
23673+ skipped = 1;
23674+ }
23675+ break;
23676+ case Opt_add:
23677+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23678+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23679+ break;
23680+ }
23681+ bindex = n;
23682+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
23683+ bindex);
23684+ if (!err)
23685+ opt->type = token;
23686+ break;
23687+ case Opt_append:
23688+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
23689+ /*dummy bindex*/1);
23690+ if (!err)
23691+ opt->type = token;
23692+ break;
23693+ case Opt_prepend:
23694+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
23695+ /*bindex*/0);
23696+ if (!err)
23697+ opt->type = token;
23698+ break;
23699+ case Opt_del:
23700+ err = au_opts_parse_del(&opt->del, a->args);
23701+ if (!err)
23702+ opt->type = token;
23703+ break;
23704+#if 0 /* reserved for future use */
23705+ case Opt_idel:
23706+ del->pathname = "(indexed)";
23707+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 23708+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23709+ break;
23710+ }
23711+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
23712+ if (!err)
23713+ opt->type = token;
23714+ break;
23715+#endif
23716+ case Opt_mod:
23717+ err = au_opts_parse_mod(&opt->mod, a->args);
23718+ if (!err)
23719+ opt->type = token;
23720+ break;
23721+#ifdef IMOD /* reserved for future use */
23722+ case Opt_imod:
23723+ u.mod->path = "(indexed)";
23724+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23725+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23726+ break;
23727+ }
23728+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
23729+ if (!err)
23730+ opt->type = token;
23731+ break;
23732+#endif
23733+ case Opt_xino:
23734+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
23735+ if (!err)
23736+ opt->type = token;
23737+ break;
23738+
23739+ case Opt_trunc_xino_path:
23740+ err = au_opts_parse_xino_itrunc_path
23741+ (sb, &opt->xino_itrunc, a->args);
23742+ if (!err)
23743+ opt->type = token;
23744+ break;
23745+
23746+ case Opt_itrunc_xino:
23747+ u.xino_itrunc = &opt->xino_itrunc;
23748+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23749+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23750+ break;
23751+ }
23752+ u.xino_itrunc->bindex = n;
23753+ aufs_read_lock(root, AuLock_FLUSH);
23754+ if (n < 0 || au_sbend(sb) < n) {
4a4d8108 23755+ pr_err("out of bounds, %d\n", n);
1facf9fc 23756+ aufs_read_unlock(root, !AuLock_IR);
23757+ break;
23758+ }
23759+ aufs_read_unlock(root, !AuLock_IR);
23760+ err = 0;
23761+ opt->type = token;
23762+ break;
23763+
23764+ case Opt_dirwh:
23765+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
23766+ break;
23767+ err = 0;
23768+ opt->type = token;
23769+ break;
23770+
23771+ case Opt_rdcache:
027c5e7a
AM
23772+ if (unlikely(match_int(&a->args[0], &n))) {
23773+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23774+ break;
027c5e7a
AM
23775+ }
23776+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
23777+ pr_err("rdcache must be smaller than %d\n",
23778+ AUFS_RDCACHE_MAX);
23779+ break;
23780+ }
23781+ opt->rdcache = n;
1facf9fc 23782+ err = 0;
23783+ opt->type = token;
23784+ break;
23785+ case Opt_rdblk:
23786+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 23787+ || n < 0
1facf9fc 23788+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 23789+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23790+ break;
23791+ }
1308ab2a 23792+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
23793+ pr_err("rdblk must be larger than %d\n",
23794+ NAME_MAX);
1facf9fc 23795+ break;
23796+ }
23797+ opt->rdblk = n;
23798+ err = 0;
23799+ opt->type = token;
23800+ break;
23801+ case Opt_rdhash:
23802+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 23803+ || n < 0
1facf9fc 23804+ || n * sizeof(struct hlist_head)
23805+ > KMALLOC_MAX_SIZE)) {
4a4d8108 23806+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23807+ break;
23808+ }
23809+ opt->rdhash = n;
23810+ err = 0;
23811+ opt->type = token;
23812+ break;
23813+
23814+ case Opt_trunc_xino:
23815+ case Opt_notrunc_xino:
23816+ case Opt_noxino:
23817+ case Opt_trunc_xib:
23818+ case Opt_notrunc_xib:
dece6358
AM
23819+ case Opt_shwh:
23820+ case Opt_noshwh:
076b876e
AM
23821+ case Opt_dirperm1:
23822+ case Opt_nodirperm1:
1facf9fc 23823+ case Opt_plink:
23824+ case Opt_noplink:
23825+ case Opt_list_plink:
4a4d8108
AM
23826+ case Opt_dio:
23827+ case Opt_nodio:
1facf9fc 23828+ case Opt_diropq_a:
23829+ case Opt_diropq_w:
23830+ case Opt_warn_perm:
23831+ case Opt_nowarn_perm:
1facf9fc 23832+ case Opt_verbose:
23833+ case Opt_noverbose:
23834+ case Opt_sum:
23835+ case Opt_nosum:
23836+ case Opt_wsum:
dece6358
AM
23837+ case Opt_rdblk_def:
23838+ case Opt_rdhash_def:
c1595e42
JR
23839+ case Opt_acl:
23840+ case Opt_noacl:
1facf9fc 23841+ err = 0;
23842+ opt->type = token;
23843+ break;
23844+
23845+ case Opt_udba:
23846+ opt->udba = udba_val(a->args[0].from);
23847+ if (opt->udba >= 0) {
23848+ err = 0;
23849+ opt->type = token;
23850+ } else
4a4d8108 23851+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23852+ break;
23853+
23854+ case Opt_wbr_create:
23855+ u.create = &opt->wbr_create;
23856+ u.create->wbr_create
23857+ = au_wbr_create_val(a->args[0].from, u.create);
23858+ if (u.create->wbr_create >= 0) {
23859+ err = 0;
23860+ opt->type = token;
23861+ } else
4a4d8108 23862+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23863+ break;
23864+ case Opt_wbr_copyup:
23865+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
23866+ if (opt->wbr_copyup >= 0) {
23867+ err = 0;
23868+ opt->type = token;
23869+ } else
4a4d8108 23870+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23871+ break;
23872+
076b876e
AM
23873+ case Opt_fhsm_sec:
23874+ if (unlikely(match_int(&a->args[0], &n)
23875+ || n < 0)) {
23876+ pr_err("bad integer in %s\n", opt_str);
23877+ break;
23878+ }
23879+ if (sysaufs_brs) {
23880+ opt->fhsm_second = n;
23881+ opt->type = token;
23882+ } else
23883+ pr_warn("ignored %s\n", opt_str);
23884+ err = 0;
23885+ break;
23886+
1facf9fc 23887+ case Opt_ignore:
0c3ec466 23888+ pr_warn("ignored %s\n", opt_str);
1facf9fc 23889+ /*FALLTHROUGH*/
23890+ case Opt_ignore_silent:
23891+ skipped = 1;
23892+ err = 0;
23893+ break;
23894+ case Opt_err:
4a4d8108 23895+ pr_err("unknown option %s\n", opt_str);
1facf9fc 23896+ break;
23897+ }
23898+
23899+ if (!err && !skipped) {
23900+ if (unlikely(++opt > opt_tail)) {
23901+ err = -E2BIG;
23902+ opt--;
23903+ opt->type = Opt_tail;
23904+ break;
23905+ }
23906+ opt->type = Opt_tail;
23907+ }
23908+ }
23909+
23910+ kfree(a);
23911+ dump_opts(opts);
23912+ if (unlikely(err))
23913+ au_opts_free(opts);
23914+
4f0767ce 23915+out:
1facf9fc 23916+ return err;
23917+}
23918+
23919+static int au_opt_wbr_create(struct super_block *sb,
23920+ struct au_opt_wbr_create *create)
23921+{
23922+ int err;
23923+ struct au_sbinfo *sbinfo;
23924+
dece6358
AM
23925+ SiMustWriteLock(sb);
23926+
1facf9fc 23927+ err = 1; /* handled */
23928+ sbinfo = au_sbi(sb);
23929+ if (sbinfo->si_wbr_create_ops->fin) {
23930+ err = sbinfo->si_wbr_create_ops->fin(sb);
23931+ if (!err)
23932+ err = 1;
23933+ }
23934+
23935+ sbinfo->si_wbr_create = create->wbr_create;
23936+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
23937+ switch (create->wbr_create) {
23938+ case AuWbrCreate_MFSRRV:
23939+ case AuWbrCreate_MFSRR:
392086de
AM
23940+ case AuWbrCreate_PMFSRR:
23941+ case AuWbrCreate_PMFSRRV:
1facf9fc 23942+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
23943+ /*FALLTHROUGH*/
23944+ case AuWbrCreate_MFS:
23945+ case AuWbrCreate_MFSV:
23946+ case AuWbrCreate_PMFS:
23947+ case AuWbrCreate_PMFSV:
e49829fe
JR
23948+ sbinfo->si_wbr_mfs.mfs_expire
23949+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 23950+ break;
23951+ }
23952+
23953+ if (sbinfo->si_wbr_create_ops->init)
23954+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
23955+
23956+ return err;
23957+}
23958+
23959+/*
23960+ * returns,
23961+ * plus: processed without an error
23962+ * zero: unprocessed
23963+ */
23964+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
23965+ struct au_opts *opts)
23966+{
23967+ int err;
23968+ struct au_sbinfo *sbinfo;
23969+
dece6358
AM
23970+ SiMustWriteLock(sb);
23971+
1facf9fc 23972+ err = 1; /* handled */
23973+ sbinfo = au_sbi(sb);
23974+ switch (opt->type) {
23975+ case Opt_udba:
23976+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
23977+ sbinfo->si_mntflags |= opt->udba;
23978+ opts->given_udba |= opt->udba;
23979+ break;
23980+
23981+ case Opt_plink:
23982+ au_opt_set(sbinfo->si_mntflags, PLINK);
23983+ break;
23984+ case Opt_noplink:
23985+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 23986+ au_plink_put(sb, /*verbose*/1);
1facf9fc 23987+ au_opt_clr(sbinfo->si_mntflags, PLINK);
23988+ break;
23989+ case Opt_list_plink:
23990+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
23991+ au_plink_list(sb);
23992+ break;
23993+
4a4d8108
AM
23994+ case Opt_dio:
23995+ au_opt_set(sbinfo->si_mntflags, DIO);
23996+ au_fset_opts(opts->flags, REFRESH_DYAOP);
23997+ break;
23998+ case Opt_nodio:
23999+ au_opt_clr(sbinfo->si_mntflags, DIO);
24000+ au_fset_opts(opts->flags, REFRESH_DYAOP);
24001+ break;
24002+
076b876e
AM
24003+ case Opt_fhsm_sec:
24004+ au_fhsm_set(sbinfo, opt->fhsm_second);
24005+ break;
24006+
1facf9fc 24007+ case Opt_diropq_a:
24008+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
24009+ break;
24010+ case Opt_diropq_w:
24011+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
24012+ break;
24013+
24014+ case Opt_warn_perm:
24015+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
24016+ break;
24017+ case Opt_nowarn_perm:
24018+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
24019+ break;
24020+
1facf9fc 24021+ case Opt_verbose:
24022+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
24023+ break;
24024+ case Opt_noverbose:
24025+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
24026+ break;
24027+
24028+ case Opt_sum:
24029+ au_opt_set(sbinfo->si_mntflags, SUM);
24030+ break;
24031+ case Opt_wsum:
24032+ au_opt_clr(sbinfo->si_mntflags, SUM);
24033+ au_opt_set(sbinfo->si_mntflags, SUM_W);
24034+ case Opt_nosum:
24035+ au_opt_clr(sbinfo->si_mntflags, SUM);
24036+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
24037+ break;
24038+
24039+ case Opt_wbr_create:
24040+ err = au_opt_wbr_create(sb, &opt->wbr_create);
24041+ break;
24042+ case Opt_wbr_copyup:
24043+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
24044+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
24045+ break;
24046+
24047+ case Opt_dirwh:
24048+ sbinfo->si_dirwh = opt->dirwh;
24049+ break;
24050+
24051+ case Opt_rdcache:
e49829fe
JR
24052+ sbinfo->si_rdcache
24053+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 24054+ break;
24055+ case Opt_rdblk:
24056+ sbinfo->si_rdblk = opt->rdblk;
24057+ break;
dece6358
AM
24058+ case Opt_rdblk_def:
24059+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
24060+ break;
1facf9fc 24061+ case Opt_rdhash:
24062+ sbinfo->si_rdhash = opt->rdhash;
24063+ break;
dece6358
AM
24064+ case Opt_rdhash_def:
24065+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
24066+ break;
24067+
24068+ case Opt_shwh:
24069+ au_opt_set(sbinfo->si_mntflags, SHWH);
24070+ break;
24071+ case Opt_noshwh:
24072+ au_opt_clr(sbinfo->si_mntflags, SHWH);
24073+ break;
1facf9fc 24074+
076b876e
AM
24075+ case Opt_dirperm1:
24076+ au_opt_set(sbinfo->si_mntflags, DIRPERM1);
24077+ break;
24078+ case Opt_nodirperm1:
24079+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
24080+ break;
24081+
1facf9fc 24082+ case Opt_trunc_xino:
24083+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
24084+ break;
24085+ case Opt_notrunc_xino:
24086+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
24087+ break;
24088+
24089+ case Opt_trunc_xino_path:
24090+ case Opt_itrunc_xino:
24091+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
24092+ if (!err)
24093+ err = 1;
24094+ break;
24095+
24096+ case Opt_trunc_xib:
24097+ au_fset_opts(opts->flags, TRUNC_XIB);
24098+ break;
24099+ case Opt_notrunc_xib:
24100+ au_fclr_opts(opts->flags, TRUNC_XIB);
24101+ break;
24102+
c1595e42
JR
24103+ case Opt_acl:
24104+ sb->s_flags |= MS_POSIXACL;
24105+ break;
24106+ case Opt_noacl:
24107+ sb->s_flags &= ~MS_POSIXACL;
24108+ break;
24109+
1facf9fc 24110+ default:
24111+ err = 0;
24112+ break;
24113+ }
24114+
24115+ return err;
24116+}
24117+
24118+/*
24119+ * returns tri-state.
24120+ * plus: processed without an error
24121+ * zero: unprocessed
24122+ * minus: error
24123+ */
24124+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
24125+ struct au_opts *opts)
24126+{
24127+ int err, do_refresh;
24128+
24129+ err = 0;
24130+ switch (opt->type) {
24131+ case Opt_append:
24132+ opt->add.bindex = au_sbend(sb) + 1;
24133+ if (opt->add.bindex < 0)
24134+ opt->add.bindex = 0;
24135+ goto add;
24136+ case Opt_prepend:
24137+ opt->add.bindex = 0;
f6b6e03d 24138+ add: /* indented label */
1facf9fc 24139+ case Opt_add:
24140+ err = au_br_add(sb, &opt->add,
24141+ au_ftest_opts(opts->flags, REMOUNT));
24142+ if (!err) {
24143+ err = 1;
027c5e7a 24144+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 24145+ }
24146+ break;
24147+
24148+ case Opt_del:
24149+ case Opt_idel:
24150+ err = au_br_del(sb, &opt->del,
24151+ au_ftest_opts(opts->flags, REMOUNT));
24152+ if (!err) {
24153+ err = 1;
24154+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 24155+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 24156+ }
24157+ break;
24158+
24159+ case Opt_mod:
24160+ case Opt_imod:
24161+ err = au_br_mod(sb, &opt->mod,
24162+ au_ftest_opts(opts->flags, REMOUNT),
24163+ &do_refresh);
24164+ if (!err) {
24165+ err = 1;
027c5e7a
AM
24166+ if (do_refresh)
24167+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 24168+ }
24169+ break;
24170+ }
24171+
24172+ return err;
24173+}
24174+
24175+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
24176+ struct au_opt_xino **opt_xino,
24177+ struct au_opts *opts)
24178+{
24179+ int err;
24180+ aufs_bindex_t bend, bindex;
24181+ struct dentry *root, *parent, *h_root;
24182+
24183+ err = 0;
24184+ switch (opt->type) {
24185+ case Opt_xino:
24186+ err = au_xino_set(sb, &opt->xino,
24187+ !!au_ftest_opts(opts->flags, REMOUNT));
24188+ if (unlikely(err))
24189+ break;
24190+
24191+ *opt_xino = &opt->xino;
24192+ au_xino_brid_set(sb, -1);
24193+
24194+ /* safe d_parent access */
2000de60 24195+ parent = opt->xino.file->f_path.dentry->d_parent;
1facf9fc 24196+ root = sb->s_root;
24197+ bend = au_sbend(sb);
24198+ for (bindex = 0; bindex <= bend; bindex++) {
24199+ h_root = au_h_dptr(root, bindex);
24200+ if (h_root == parent) {
24201+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
24202+ break;
24203+ }
24204+ }
24205+ break;
24206+
24207+ case Opt_noxino:
24208+ au_xino_clr(sb);
24209+ au_xino_brid_set(sb, -1);
24210+ *opt_xino = (void *)-1;
24211+ break;
24212+ }
24213+
24214+ return err;
24215+}
24216+
24217+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
24218+ unsigned int pending)
24219+{
076b876e 24220+ int err, fhsm;
1facf9fc 24221+ aufs_bindex_t bindex, bend;
79b8bda9 24222+ unsigned char do_plink, skip, do_free, can_no_dreval;
1facf9fc 24223+ struct au_branch *br;
24224+ struct au_wbr *wbr;
79b8bda9 24225+ struct dentry *root, *dentry;
1facf9fc 24226+ struct inode *dir, *h_dir;
24227+ struct au_sbinfo *sbinfo;
24228+ struct au_hinode *hdir;
24229+
dece6358
AM
24230+ SiMustAnyLock(sb);
24231+
1facf9fc 24232+ sbinfo = au_sbi(sb);
24233+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
24234+
dece6358
AM
24235+ if (!(sb_flags & MS_RDONLY)) {
24236+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 24237+ pr_warn("first branch should be rw\n");
dece6358 24238+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
0c3ec466 24239+ pr_warn("shwh should be used with ro\n");
dece6358 24240+ }
1facf9fc 24241+
4a4d8108 24242+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 24243+ && !au_opt_test(sbinfo->si_mntflags, XINO))
0c3ec466 24244+ pr_warn("udba=*notify requires xino\n");
1facf9fc 24245+
076b876e
AM
24246+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
24247+ pr_warn("dirperm1 breaks the protection"
24248+ " by the permission bits on the lower branch\n");
24249+
1facf9fc 24250+ err = 0;
076b876e 24251+ fhsm = 0;
1facf9fc 24252+ root = sb->s_root;
5527c038 24253+ dir = d_inode(root);
1facf9fc 24254+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
79b8bda9
AM
24255+ can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending),
24256+ UDBA_NONE);
1facf9fc 24257+ bend = au_sbend(sb);
24258+ for (bindex = 0; !err && bindex <= bend; bindex++) {
24259+ skip = 0;
24260+ h_dir = au_h_iptr(dir, bindex);
24261+ br = au_sbr(sb, bindex);
1facf9fc 24262+
c1595e42
JR
24263+ if ((br->br_perm & AuBrAttr_ICEX)
24264+ && !h_dir->i_op->listxattr)
24265+ br->br_perm &= ~AuBrAttr_ICEX;
24266+#if 0
24267+ if ((br->br_perm & AuBrAttr_ICEX_SEC)
24268+ && (au_br_sb(br)->s_flags & MS_NOSEC))
24269+ br->br_perm &= ~AuBrAttr_ICEX_SEC;
24270+#endif
24271+
24272+ do_free = 0;
1facf9fc 24273+ wbr = br->br_wbr;
24274+ if (wbr)
24275+ wbr_wh_read_lock(wbr);
24276+
1e00d052 24277+ if (!au_br_writable(br->br_perm)) {
1facf9fc 24278+ do_free = !!wbr;
24279+ skip = (!wbr
24280+ || (!wbr->wbr_whbase
24281+ && !wbr->wbr_plink
24282+ && !wbr->wbr_orph));
1e00d052 24283+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 24284+ /* skip = (!br->br_whbase && !br->br_orph); */
24285+ skip = (!wbr || !wbr->wbr_whbase);
24286+ if (skip && wbr) {
24287+ if (do_plink)
24288+ skip = !!wbr->wbr_plink;
24289+ else
24290+ skip = !wbr->wbr_plink;
24291+ }
1e00d052 24292+ } else {
1facf9fc 24293+ /* skip = (br->br_whbase && br->br_ohph); */
24294+ skip = (wbr && wbr->wbr_whbase);
24295+ if (skip) {
24296+ if (do_plink)
24297+ skip = !!wbr->wbr_plink;
24298+ else
24299+ skip = !wbr->wbr_plink;
24300+ }
1facf9fc 24301+ }
24302+ if (wbr)
24303+ wbr_wh_read_unlock(wbr);
24304+
79b8bda9
AM
24305+ if (can_no_dreval) {
24306+ dentry = br->br_path.dentry;
24307+ spin_lock(&dentry->d_lock);
24308+ if (dentry->d_flags &
24309+ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE))
24310+ can_no_dreval = 0;
24311+ spin_unlock(&dentry->d_lock);
24312+ }
24313+
076b876e
AM
24314+ if (au_br_fhsm(br->br_perm)) {
24315+ fhsm++;
24316+ AuDebugOn(!br->br_fhsm);
24317+ }
24318+
1facf9fc 24319+ if (skip)
24320+ continue;
24321+
24322+ hdir = au_hi(dir, bindex);
4a4d8108 24323+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 24324+ if (wbr)
24325+ wbr_wh_write_lock(wbr);
86dc4139 24326+ err = au_wh_init(br, sb);
1facf9fc 24327+ if (wbr)
24328+ wbr_wh_write_unlock(wbr);
4a4d8108 24329+ au_hn_imtx_unlock(hdir);
1facf9fc 24330+
24331+ if (!err && do_free) {
24332+ kfree(wbr);
24333+ br->br_wbr = NULL;
24334+ }
24335+ }
24336+
79b8bda9
AM
24337+ if (can_no_dreval)
24338+ au_fset_si(sbinfo, NO_DREVAL);
24339+ else
24340+ au_fclr_si(sbinfo, NO_DREVAL);
24341+
c1595e42 24342+ if (fhsm >= 2) {
076b876e 24343+ au_fset_si(sbinfo, FHSM);
c1595e42
JR
24344+ for (bindex = bend; bindex >= 0; bindex--) {
24345+ br = au_sbr(sb, bindex);
24346+ if (au_br_fhsm(br->br_perm)) {
24347+ au_fhsm_set_bottom(sb, bindex);
24348+ break;
24349+ }
24350+ }
24351+ } else {
076b876e 24352+ au_fclr_si(sbinfo, FHSM);
c1595e42
JR
24353+ au_fhsm_set_bottom(sb, -1);
24354+ }
076b876e 24355+
1facf9fc 24356+ return err;
24357+}
24358+
24359+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
24360+{
24361+ int err;
24362+ unsigned int tmp;
027c5e7a 24363+ aufs_bindex_t bindex, bend;
1facf9fc 24364+ struct au_opt *opt;
24365+ struct au_opt_xino *opt_xino, xino;
24366+ struct au_sbinfo *sbinfo;
027c5e7a 24367+ struct au_branch *br;
076b876e 24368+ struct inode *dir;
1facf9fc 24369+
dece6358
AM
24370+ SiMustWriteLock(sb);
24371+
1facf9fc 24372+ err = 0;
24373+ opt_xino = NULL;
24374+ opt = opts->opt;
24375+ while (err >= 0 && opt->type != Opt_tail)
24376+ err = au_opt_simple(sb, opt++, opts);
24377+ if (err > 0)
24378+ err = 0;
24379+ else if (unlikely(err < 0))
24380+ goto out;
24381+
24382+ /* disable xino and udba temporary */
24383+ sbinfo = au_sbi(sb);
24384+ tmp = sbinfo->si_mntflags;
24385+ au_opt_clr(sbinfo->si_mntflags, XINO);
24386+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
24387+
24388+ opt = opts->opt;
24389+ while (err >= 0 && opt->type != Opt_tail)
24390+ err = au_opt_br(sb, opt++, opts);
24391+ if (err > 0)
24392+ err = 0;
24393+ else if (unlikely(err < 0))
24394+ goto out;
24395+
24396+ bend = au_sbend(sb);
24397+ if (unlikely(bend < 0)) {
24398+ err = -EINVAL;
4a4d8108 24399+ pr_err("no branches\n");
1facf9fc 24400+ goto out;
24401+ }
24402+
24403+ if (au_opt_test(tmp, XINO))
24404+ au_opt_set(sbinfo->si_mntflags, XINO);
24405+ opt = opts->opt;
24406+ while (!err && opt->type != Opt_tail)
24407+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
24408+ if (unlikely(err))
24409+ goto out;
24410+
24411+ err = au_opts_verify(sb, sb->s_flags, tmp);
24412+ if (unlikely(err))
24413+ goto out;
24414+
24415+ /* restore xino */
24416+ if (au_opt_test(tmp, XINO) && !opt_xino) {
24417+ xino.file = au_xino_def(sb);
24418+ err = PTR_ERR(xino.file);
24419+ if (IS_ERR(xino.file))
24420+ goto out;
24421+
24422+ err = au_xino_set(sb, &xino, /*remount*/0);
24423+ fput(xino.file);
24424+ if (unlikely(err))
24425+ goto out;
24426+ }
24427+
24428+ /* restore udba */
027c5e7a 24429+ tmp &= AuOptMask_UDBA;
1facf9fc 24430+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a
AM
24431+ sbinfo->si_mntflags |= tmp;
24432+ bend = au_sbend(sb);
24433+ for (bindex = 0; bindex <= bend; bindex++) {
24434+ br = au_sbr(sb, bindex);
24435+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
24436+ if (unlikely(err))
24437+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
24438+ bindex, err);
24439+ /* go on even if err */
24440+ }
4a4d8108 24441+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
5527c038 24442+ dir = d_inode(sb->s_root);
4a4d8108 24443+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 24444+ }
24445+
4f0767ce 24446+out:
1facf9fc 24447+ return err;
24448+}
24449+
24450+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
24451+{
24452+ int err, rerr;
79b8bda9 24453+ unsigned char no_dreval;
1facf9fc 24454+ struct inode *dir;
24455+ struct au_opt_xino *opt_xino;
24456+ struct au_opt *opt;
24457+ struct au_sbinfo *sbinfo;
24458+
dece6358
AM
24459+ SiMustWriteLock(sb);
24460+
79b8bda9 24461+ err = 0;
5527c038 24462+ dir = d_inode(sb->s_root);
1facf9fc 24463+ sbinfo = au_sbi(sb);
1facf9fc 24464+ opt_xino = NULL;
24465+ opt = opts->opt;
24466+ while (err >= 0 && opt->type != Opt_tail) {
24467+ err = au_opt_simple(sb, opt, opts);
24468+ if (!err)
24469+ err = au_opt_br(sb, opt, opts);
24470+ if (!err)
24471+ err = au_opt_xino(sb, opt, &opt_xino, opts);
24472+ opt++;
24473+ }
24474+ if (err > 0)
24475+ err = 0;
24476+ AuTraceErr(err);
24477+ /* go on even err */
24478+
79b8bda9 24479+ no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
1facf9fc 24480+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
24481+ if (unlikely(rerr && !err))
24482+ err = rerr;
24483+
79b8bda9
AM
24484+ if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
24485+ au_fset_opts(opts->flags, REFRESH_DOP);
24486+
1facf9fc 24487+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
24488+ rerr = au_xib_trunc(sb);
24489+ if (unlikely(rerr && !err))
24490+ err = rerr;
24491+ }
24492+
24493+ /* will be handled by the caller */
027c5e7a 24494+ if (!au_ftest_opts(opts->flags, REFRESH)
79b8bda9
AM
24495+ && (opts->given_udba
24496+ || au_opt_test(sbinfo->si_mntflags, XINO)
24497+ || au_ftest_opts(opts->flags, REFRESH_DOP)
24498+ ))
027c5e7a 24499+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 24500+
24501+ AuDbg("status 0x%x\n", opts->flags);
24502+ return err;
24503+}
24504+
24505+/* ---------------------------------------------------------------------- */
24506+
24507+unsigned int au_opt_udba(struct super_block *sb)
24508+{
24509+ return au_mntflags(sb) & AuOptMask_UDBA;
24510+}
7f207e10
AM
24511diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
24512--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
24513+++ linux/fs/aufs/opts.h 2015-11-11 17:21:46.918863802 +0100
24514@@ -0,0 +1,211 @@
1facf9fc 24515+/*
2000de60 24516+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 24517+ *
24518+ * This program, aufs is free software; you can redistribute it and/or modify
24519+ * it under the terms of the GNU General Public License as published by
24520+ * the Free Software Foundation; either version 2 of the License, or
24521+ * (at your option) any later version.
dece6358
AM
24522+ *
24523+ * This program is distributed in the hope that it will be useful,
24524+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24525+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24526+ * GNU General Public License for more details.
24527+ *
24528+ * You should have received a copy of the GNU General Public License
523b37e3 24529+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24530+ */
24531+
24532+/*
24533+ * mount options/flags
24534+ */
24535+
24536+#ifndef __AUFS_OPTS_H__
24537+#define __AUFS_OPTS_H__
24538+
24539+#ifdef __KERNEL__
24540+
dece6358 24541+#include <linux/path.h>
1facf9fc 24542+
dece6358
AM
24543+struct file;
24544+struct super_block;
24545+
1facf9fc 24546+/* ---------------------------------------------------------------------- */
24547+
24548+/* mount flags */
24549+#define AuOpt_XINO 1 /* external inode number bitmap
24550+ and translation table */
24551+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
24552+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
24553+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 24554+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
24555+#define AuOpt_SHWH (1 << 5) /* show whiteout */
24556+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
076b876e
AM
24557+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
24558+ bits */
dece6358
AM
24559+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
24560+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
24561+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
24562+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
24563+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 24564+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 24565+
4a4d8108
AM
24566+#ifndef CONFIG_AUFS_HNOTIFY
24567+#undef AuOpt_UDBA_HNOTIFY
24568+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 24569+#endif
dece6358
AM
24570+#ifndef CONFIG_AUFS_SHWH
24571+#undef AuOpt_SHWH
24572+#define AuOpt_SHWH 0
24573+#endif
1facf9fc 24574+
24575+#define AuOpt_Def (AuOpt_XINO \
24576+ | AuOpt_UDBA_REVAL \
24577+ | AuOpt_PLINK \
24578+ /* | AuOpt_DIRPERM1 */ \
24579+ | AuOpt_WARN_PERM)
24580+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
24581+ | AuOpt_UDBA_REVAL \
4a4d8108 24582+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 24583+
24584+#define au_opt_test(flags, name) (flags & AuOpt_##name)
24585+#define au_opt_set(flags, name) do { \
24586+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
24587+ ((flags) |= AuOpt_##name); \
24588+} while (0)
24589+#define au_opt_set_udba(flags, name) do { \
24590+ (flags) &= ~AuOptMask_UDBA; \
24591+ ((flags) |= AuOpt_##name); \
24592+} while (0)
7f207e10
AM
24593+#define au_opt_clr(flags, name) do { \
24594+ ((flags) &= ~AuOpt_##name); \
24595+} while (0)
1facf9fc 24596+
e49829fe
JR
24597+static inline unsigned int au_opts_plink(unsigned int mntflags)
24598+{
24599+#ifdef CONFIG_PROC_FS
24600+ return mntflags;
24601+#else
24602+ return mntflags & ~AuOpt_PLINK;
24603+#endif
24604+}
24605+
1facf9fc 24606+/* ---------------------------------------------------------------------- */
24607+
24608+/* policies to select one among multiple writable branches */
24609+enum {
24610+ AuWbrCreate_TDP, /* top down parent */
24611+ AuWbrCreate_RR, /* round robin */
24612+ AuWbrCreate_MFS, /* most free space */
24613+ AuWbrCreate_MFSV, /* mfs with seconds */
24614+ AuWbrCreate_MFSRR, /* mfs then rr */
24615+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
24616+ AuWbrCreate_PMFS, /* parent and mfs */
24617+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
24618+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
24619+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 24620+
24621+ AuWbrCreate_Def = AuWbrCreate_TDP
24622+};
24623+
24624+enum {
24625+ AuWbrCopyup_TDP, /* top down parent */
24626+ AuWbrCopyup_BUP, /* bottom up parent */
24627+ AuWbrCopyup_BU, /* bottom up */
24628+
24629+ AuWbrCopyup_Def = AuWbrCopyup_TDP
24630+};
24631+
24632+/* ---------------------------------------------------------------------- */
24633+
24634+struct au_opt_add {
24635+ aufs_bindex_t bindex;
24636+ char *pathname;
24637+ int perm;
24638+ struct path path;
24639+};
24640+
24641+struct au_opt_del {
24642+ char *pathname;
24643+ struct path h_path;
24644+};
24645+
24646+struct au_opt_mod {
24647+ char *path;
24648+ int perm;
24649+ struct dentry *h_root;
24650+};
24651+
24652+struct au_opt_xino {
24653+ char *path;
24654+ struct file *file;
24655+};
24656+
24657+struct au_opt_xino_itrunc {
24658+ aufs_bindex_t bindex;
24659+};
24660+
24661+struct au_opt_wbr_create {
24662+ int wbr_create;
24663+ int mfs_second;
24664+ unsigned long long mfsrr_watermark;
24665+};
24666+
24667+struct au_opt {
24668+ int type;
24669+ union {
24670+ struct au_opt_xino xino;
24671+ struct au_opt_xino_itrunc xino_itrunc;
24672+ struct au_opt_add add;
24673+ struct au_opt_del del;
24674+ struct au_opt_mod mod;
24675+ int dirwh;
24676+ int rdcache;
24677+ unsigned int rdblk;
24678+ unsigned int rdhash;
24679+ int udba;
24680+ struct au_opt_wbr_create wbr_create;
24681+ int wbr_copyup;
076b876e 24682+ unsigned int fhsm_second;
1facf9fc 24683+ };
24684+};
24685+
24686+/* opts flags */
24687+#define AuOpts_REMOUNT 1
027c5e7a
AM
24688+#define AuOpts_REFRESH (1 << 1)
24689+#define AuOpts_TRUNC_XIB (1 << 2)
24690+#define AuOpts_REFRESH_DYAOP (1 << 3)
79b8bda9 24691+#define AuOpts_REFRESH_DOP (1 << 4)
1facf9fc 24692+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
24693+#define au_fset_opts(flags, name) \
24694+ do { (flags) |= AuOpts_##name; } while (0)
24695+#define au_fclr_opts(flags, name) \
24696+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 24697+
24698+struct au_opts {
24699+ struct au_opt *opt;
24700+ int max_opt;
24701+
24702+ unsigned int given_udba;
24703+ unsigned int flags;
24704+ unsigned long sb_flags;
24705+};
24706+
24707+/* ---------------------------------------------------------------------- */
24708+
7e9cd9fe 24709+/* opts.c */
076b876e 24710+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
1facf9fc 24711+const char *au_optstr_udba(int udba);
24712+const char *au_optstr_wbr_copyup(int wbr_copyup);
24713+const char *au_optstr_wbr_create(int wbr_create);
24714+
24715+void au_opts_free(struct au_opts *opts);
24716+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
24717+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
24718+ unsigned int pending);
24719+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
24720+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
24721+
24722+unsigned int au_opt_udba(struct super_block *sb);
24723+
1facf9fc 24724+#endif /* __KERNEL__ */
24725+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
24726diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
24727--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 24728+++ linux/fs/aufs/plink.c 2015-09-24 10:47:58.254719746 +0200
5527c038 24729@@ -0,0 +1,528 @@
1facf9fc 24730+/*
2000de60 24731+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 24732+ *
24733+ * This program, aufs is free software; you can redistribute it and/or modify
24734+ * it under the terms of the GNU General Public License as published by
24735+ * the Free Software Foundation; either version 2 of the License, or
24736+ * (at your option) any later version.
dece6358
AM
24737+ *
24738+ * This program is distributed in the hope that it will be useful,
24739+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24740+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24741+ * GNU General Public License for more details.
24742+ *
24743+ * You should have received a copy of the GNU General Public License
523b37e3 24744+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24745+ */
24746+
24747+/*
24748+ * pseudo-link
24749+ */
24750+
24751+#include "aufs.h"
24752+
24753+/*
e49829fe 24754+ * the pseudo-link maintenance mode.
1facf9fc 24755+ * during a user process maintains the pseudo-links,
24756+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
24757+ *
24758+ * Flags
24759+ * NOPLM:
24760+ * For entry functions which will handle plink, and i_mutex is already held
24761+ * in VFS.
24762+ * They cannot wait and should return an error at once.
24763+ * Callers has to check the error.
24764+ * NOPLMW:
24765+ * For entry functions which will handle plink, but i_mutex is not held
24766+ * in VFS.
24767+ * They can wait the plink maintenance mode to finish.
24768+ *
24769+ * They behave like F_SETLK and F_SETLKW.
24770+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 24771+ */
e49829fe
JR
24772+
24773+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 24774+{
e49829fe
JR
24775+ int err;
24776+ pid_t pid, ppid;
24777+ struct au_sbinfo *sbi;
dece6358
AM
24778+
24779+ SiMustAnyLock(sb);
24780+
e49829fe
JR
24781+ err = 0;
24782+ if (!au_opt_test(au_mntflags(sb), PLINK))
24783+ goto out;
24784+
24785+ sbi = au_sbi(sb);
24786+ pid = sbi->si_plink_maint_pid;
24787+ if (!pid || pid == current->pid)
24788+ goto out;
24789+
24790+ /* todo: it highly depends upon /sbin/mount.aufs */
24791+ rcu_read_lock();
24792+ ppid = task_pid_vnr(rcu_dereference(current->real_parent));
24793+ rcu_read_unlock();
24794+ if (pid == ppid)
24795+ goto out;
24796+
24797+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
24798+ /* if there is no i_mutex lock in VFS, we don't need to wait */
24799+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
24800+ while (sbi->si_plink_maint_pid) {
24801+ si_read_unlock(sb);
24802+ /* gave up wake_up_bit() */
24803+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
24804+
24805+ if (au_ftest_lock(flags, FLUSH))
24806+ au_nwt_flush(&sbi->si_nowait);
24807+ si_noflush_read_lock(sb);
24808+ }
24809+ } else if (au_ftest_lock(flags, NOPLM)) {
24810+ AuDbg("ppid %d, pid %d\n", ppid, pid);
24811+ err = -EAGAIN;
24812+ }
24813+
24814+out:
24815+ return err;
4a4d8108
AM
24816+}
24817+
e49829fe 24818+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 24819+{
4a4d8108 24820+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 24821+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 24822+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 24823+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
24824+}
24825+
e49829fe 24826+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
24827+{
24828+ int err;
4a4d8108
AM
24829+ struct au_sbinfo *sbinfo;
24830+
24831+ err = 0;
4a4d8108
AM
24832+ sbinfo = au_sbi(sb);
24833+ /* make sure i am the only one in this fs */
e49829fe
JR
24834+ si_write_lock(sb, AuLock_FLUSH);
24835+ if (au_opt_test(au_mntflags(sb), PLINK)) {
24836+ spin_lock(&sbinfo->si_plink_maint_lock);
24837+ if (!sbinfo->si_plink_maint_pid)
24838+ sbinfo->si_plink_maint_pid = current->pid;
24839+ else
24840+ err = -EBUSY;
24841+ spin_unlock(&sbinfo->si_plink_maint_lock);
24842+ }
4a4d8108
AM
24843+ si_write_unlock(sb);
24844+
24845+ return err;
1facf9fc 24846+}
24847+
24848+/* ---------------------------------------------------------------------- */
24849+
1facf9fc 24850+#ifdef CONFIG_AUFS_DEBUG
24851+void au_plink_list(struct super_block *sb)
24852+{
86dc4139 24853+ int i;
1facf9fc 24854+ struct au_sbinfo *sbinfo;
86dc4139 24855+ struct hlist_head *plink_hlist;
1facf9fc 24856+ struct pseudo_link *plink;
24857+
dece6358
AM
24858+ SiMustAnyLock(sb);
24859+
1facf9fc 24860+ sbinfo = au_sbi(sb);
24861+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24862+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24863+
86dc4139
AM
24864+ for (i = 0; i < AuPlink_NHASH; i++) {
24865+ plink_hlist = &sbinfo->si_plink[i].head;
24866+ rcu_read_lock();
24867+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
24868+ AuDbg("%lu\n", plink->inode->i_ino);
24869+ rcu_read_unlock();
24870+ }
1facf9fc 24871+}
24872+#endif
24873+
24874+/* is the inode pseudo-linked? */
24875+int au_plink_test(struct inode *inode)
24876+{
86dc4139 24877+ int found, i;
1facf9fc 24878+ struct au_sbinfo *sbinfo;
86dc4139 24879+ struct hlist_head *plink_hlist;
1facf9fc 24880+ struct pseudo_link *plink;
24881+
24882+ sbinfo = au_sbi(inode->i_sb);
dece6358 24883+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 24884+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 24885+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 24886+
24887+ found = 0;
86dc4139
AM
24888+ i = au_plink_hash(inode->i_ino);
24889+ plink_hlist = &sbinfo->si_plink[i].head;
4a4d8108 24890+ rcu_read_lock();
86dc4139 24891+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
1facf9fc 24892+ if (plink->inode == inode) {
24893+ found = 1;
24894+ break;
24895+ }
4a4d8108 24896+ rcu_read_unlock();
1facf9fc 24897+ return found;
24898+}
24899+
24900+/* ---------------------------------------------------------------------- */
24901+
24902+/*
24903+ * generate a name for plink.
24904+ * the file will be stored under AUFS_WH_PLINKDIR.
24905+ */
24906+/* 20 is max digits length of ulong 64 */
24907+#define PLINK_NAME_LEN ((20 + 1) * 2)
24908+
24909+static int plink_name(char *name, int len, struct inode *inode,
24910+ aufs_bindex_t bindex)
24911+{
24912+ int rlen;
24913+ struct inode *h_inode;
24914+
24915+ h_inode = au_h_iptr(inode, bindex);
24916+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
24917+ return rlen;
24918+}
24919+
7f207e10
AM
24920+struct au_do_plink_lkup_args {
24921+ struct dentry **errp;
24922+ struct qstr *tgtname;
24923+ struct dentry *h_parent;
24924+ struct au_branch *br;
24925+};
24926+
24927+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
24928+ struct dentry *h_parent,
24929+ struct au_branch *br)
24930+{
24931+ struct dentry *h_dentry;
24932+ struct mutex *h_mtx;
24933+
5527c038 24934+ h_mtx = &d_inode(h_parent)->i_mutex;
7f207e10 24935+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
b4510431 24936+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
7f207e10
AM
24937+ mutex_unlock(h_mtx);
24938+ return h_dentry;
24939+}
24940+
24941+static void au_call_do_plink_lkup(void *args)
24942+{
24943+ struct au_do_plink_lkup_args *a = args;
24944+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
24945+}
24946+
1facf9fc 24947+/* lookup the plink-ed @inode under the branch at @bindex */
24948+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
24949+{
24950+ struct dentry *h_dentry, *h_parent;
24951+ struct au_branch *br;
7f207e10 24952+ int wkq_err;
1facf9fc 24953+ char a[PLINK_NAME_LEN];
0c3ec466 24954+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 24955+
e49829fe
JR
24956+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
24957+
1facf9fc 24958+ br = au_sbr(inode->i_sb, bindex);
24959+ h_parent = br->br_wbr->wbr_plink;
1facf9fc 24960+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
24961+
2dfbb274 24962+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
24963+ struct au_do_plink_lkup_args args = {
24964+ .errp = &h_dentry,
24965+ .tgtname = &tgtname,
24966+ .h_parent = h_parent,
24967+ .br = br
24968+ };
24969+
24970+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
24971+ if (unlikely(wkq_err))
24972+ h_dentry = ERR_PTR(wkq_err);
24973+ } else
24974+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
24975+
1facf9fc 24976+ return h_dentry;
24977+}
24978+
24979+/* create a pseudo-link */
24980+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
24981+ struct dentry *h_dentry, struct au_branch *br)
24982+{
24983+ int err;
24984+ struct path h_path = {
86dc4139 24985+ .mnt = au_br_mnt(br)
1facf9fc 24986+ };
523b37e3 24987+ struct inode *h_dir, *delegated;
1facf9fc 24988+
5527c038 24989+ h_dir = d_inode(h_parent);
7f207e10 24990+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
4f0767ce 24991+again:
b4510431 24992+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 24993+ err = PTR_ERR(h_path.dentry);
24994+ if (IS_ERR(h_path.dentry))
24995+ goto out;
24996+
24997+ err = 0;
24998+ /* wh.plink dir is not monitored */
7f207e10 24999+ /* todo: is it really safe? */
5527c038
JR
25000+ if (d_is_positive(h_path.dentry)
25001+ && d_inode(h_path.dentry) != d_inode(h_dentry)) {
523b37e3
AM
25002+ delegated = NULL;
25003+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
25004+ if (unlikely(err == -EWOULDBLOCK)) {
25005+ pr_warn("cannot retry for NFSv4 delegation"
25006+ " for an internal unlink\n");
25007+ iput(delegated);
25008+ }
1facf9fc 25009+ dput(h_path.dentry);
25010+ h_path.dentry = NULL;
25011+ if (!err)
25012+ goto again;
25013+ }
5527c038 25014+ if (!err && d_is_negative(h_path.dentry)) {
523b37e3
AM
25015+ delegated = NULL;
25016+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
25017+ if (unlikely(err == -EWOULDBLOCK)) {
25018+ pr_warn("cannot retry for NFSv4 delegation"
25019+ " for an internal link\n");
25020+ iput(delegated);
25021+ }
25022+ }
1facf9fc 25023+ dput(h_path.dentry);
25024+
4f0767ce 25025+out:
7f207e10 25026+ mutex_unlock(&h_dir->i_mutex);
1facf9fc 25027+ return err;
25028+}
25029+
25030+struct do_whplink_args {
25031+ int *errp;
25032+ struct qstr *tgt;
25033+ struct dentry *h_parent;
25034+ struct dentry *h_dentry;
25035+ struct au_branch *br;
25036+};
25037+
25038+static void call_do_whplink(void *args)
25039+{
25040+ struct do_whplink_args *a = args;
25041+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
25042+}
25043+
25044+static int whplink(struct dentry *h_dentry, struct inode *inode,
25045+ aufs_bindex_t bindex, struct au_branch *br)
25046+{
25047+ int err, wkq_err;
25048+ struct au_wbr *wbr;
25049+ struct dentry *h_parent;
1facf9fc 25050+ char a[PLINK_NAME_LEN];
0c3ec466 25051+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 25052+
25053+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
25054+ h_parent = wbr->wbr_plink;
1facf9fc 25055+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
25056+
25057+ /* always superio. */
2dfbb274 25058+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 25059+ struct do_whplink_args args = {
25060+ .errp = &err,
25061+ .tgt = &tgtname,
25062+ .h_parent = h_parent,
25063+ .h_dentry = h_dentry,
25064+ .br = br
25065+ };
25066+ wkq_err = au_wkq_wait(call_do_whplink, &args);
25067+ if (unlikely(wkq_err))
25068+ err = wkq_err;
25069+ } else
25070+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 25071+
25072+ return err;
25073+}
25074+
25075+/* free a single plink */
25076+static void do_put_plink(struct pseudo_link *plink, int do_del)
25077+{
1facf9fc 25078+ if (do_del)
86dc4139 25079+ hlist_del(&plink->hlist);
4a4d8108
AM
25080+ iput(plink->inode);
25081+ kfree(plink);
25082+}
25083+
25084+static void do_put_plink_rcu(struct rcu_head *rcu)
25085+{
25086+ struct pseudo_link *plink;
25087+
25088+ plink = container_of(rcu, struct pseudo_link, rcu);
25089+ iput(plink->inode);
1facf9fc 25090+ kfree(plink);
25091+}
25092+
25093+/*
25094+ * create a new pseudo-link for @h_dentry on @bindex.
25095+ * the linked inode is held in aufs @inode.
25096+ */
25097+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
25098+ struct dentry *h_dentry)
25099+{
25100+ struct super_block *sb;
25101+ struct au_sbinfo *sbinfo;
86dc4139 25102+ struct hlist_head *plink_hlist;
4a4d8108 25103+ struct pseudo_link *plink, *tmp;
86dc4139
AM
25104+ struct au_sphlhead *sphl;
25105+ int found, err, cnt, i;
1facf9fc 25106+
25107+ sb = inode->i_sb;
25108+ sbinfo = au_sbi(sb);
25109+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 25110+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 25111+
86dc4139 25112+ found = au_plink_test(inode);
4a4d8108 25113+ if (found)
1facf9fc 25114+ return;
4a4d8108 25115+
86dc4139
AM
25116+ i = au_plink_hash(inode->i_ino);
25117+ sphl = sbinfo->si_plink + i;
25118+ plink_hlist = &sphl->head;
4a4d8108
AM
25119+ tmp = kmalloc(sizeof(*plink), GFP_NOFS);
25120+ if (tmp)
25121+ tmp->inode = au_igrab(inode);
25122+ else {
25123+ err = -ENOMEM;
25124+ goto out;
1facf9fc 25125+ }
25126+
86dc4139
AM
25127+ spin_lock(&sphl->spin);
25128+ hlist_for_each_entry(plink, plink_hlist, hlist) {
4a4d8108
AM
25129+ if (plink->inode == inode) {
25130+ found = 1;
25131+ break;
25132+ }
1facf9fc 25133+ }
4a4d8108 25134+ if (!found)
86dc4139
AM
25135+ hlist_add_head_rcu(&tmp->hlist, plink_hlist);
25136+ spin_unlock(&sphl->spin);
4a4d8108 25137+ if (!found) {
86dc4139
AM
25138+ cnt = au_sphl_count(sphl);
25139+#define msg "unexpectedly unblanced or too many pseudo-links"
25140+ if (cnt > AUFS_PLINK_WARN)
25141+ AuWarn1(msg ", %d\n", cnt);
25142+#undef msg
1facf9fc 25143+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
4a4d8108
AM
25144+ } else {
25145+ do_put_plink(tmp, 0);
25146+ return;
1facf9fc 25147+ }
25148+
4a4d8108 25149+out:
1facf9fc 25150+ if (unlikely(err)) {
0c3ec466 25151+ pr_warn("err %d, damaged pseudo link.\n", err);
4a4d8108 25152+ if (tmp) {
86dc4139 25153+ au_sphl_del_rcu(&tmp->hlist, sphl);
4a4d8108
AM
25154+ call_rcu(&tmp->rcu, do_put_plink_rcu);
25155+ }
1facf9fc 25156+ }
25157+}
25158+
25159+/* free all plinks */
e49829fe 25160+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 25161+{
86dc4139 25162+ int i, warned;
1facf9fc 25163+ struct au_sbinfo *sbinfo;
86dc4139
AM
25164+ struct hlist_head *plink_hlist;
25165+ struct hlist_node *tmp;
25166+ struct pseudo_link *plink;
1facf9fc 25167+
dece6358
AM
25168+ SiMustWriteLock(sb);
25169+
1facf9fc 25170+ sbinfo = au_sbi(sb);
25171+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 25172+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 25173+
1facf9fc 25174+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
25175+ warned = 0;
25176+ for (i = 0; i < AuPlink_NHASH; i++) {
25177+ plink_hlist = &sbinfo->si_plink[i].head;
25178+ if (!warned && verbose && !hlist_empty(plink_hlist)) {
25179+ pr_warn("pseudo-link is not flushed");
25180+ warned = 1;
25181+ }
25182+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
25183+ do_put_plink(plink, 0);
25184+ INIT_HLIST_HEAD(plink_hlist);
25185+ }
1facf9fc 25186+}
25187+
e49829fe
JR
25188+void au_plink_clean(struct super_block *sb, int verbose)
25189+{
25190+ struct dentry *root;
25191+
25192+ root = sb->s_root;
25193+ aufs_write_lock(root);
25194+ if (au_opt_test(au_mntflags(sb), PLINK))
25195+ au_plink_put(sb, verbose);
25196+ aufs_write_unlock(root);
25197+}
25198+
86dc4139
AM
25199+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
25200+{
25201+ int do_put;
25202+ aufs_bindex_t bstart, bend, bindex;
25203+
25204+ do_put = 0;
25205+ bstart = au_ibstart(inode);
25206+ bend = au_ibend(inode);
25207+ if (bstart >= 0) {
25208+ for (bindex = bstart; bindex <= bend; bindex++) {
25209+ if (!au_h_iptr(inode, bindex)
25210+ || au_ii_br_id(inode, bindex) != br_id)
25211+ continue;
25212+ au_set_h_iptr(inode, bindex, NULL, 0);
25213+ do_put = 1;
25214+ break;
25215+ }
25216+ if (do_put)
25217+ for (bindex = bstart; bindex <= bend; bindex++)
25218+ if (au_h_iptr(inode, bindex)) {
25219+ do_put = 0;
25220+ break;
25221+ }
25222+ } else
25223+ do_put = 1;
25224+
25225+ return do_put;
25226+}
25227+
1facf9fc 25228+/* free the plinks on a branch specified by @br_id */
25229+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
25230+{
25231+ struct au_sbinfo *sbinfo;
86dc4139
AM
25232+ struct hlist_head *plink_hlist;
25233+ struct hlist_node *tmp;
25234+ struct pseudo_link *plink;
1facf9fc 25235+ struct inode *inode;
86dc4139 25236+ int i, do_put;
1facf9fc 25237+
dece6358
AM
25238+ SiMustWriteLock(sb);
25239+
1facf9fc 25240+ sbinfo = au_sbi(sb);
25241+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 25242+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 25243+
1facf9fc 25244+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
25245+ for (i = 0; i < AuPlink_NHASH; i++) {
25246+ plink_hlist = &sbinfo->si_plink[i].head;
25247+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
25248+ inode = au_igrab(plink->inode);
25249+ ii_write_lock_child(inode);
25250+ do_put = au_plink_do_half_refresh(inode, br_id);
dece6358
AM
25251+ if (do_put)
25252+ do_put_plink(plink, 1);
86dc4139
AM
25253+ ii_write_unlock(inode);
25254+ iput(inode);
dece6358 25255+ }
dece6358
AM
25256+ }
25257+}
7f207e10
AM
25258diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
25259--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 25260+++ linux/fs/aufs/poll.c 2015-09-24 10:47:58.254719746 +0200
b912730e 25261@@ -0,0 +1,52 @@
dece6358 25262+/*
2000de60 25263+ * Copyright (C) 2005-2015 Junjiro R. Okajima
dece6358
AM
25264+ *
25265+ * This program, aufs is free software; you can redistribute it and/or modify
25266+ * it under the terms of the GNU General Public License as published by
25267+ * the Free Software Foundation; either version 2 of the License, or
25268+ * (at your option) any later version.
25269+ *
25270+ * This program is distributed in the hope that it will be useful,
25271+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25272+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25273+ * GNU General Public License for more details.
25274+ *
25275+ * You should have received a copy of the GNU General Public License
523b37e3 25276+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
25277+ */
25278+
1308ab2a 25279+/*
25280+ * poll operation
25281+ * There is only one filesystem which implements ->poll operation, currently.
25282+ */
25283+
25284+#include "aufs.h"
25285+
25286+unsigned int aufs_poll(struct file *file, poll_table *wait)
25287+{
25288+ unsigned int mask;
25289+ int err;
25290+ struct file *h_file;
1308ab2a 25291+ struct super_block *sb;
25292+
25293+ /* We should pretend an error happened. */
25294+ mask = POLLERR /* | POLLIN | POLLOUT */;
b912730e 25295+ sb = file->f_path.dentry->d_sb;
e49829fe 25296+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
b912730e
AM
25297+
25298+ h_file = au_read_pre(file, /*keep_fi*/0);
25299+ err = PTR_ERR(h_file);
25300+ if (IS_ERR(h_file))
1308ab2a 25301+ goto out;
25302+
25303+ /* it is not an error if h_file has no operation */
25304+ mask = DEFAULT_POLLMASK;
523b37e3 25305+ if (h_file->f_op->poll)
1308ab2a 25306+ mask = h_file->f_op->poll(h_file, wait);
b912730e 25307+ fput(h_file); /* instead of au_read_post() */
1308ab2a 25308+
4f0767ce 25309+out:
1308ab2a 25310+ si_read_unlock(sb);
25311+ AuTraceErr((int)mask);
25312+ return mask;
25313+}
c1595e42
JR
25314diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
25315--- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 25316+++ linux/fs/aufs/posix_acl.c 2015-09-24 10:47:58.254719746 +0200
c1595e42
JR
25317@@ -0,0 +1,99 @@
25318+/*
2000de60 25319+ * Copyright (C) 2014-2015 Junjiro R. Okajima
c1595e42
JR
25320+ *
25321+ * This program, aufs is free software; you can redistribute it and/or modify
25322+ * it under the terms of the GNU General Public License as published by
25323+ * the Free Software Foundation; either version 2 of the License, or
25324+ * (at your option) any later version.
25325+ *
25326+ * This program is distributed in the hope that it will be useful,
25327+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25328+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25329+ * GNU General Public License for more details.
25330+ *
25331+ * You should have received a copy of the GNU General Public License
25332+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
25333+ */
25334+
25335+/*
25336+ * posix acl operations
25337+ */
25338+
25339+#include <linux/fs.h>
25340+#include <linux/posix_acl.h>
25341+#include "aufs.h"
25342+
25343+struct posix_acl *aufs_get_acl(struct inode *inode, int type)
25344+{
25345+ struct posix_acl *acl;
25346+ int err;
25347+ aufs_bindex_t bindex;
25348+ struct inode *h_inode;
25349+ struct super_block *sb;
25350+
25351+ acl = NULL;
25352+ sb = inode->i_sb;
25353+ si_read_lock(sb, AuLock_FLUSH);
25354+ ii_read_lock_child(inode);
25355+ if (!(sb->s_flags & MS_POSIXACL))
25356+ goto out;
25357+
25358+ bindex = au_ibstart(inode);
25359+ h_inode = au_h_iptr(inode, bindex);
25360+ if (unlikely(!h_inode
25361+ || ((h_inode->i_mode & S_IFMT)
25362+ != (inode->i_mode & S_IFMT)))) {
25363+ err = au_busy_or_stale();
25364+ acl = ERR_PTR(err);
25365+ goto out;
25366+ }
25367+
25368+ /* always topmost only */
25369+ acl = get_acl(h_inode, type);
25370+
25371+out:
25372+ ii_read_unlock(inode);
25373+ si_read_unlock(sb);
25374+
25375+ AuTraceErrPtr(acl);
25376+ return acl;
25377+}
25378+
25379+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
25380+{
25381+ int err;
25382+ ssize_t ssz;
25383+ struct dentry *dentry;
25384+ struct au_srxattr arg = {
25385+ .type = AU_ACL_SET,
25386+ .u.acl_set = {
25387+ .acl = acl,
25388+ .type = type
25389+ },
25390+ };
25391+
25392+ mutex_lock(&inode->i_mutex);
25393+ if (inode->i_ino == AUFS_ROOT_INO)
25394+ dentry = dget(inode->i_sb->s_root);
25395+ else {
25396+ dentry = d_find_alias(inode);
25397+ if (!dentry)
25398+ dentry = d_find_any_alias(inode);
25399+ if (!dentry) {
25400+ pr_warn("cannot handle this inode, "
25401+ "please report to aufs-users ML\n");
25402+ err = -ENOENT;
25403+ goto out;
25404+ }
25405+ }
25406+
25407+ ssz = au_srxattr(dentry, &arg);
25408+ dput(dentry);
25409+ err = ssz;
25410+ if (ssz >= 0)
25411+ err = 0;
25412+
25413+out:
25414+ mutex_unlock(&inode->i_mutex);
25415+ return err;
25416+}
7f207e10
AM
25417diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
25418--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 25419+++ linux/fs/aufs/procfs.c 2015-09-24 10:47:58.254719746 +0200
523b37e3 25420@@ -0,0 +1,169 @@
e49829fe 25421+/*
2000de60 25422+ * Copyright (C) 2010-2015 Junjiro R. Okajima
e49829fe
JR
25423+ *
25424+ * This program, aufs is free software; you can redistribute it and/or modify
25425+ * it under the terms of the GNU General Public License as published by
25426+ * the Free Software Foundation; either version 2 of the License, or
25427+ * (at your option) any later version.
25428+ *
25429+ * This program is distributed in the hope that it will be useful,
25430+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25431+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25432+ * GNU General Public License for more details.
25433+ *
25434+ * You should have received a copy of the GNU General Public License
523b37e3 25435+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
25436+ */
25437+
25438+/*
25439+ * procfs interfaces
25440+ */
25441+
25442+#include <linux/proc_fs.h>
25443+#include "aufs.h"
25444+
25445+static int au_procfs_plm_release(struct inode *inode, struct file *file)
25446+{
25447+ struct au_sbinfo *sbinfo;
25448+
25449+ sbinfo = file->private_data;
25450+ if (sbinfo) {
25451+ au_plink_maint_leave(sbinfo);
25452+ kobject_put(&sbinfo->si_kobj);
25453+ }
25454+
25455+ return 0;
25456+}
25457+
25458+static void au_procfs_plm_write_clean(struct file *file)
25459+{
25460+ struct au_sbinfo *sbinfo;
25461+
25462+ sbinfo = file->private_data;
25463+ if (sbinfo)
25464+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
25465+}
25466+
25467+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
25468+{
25469+ int err;
25470+ struct super_block *sb;
25471+ struct au_sbinfo *sbinfo;
25472+
25473+ err = -EBUSY;
25474+ if (unlikely(file->private_data))
25475+ goto out;
25476+
25477+ sb = NULL;
53392da6 25478+ /* don't use au_sbilist_lock() here */
e49829fe
JR
25479+ spin_lock(&au_sbilist.spin);
25480+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
25481+ if (id == sysaufs_si_id(sbinfo)) {
25482+ kobject_get(&sbinfo->si_kobj);
25483+ sb = sbinfo->si_sb;
25484+ break;
25485+ }
25486+ spin_unlock(&au_sbilist.spin);
25487+
25488+ err = -EINVAL;
25489+ if (unlikely(!sb))
25490+ goto out;
25491+
25492+ err = au_plink_maint_enter(sb);
25493+ if (!err)
25494+ /* keep kobject_get() */
25495+ file->private_data = sbinfo;
25496+ else
25497+ kobject_put(&sbinfo->si_kobj);
25498+out:
25499+ return err;
25500+}
25501+
25502+/*
25503+ * Accept a valid "si=xxxx" only.
25504+ * Once it is accepted successfully, accept "clean" too.
25505+ */
25506+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
25507+ size_t count, loff_t *ppos)
25508+{
25509+ ssize_t err;
25510+ unsigned long id;
25511+ /* last newline is allowed */
25512+ char buf[3 + sizeof(unsigned long) * 2 + 1];
25513+
25514+ err = -EACCES;
25515+ if (unlikely(!capable(CAP_SYS_ADMIN)))
25516+ goto out;
25517+
25518+ err = -EINVAL;
25519+ if (unlikely(count > sizeof(buf)))
25520+ goto out;
25521+
25522+ err = copy_from_user(buf, ubuf, count);
25523+ if (unlikely(err)) {
25524+ err = -EFAULT;
25525+ goto out;
25526+ }
25527+ buf[count] = 0;
25528+
25529+ err = -EINVAL;
25530+ if (!strcmp("clean", buf)) {
25531+ au_procfs_plm_write_clean(file);
25532+ goto out_success;
25533+ } else if (unlikely(strncmp("si=", buf, 3)))
25534+ goto out;
25535+
9dbd164d 25536+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
25537+ if (unlikely(err))
25538+ goto out;
25539+
25540+ err = au_procfs_plm_write_si(file, id);
25541+ if (unlikely(err))
25542+ goto out;
25543+
25544+out_success:
25545+ err = count; /* success */
25546+out:
25547+ return err;
25548+}
25549+
25550+static const struct file_operations au_procfs_plm_fop = {
25551+ .write = au_procfs_plm_write,
25552+ .release = au_procfs_plm_release,
25553+ .owner = THIS_MODULE
25554+};
25555+
25556+/* ---------------------------------------------------------------------- */
25557+
25558+static struct proc_dir_entry *au_procfs_dir;
25559+
25560+void au_procfs_fin(void)
25561+{
25562+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
25563+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
25564+}
25565+
25566+int __init au_procfs_init(void)
25567+{
25568+ int err;
25569+ struct proc_dir_entry *entry;
25570+
25571+ err = -ENOMEM;
25572+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
25573+ if (unlikely(!au_procfs_dir))
25574+ goto out;
25575+
25576+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
25577+ au_procfs_dir, &au_procfs_plm_fop);
25578+ if (unlikely(!entry))
25579+ goto out_dir;
25580+
25581+ err = 0;
25582+ goto out; /* success */
25583+
25584+
25585+out_dir:
25586+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
25587+out:
25588+ return err;
25589+}
7f207e10
AM
25590diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
25591--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 25592+++ linux/fs/aufs/rdu.c 2015-09-24 10:47:58.254719746 +0200
523b37e3 25593@@ -0,0 +1,388 @@
1308ab2a 25594+/*
2000de60 25595+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1308ab2a 25596+ *
25597+ * This program, aufs is free software; you can redistribute it and/or modify
25598+ * it under the terms of the GNU General Public License as published by
25599+ * the Free Software Foundation; either version 2 of the License, or
25600+ * (at your option) any later version.
25601+ *
25602+ * This program is distributed in the hope that it will be useful,
25603+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25604+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25605+ * GNU General Public License for more details.
25606+ *
25607+ * You should have received a copy of the GNU General Public License
523b37e3 25608+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 25609+ */
25610+
25611+/*
25612+ * readdir in userspace.
25613+ */
25614+
b752ccd1 25615+#include <linux/compat.h>
4a4d8108 25616+#include <linux/fs_stack.h>
1308ab2a 25617+#include <linux/security.h>
1308ab2a 25618+#include "aufs.h"
25619+
25620+/* bits for struct aufs_rdu.flags */
25621+#define AuRdu_CALLED 1
25622+#define AuRdu_CONT (1 << 1)
25623+#define AuRdu_FULL (1 << 2)
25624+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
25625+#define au_fset_rdu(flags, name) \
25626+ do { (flags) |= AuRdu_##name; } while (0)
25627+#define au_fclr_rdu(flags, name) \
25628+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 25629+
25630+struct au_rdu_arg {
392086de 25631+ struct dir_context ctx;
1308ab2a 25632+ struct aufs_rdu *rdu;
25633+ union au_rdu_ent_ul ent;
25634+ unsigned long end;
25635+
25636+ struct super_block *sb;
25637+ int err;
25638+};
25639+
392086de 25640+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 25641+ loff_t offset, u64 h_ino, unsigned int d_type)
25642+{
25643+ int err, len;
392086de 25644+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 25645+ struct aufs_rdu *rdu = arg->rdu;
25646+ struct au_rdu_ent ent;
25647+
25648+ err = 0;
25649+ arg->err = 0;
25650+ au_fset_rdu(rdu->cookie.flags, CALLED);
25651+ len = au_rdu_len(nlen);
25652+ if (arg->ent.ul + len < arg->end) {
25653+ ent.ino = h_ino;
25654+ ent.bindex = rdu->cookie.bindex;
25655+ ent.type = d_type;
25656+ ent.nlen = nlen;
4a4d8108
AM
25657+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
25658+ ent.type = DT_UNKNOWN;
1308ab2a 25659+
9dbd164d 25660+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 25661+ err = -EFAULT;
25662+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
25663+ goto out;
25664+ if (copy_to_user(arg->ent.e->name, name, nlen))
25665+ goto out;
25666+ /* the terminating NULL */
25667+ if (__put_user(0, arg->ent.e->name + nlen))
25668+ goto out;
25669+ err = 0;
25670+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
25671+ arg->ent.ul += len;
25672+ rdu->rent++;
25673+ } else {
25674+ err = -EFAULT;
25675+ au_fset_rdu(rdu->cookie.flags, FULL);
25676+ rdu->full = 1;
25677+ rdu->tail = arg->ent;
25678+ }
25679+
4f0767ce 25680+out:
1308ab2a 25681+ /* AuTraceErr(err); */
25682+ return err;
25683+}
25684+
25685+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
25686+{
25687+ int err;
25688+ loff_t offset;
25689+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
25690+
92d182d2 25691+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 25692+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
25693+ err = offset;
25694+ if (unlikely(offset != cookie->h_pos))
25695+ goto out;
25696+
25697+ err = 0;
25698+ do {
25699+ arg->err = 0;
25700+ au_fclr_rdu(cookie->flags, CALLED);
25701+ /* smp_mb(); */
392086de 25702+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 25703+ if (err >= 0)
25704+ err = arg->err;
25705+ } while (!err
25706+ && au_ftest_rdu(cookie->flags, CALLED)
25707+ && !au_ftest_rdu(cookie->flags, FULL));
25708+ cookie->h_pos = h_file->f_pos;
25709+
4f0767ce 25710+out:
1308ab2a 25711+ AuTraceErr(err);
25712+ return err;
25713+}
25714+
25715+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
25716+{
25717+ int err;
25718+ aufs_bindex_t bend;
392086de
AM
25719+ struct au_rdu_arg arg = {
25720+ .ctx = {
2000de60 25721+ .actor = au_rdu_fill
392086de
AM
25722+ }
25723+ };
1308ab2a 25724+ struct dentry *dentry;
25725+ struct inode *inode;
25726+ struct file *h_file;
25727+ struct au_rdu_cookie *cookie = &rdu->cookie;
25728+
25729+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
25730+ if (unlikely(err)) {
25731+ err = -EFAULT;
25732+ AuTraceErr(err);
25733+ goto out;
25734+ }
25735+ rdu->rent = 0;
25736+ rdu->tail = rdu->ent;
25737+ rdu->full = 0;
25738+ arg.rdu = rdu;
25739+ arg.ent = rdu->ent;
25740+ arg.end = arg.ent.ul;
25741+ arg.end += rdu->sz;
25742+
25743+ err = -ENOTDIR;
523b37e3 25744+ if (unlikely(!file->f_op->iterate))
1308ab2a 25745+ goto out;
25746+
25747+ err = security_file_permission(file, MAY_READ);
25748+ AuTraceErr(err);
25749+ if (unlikely(err))
25750+ goto out;
25751+
2000de60 25752+ dentry = file->f_path.dentry;
5527c038 25753+ inode = d_inode(dentry);
1308ab2a 25754+#if 1
25755+ mutex_lock(&inode->i_mutex);
25756+#else
25757+ err = mutex_lock_killable(&inode->i_mutex);
25758+ AuTraceErr(err);
25759+ if (unlikely(err))
25760+ goto out;
25761+#endif
1308ab2a 25762+
25763+ arg.sb = inode->i_sb;
e49829fe
JR
25764+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
25765+ if (unlikely(err))
25766+ goto out_mtx;
027c5e7a
AM
25767+ err = au_alive_dir(dentry);
25768+ if (unlikely(err))
25769+ goto out_si;
e49829fe 25770+ /* todo: reval? */
1308ab2a 25771+ fi_read_lock(file);
25772+
25773+ err = -EAGAIN;
25774+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
25775+ && cookie->generation != au_figen(file)))
25776+ goto out_unlock;
25777+
25778+ err = 0;
25779+ if (!rdu->blk) {
25780+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
25781+ if (!rdu->blk)
25782+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
25783+ }
25784+ bend = au_fbstart(file);
25785+ if (cookie->bindex < bend)
25786+ cookie->bindex = bend;
4a4d8108 25787+ bend = au_fbend_dir(file);
1308ab2a 25788+ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
25789+ for (; !err && cookie->bindex <= bend;
25790+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 25791+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 25792+ if (!h_file)
25793+ continue;
25794+
25795+ au_fclr_rdu(cookie->flags, FULL);
25796+ err = au_rdu_do(h_file, &arg);
25797+ AuTraceErr(err);
25798+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
25799+ break;
25800+ }
25801+ AuDbg("rent %llu\n", rdu->rent);
25802+
25803+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
25804+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
25805+ au_fset_rdu(cookie->flags, CONT);
25806+ cookie->generation = au_figen(file);
25807+ }
25808+
25809+ ii_read_lock_child(inode);
25810+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
25811+ ii_read_unlock(inode);
25812+
4f0767ce 25813+out_unlock:
1308ab2a 25814+ fi_read_unlock(file);
027c5e7a 25815+out_si:
1308ab2a 25816+ si_read_unlock(arg.sb);
4f0767ce 25817+out_mtx:
1308ab2a 25818+ mutex_unlock(&inode->i_mutex);
4f0767ce 25819+out:
1308ab2a 25820+ AuTraceErr(err);
25821+ return err;
25822+}
25823+
25824+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
25825+{
25826+ int err;
25827+ ino_t ino;
25828+ unsigned long long nent;
25829+ union au_rdu_ent_ul *u;
25830+ struct au_rdu_ent ent;
25831+ struct super_block *sb;
25832+
25833+ err = 0;
25834+ nent = rdu->nent;
25835+ u = &rdu->ent;
2000de60 25836+ sb = file->f_path.dentry->d_sb;
1308ab2a 25837+ si_read_lock(sb, AuLock_FLUSH);
25838+ while (nent-- > 0) {
9dbd164d 25839+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 25840+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
25841+ if (!err)
25842+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 25843+ if (unlikely(err)) {
25844+ err = -EFAULT;
25845+ AuTraceErr(err);
25846+ break;
25847+ }
25848+
25849+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
25850+ if (!ent.wh)
25851+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
25852+ else
25853+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
25854+ &ino);
25855+ if (unlikely(err)) {
25856+ AuTraceErr(err);
25857+ break;
25858+ }
25859+
25860+ err = __put_user(ino, &u->e->ino);
25861+ if (unlikely(err)) {
25862+ err = -EFAULT;
25863+ AuTraceErr(err);
25864+ break;
25865+ }
25866+ u->ul += au_rdu_len(ent.nlen);
25867+ }
25868+ si_read_unlock(sb);
25869+
25870+ return err;
25871+}
25872+
25873+/* ---------------------------------------------------------------------- */
25874+
25875+static int au_rdu_verify(struct aufs_rdu *rdu)
25876+{
b752ccd1 25877+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 25878+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 25879+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 25880+ rdu->blk,
25881+ rdu->rent, rdu->shwh, rdu->full,
25882+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
25883+ rdu->cookie.generation);
dece6358 25884+
b752ccd1 25885+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 25886+ return 0;
dece6358 25887+
b752ccd1
AM
25888+ AuDbg("%u:%u\n",
25889+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 25890+ return -EINVAL;
25891+}
25892+
25893+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 25894+{
1308ab2a 25895+ long err, e;
25896+ struct aufs_rdu rdu;
25897+ void __user *p = (void __user *)arg;
dece6358 25898+
1308ab2a 25899+ err = copy_from_user(&rdu, p, sizeof(rdu));
25900+ if (unlikely(err)) {
25901+ err = -EFAULT;
25902+ AuTraceErr(err);
25903+ goto out;
25904+ }
25905+ err = au_rdu_verify(&rdu);
dece6358
AM
25906+ if (unlikely(err))
25907+ goto out;
25908+
1308ab2a 25909+ switch (cmd) {
25910+ case AUFS_CTL_RDU:
25911+ err = au_rdu(file, &rdu);
25912+ if (unlikely(err))
25913+ break;
dece6358 25914+
1308ab2a 25915+ e = copy_to_user(p, &rdu, sizeof(rdu));
25916+ if (unlikely(e)) {
25917+ err = -EFAULT;
25918+ AuTraceErr(err);
25919+ }
25920+ break;
25921+ case AUFS_CTL_RDU_INO:
25922+ err = au_rdu_ino(file, &rdu);
25923+ break;
25924+
25925+ default:
4a4d8108 25926+ /* err = -ENOTTY; */
1308ab2a 25927+ err = -EINVAL;
25928+ }
dece6358 25929+
4f0767ce 25930+out:
1308ab2a 25931+ AuTraceErr(err);
25932+ return err;
1facf9fc 25933+}
b752ccd1
AM
25934+
25935+#ifdef CONFIG_COMPAT
25936+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
25937+{
25938+ long err, e;
25939+ struct aufs_rdu rdu;
25940+ void __user *p = compat_ptr(arg);
25941+
25942+ /* todo: get_user()? */
25943+ err = copy_from_user(&rdu, p, sizeof(rdu));
25944+ if (unlikely(err)) {
25945+ err = -EFAULT;
25946+ AuTraceErr(err);
25947+ goto out;
25948+ }
25949+ rdu.ent.e = compat_ptr(rdu.ent.ul);
25950+ err = au_rdu_verify(&rdu);
25951+ if (unlikely(err))
25952+ goto out;
25953+
25954+ switch (cmd) {
25955+ case AUFS_CTL_RDU:
25956+ err = au_rdu(file, &rdu);
25957+ if (unlikely(err))
25958+ break;
25959+
25960+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
25961+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
25962+ e = copy_to_user(p, &rdu, sizeof(rdu));
25963+ if (unlikely(e)) {
25964+ err = -EFAULT;
25965+ AuTraceErr(err);
25966+ }
25967+ break;
25968+ case AUFS_CTL_RDU_INO:
25969+ err = au_rdu_ino(file, &rdu);
25970+ break;
25971+
25972+ default:
25973+ /* err = -ENOTTY; */
25974+ err = -EINVAL;
25975+ }
25976+
4f0767ce 25977+out:
b752ccd1
AM
25978+ AuTraceErr(err);
25979+ return err;
25980+}
25981+#endif
7f207e10
AM
25982diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
25983--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 25984+++ linux/fs/aufs/rwsem.h 2015-09-24 10:47:58.254719746 +0200
076b876e 25985@@ -0,0 +1,191 @@
1facf9fc 25986+/*
2000de60 25987+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 25988+ *
25989+ * This program, aufs is free software; you can redistribute it and/or modify
25990+ * it under the terms of the GNU General Public License as published by
25991+ * the Free Software Foundation; either version 2 of the License, or
25992+ * (at your option) any later version.
dece6358
AM
25993+ *
25994+ * This program is distributed in the hope that it will be useful,
25995+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25996+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25997+ * GNU General Public License for more details.
25998+ *
25999+ * You should have received a copy of the GNU General Public License
523b37e3 26000+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26001+ */
26002+
26003+/*
26004+ * simple read-write semaphore wrappers
26005+ */
26006+
26007+#ifndef __AUFS_RWSEM_H__
26008+#define __AUFS_RWSEM_H__
26009+
26010+#ifdef __KERNEL__
26011+
4a4d8108 26012+#include "debug.h"
dece6358
AM
26013+
26014+struct au_rwsem {
26015+ struct rw_semaphore rwsem;
26016+#ifdef CONFIG_AUFS_DEBUG
26017+ /* just for debugging, not almighty counter */
26018+ atomic_t rcnt, wcnt;
26019+#endif
26020+};
26021+
26022+#ifdef CONFIG_AUFS_DEBUG
26023+#define AuDbgCntInit(rw) do { \
26024+ atomic_set(&(rw)->rcnt, 0); \
26025+ atomic_set(&(rw)->wcnt, 0); \
26026+ smp_mb(); /* atomic set */ \
26027+} while (0)
26028+
e49829fe 26029+#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
dece6358 26030+#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
e49829fe 26031+#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
dece6358
AM
26032+#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
26033+#else
26034+#define AuDbgCntInit(rw) do {} while (0)
26035+#define AuDbgRcntInc(rw) do {} while (0)
26036+#define AuDbgRcntDec(rw) do {} while (0)
26037+#define AuDbgWcntInc(rw) do {} while (0)
26038+#define AuDbgWcntDec(rw) do {} while (0)
26039+#endif /* CONFIG_AUFS_DEBUG */
26040+
26041+/* to debug easier, do not make them inlined functions */
26042+#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
26043+/* rwsem_is_locked() is unusable */
26044+#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
26045+#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
26046+#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
26047+ && atomic_read(&(rw)->wcnt) <= 0)
26048+#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
26049+ || atomic_read(&(rw)->wcnt))
26050+
e49829fe
JR
26051+#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
26052+
dece6358
AM
26053+static inline void au_rw_init(struct au_rwsem *rw)
26054+{
26055+ AuDbgCntInit(rw);
26056+ init_rwsem(&rw->rwsem);
26057+}
26058+
26059+static inline void au_rw_init_wlock(struct au_rwsem *rw)
26060+{
26061+ au_rw_init(rw);
26062+ down_write(&rw->rwsem);
26063+ AuDbgWcntInc(rw);
26064+}
26065+
26066+static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
26067+ unsigned int lsc)
26068+{
26069+ au_rw_init(rw);
26070+ down_write_nested(&rw->rwsem, lsc);
26071+ AuDbgWcntInc(rw);
26072+}
26073+
26074+static inline void au_rw_read_lock(struct au_rwsem *rw)
26075+{
26076+ down_read(&rw->rwsem);
26077+ AuDbgRcntInc(rw);
26078+}
26079+
26080+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
26081+{
26082+ down_read_nested(&rw->rwsem, lsc);
26083+ AuDbgRcntInc(rw);
26084+}
26085+
26086+static inline void au_rw_read_unlock(struct au_rwsem *rw)
26087+{
26088+ AuRwMustReadLock(rw);
26089+ AuDbgRcntDec(rw);
26090+ up_read(&rw->rwsem);
26091+}
26092+
26093+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
26094+{
26095+ AuRwMustWriteLock(rw);
26096+ AuDbgRcntInc(rw);
26097+ AuDbgWcntDec(rw);
26098+ downgrade_write(&rw->rwsem);
26099+}
26100+
26101+static inline void au_rw_write_lock(struct au_rwsem *rw)
26102+{
26103+ down_write(&rw->rwsem);
26104+ AuDbgWcntInc(rw);
26105+}
26106+
26107+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
26108+ unsigned int lsc)
26109+{
26110+ down_write_nested(&rw->rwsem, lsc);
26111+ AuDbgWcntInc(rw);
26112+}
1facf9fc 26113+
dece6358
AM
26114+static inline void au_rw_write_unlock(struct au_rwsem *rw)
26115+{
26116+ AuRwMustWriteLock(rw);
26117+ AuDbgWcntDec(rw);
26118+ up_write(&rw->rwsem);
26119+}
26120+
26121+/* why is not _nested version defined */
26122+static inline int au_rw_read_trylock(struct au_rwsem *rw)
26123+{
076b876e
AM
26124+ int ret;
26125+
26126+ ret = down_read_trylock(&rw->rwsem);
dece6358
AM
26127+ if (ret)
26128+ AuDbgRcntInc(rw);
26129+ return ret;
26130+}
26131+
26132+static inline int au_rw_write_trylock(struct au_rwsem *rw)
26133+{
076b876e
AM
26134+ int ret;
26135+
26136+ ret = down_write_trylock(&rw->rwsem);
dece6358
AM
26137+ if (ret)
26138+ AuDbgWcntInc(rw);
26139+ return ret;
26140+}
26141+
26142+#undef AuDbgCntInit
26143+#undef AuDbgRcntInc
26144+#undef AuDbgRcntDec
26145+#undef AuDbgWcntInc
26146+#undef AuDbgWcntDec
1facf9fc 26147+
26148+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
26149+static inline void prefix##_read_lock(param) \
dece6358 26150+{ au_rw_read_lock(rwsem); } \
1facf9fc 26151+static inline void prefix##_write_lock(param) \
dece6358 26152+{ au_rw_write_lock(rwsem); } \
1facf9fc 26153+static inline int prefix##_read_trylock(param) \
dece6358 26154+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 26155+static inline int prefix##_write_trylock(param) \
dece6358 26156+{ return au_rw_write_trylock(rwsem); }
1facf9fc 26157+/* why is not _nested version defined */
26158+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 26159+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 26160+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 26161+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 26162+
26163+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
26164+static inline void prefix##_read_unlock(param) \
dece6358 26165+{ au_rw_read_unlock(rwsem); } \
1facf9fc 26166+static inline void prefix##_write_unlock(param) \
dece6358 26167+{ au_rw_write_unlock(rwsem); } \
1facf9fc 26168+static inline void prefix##_downgrade_lock(param) \
dece6358 26169+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 26170+
26171+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
26172+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
26173+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
26174+
26175+#endif /* __KERNEL__ */
26176+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
26177diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
26178--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
26179+++ linux/fs/aufs/sbinfo.c 2015-11-11 17:21:46.922197217 +0100
26180@@ -0,0 +1,363 @@
1facf9fc 26181+/*
2000de60 26182+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 26183+ *
26184+ * This program, aufs is free software; you can redistribute it and/or modify
26185+ * it under the terms of the GNU General Public License as published by
26186+ * the Free Software Foundation; either version 2 of the License, or
26187+ * (at your option) any later version.
dece6358
AM
26188+ *
26189+ * This program is distributed in the hope that it will be useful,
26190+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26191+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26192+ * GNU General Public License for more details.
26193+ *
26194+ * You should have received a copy of the GNU General Public License
523b37e3 26195+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26196+ */
26197+
26198+/*
26199+ * superblock private data
26200+ */
26201+
26202+#include "aufs.h"
26203+
26204+/*
26205+ * they are necessary regardless sysfs is disabled.
26206+ */
26207+void au_si_free(struct kobject *kobj)
26208+{
86dc4139 26209+ int i;
1facf9fc 26210+ struct au_sbinfo *sbinfo;
b752ccd1 26211+ char *locked __maybe_unused; /* debug only */
1facf9fc 26212+
26213+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139
AM
26214+ for (i = 0; i < AuPlink_NHASH; i++)
26215+ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
e49829fe 26216+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
1facf9fc 26217+
c2c0f25c
AM
26218+ AuDebugOn(!hlist_empty(&sbinfo->si_symlink.head));
26219+
e49829fe 26220+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 26221+ au_br_free(sbinfo);
e49829fe 26222+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1
AM
26223+
26224+ AuDebugOn(radix_tree_gang_lookup
26225+ (&sbinfo->au_si_pid.tree, (void **)&locked,
26226+ /*first_index*/PID_MAX_DEFAULT - 1,
26227+ /*max_items*/sizeof(locked)/sizeof(*locked)));
26228+
1facf9fc 26229+ kfree(sbinfo->si_branch);
b752ccd1 26230+ kfree(sbinfo->au_si_pid.bitmap);
1facf9fc 26231+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 26232+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 26233+
26234+ kfree(sbinfo);
26235+}
26236+
26237+int au_si_alloc(struct super_block *sb)
26238+{
86dc4139 26239+ int err, i;
1facf9fc 26240+ struct au_sbinfo *sbinfo;
e49829fe 26241+ static struct lock_class_key aufs_si;
1facf9fc 26242+
26243+ err = -ENOMEM;
4a4d8108 26244+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 26245+ if (unlikely(!sbinfo))
26246+ goto out;
26247+
b752ccd1
AM
26248+ BUILD_BUG_ON(sizeof(unsigned long) !=
26249+ sizeof(*sbinfo->au_si_pid.bitmap));
26250+ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
26251+ sizeof(*sbinfo->au_si_pid.bitmap),
26252+ GFP_NOFS);
26253+ if (unlikely(!sbinfo->au_si_pid.bitmap))
26254+ goto out_sbinfo;
26255+
1facf9fc 26256+ /* will be reallocated separately */
26257+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
26258+ if (unlikely(!sbinfo->si_branch))
b752ccd1 26259+ goto out_pidmap;
1facf9fc 26260+
1facf9fc 26261+ err = sysaufs_si_init(sbinfo);
26262+ if (unlikely(err))
26263+ goto out_br;
26264+
26265+ au_nwt_init(&sbinfo->si_nowait);
dece6358 26266+ au_rw_init_wlock(&sbinfo->si_rwsem);
e49829fe 26267+ au_rw_class(&sbinfo->si_rwsem, &aufs_si);
b752ccd1
AM
26268+ spin_lock_init(&sbinfo->au_si_pid.tree_lock);
26269+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
26270+
7f207e10 26271+ atomic_long_set(&sbinfo->si_ninodes, 0);
7f207e10
AM
26272+ atomic_long_set(&sbinfo->si_nfiles, 0);
26273+
1facf9fc 26274+ sbinfo->si_bend = -1;
392086de 26275+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 26276+
26277+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
26278+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
26279+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
26280+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 26281+
076b876e
AM
26282+ au_fhsm_init(sbinfo);
26283+
e49829fe 26284+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 26285+
c2c0f25c
AM
26286+ au_sphl_init(&sbinfo->si_symlink);
26287+
392086de
AM
26288+ sbinfo->si_xino_jiffy = jiffies;
26289+ sbinfo->si_xino_expire
26290+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 26291+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 26292+ sbinfo->si_xino_brid = -1;
26293+ /* leave si_xib_last_pindex and si_xib_next_bit */
26294+
b912730e
AM
26295+ au_sphl_init(&sbinfo->si_aopen);
26296+
e49829fe 26297+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 26298+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
26299+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
26300+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
26301+
86dc4139
AM
26302+ for (i = 0; i < AuPlink_NHASH; i++)
26303+ au_sphl_init(sbinfo->si_plink + i);
1facf9fc 26304+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 26305+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 26306+
523b37e3
AM
26307+ au_sphl_init(&sbinfo->si_files);
26308+
1facf9fc 26309+ /* leave other members for sysaufs and si_mnt. */
26310+ sbinfo->si_sb = sb;
26311+ sb->s_fs_info = sbinfo;
b752ccd1 26312+ si_pid_set(sb);
1facf9fc 26313+ return 0; /* success */
26314+
4f0767ce 26315+out_br:
1facf9fc 26316+ kfree(sbinfo->si_branch);
4f0767ce 26317+out_pidmap:
b752ccd1 26318+ kfree(sbinfo->au_si_pid.bitmap);
4f0767ce 26319+out_sbinfo:
1facf9fc 26320+ kfree(sbinfo);
4f0767ce 26321+out:
1facf9fc 26322+ return err;
26323+}
26324+
26325+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
26326+{
26327+ int err, sz;
26328+ struct au_branch **brp;
26329+
dece6358
AM
26330+ AuRwMustWriteLock(&sbinfo->si_rwsem);
26331+
1facf9fc 26332+ err = -ENOMEM;
26333+ sz = sizeof(*brp) * (sbinfo->si_bend + 1);
26334+ if (unlikely(!sz))
26335+ sz = sizeof(*brp);
26336+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
26337+ if (brp) {
26338+ sbinfo->si_branch = brp;
26339+ err = 0;
26340+ }
26341+
26342+ return err;
26343+}
26344+
26345+/* ---------------------------------------------------------------------- */
26346+
26347+unsigned int au_sigen_inc(struct super_block *sb)
26348+{
26349+ unsigned int gen;
5527c038 26350+ struct inode *inode;
1facf9fc 26351+
dece6358
AM
26352+ SiMustWriteLock(sb);
26353+
1facf9fc 26354+ gen = ++au_sbi(sb)->si_generation;
26355+ au_update_digen(sb->s_root);
5527c038
JR
26356+ inode = d_inode(sb->s_root);
26357+ au_update_iigen(inode, /*half*/0);
26358+ inode->i_version++;
1facf9fc 26359+ return gen;
26360+}
26361+
26362+aufs_bindex_t au_new_br_id(struct super_block *sb)
26363+{
26364+ aufs_bindex_t br_id;
26365+ int i;
26366+ struct au_sbinfo *sbinfo;
26367+
dece6358
AM
26368+ SiMustWriteLock(sb);
26369+
1facf9fc 26370+ sbinfo = au_sbi(sb);
26371+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
26372+ br_id = ++sbinfo->si_last_br_id;
7f207e10 26373+ AuDebugOn(br_id < 0);
1facf9fc 26374+ if (br_id && au_br_index(sb, br_id) < 0)
26375+ return br_id;
26376+ }
26377+
26378+ return -1;
26379+}
26380+
26381+/* ---------------------------------------------------------------------- */
26382+
e49829fe
JR
26383+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
26384+int si_read_lock(struct super_block *sb, int flags)
26385+{
26386+ int err;
26387+
26388+ err = 0;
26389+ if (au_ftest_lock(flags, FLUSH))
26390+ au_nwt_flush(&au_sbi(sb)->si_nowait);
26391+
26392+ si_noflush_read_lock(sb);
26393+ err = au_plink_maint(sb, flags);
26394+ if (unlikely(err))
26395+ si_read_unlock(sb);
26396+
26397+ return err;
26398+}
26399+
26400+int si_write_lock(struct super_block *sb, int flags)
26401+{
26402+ int err;
26403+
26404+ if (au_ftest_lock(flags, FLUSH))
26405+ au_nwt_flush(&au_sbi(sb)->si_nowait);
26406+
26407+ si_noflush_write_lock(sb);
26408+ err = au_plink_maint(sb, flags);
26409+ if (unlikely(err))
26410+ si_write_unlock(sb);
26411+
26412+ return err;
26413+}
26414+
1facf9fc 26415+/* dentry and super_block lock. call at entry point */
e49829fe 26416+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 26417+{
e49829fe 26418+ int err;
027c5e7a 26419+ struct super_block *sb;
e49829fe 26420+
027c5e7a
AM
26421+ sb = dentry->d_sb;
26422+ err = si_read_lock(sb, flags);
26423+ if (unlikely(err))
26424+ goto out;
26425+
26426+ if (au_ftest_lock(flags, DW))
26427+ di_write_lock_child(dentry);
26428+ else
26429+ di_read_lock_child(dentry, flags);
26430+
26431+ if (au_ftest_lock(flags, GEN)) {
26432+ err = au_digen_test(dentry, au_sigen(sb));
79b8bda9
AM
26433+ if (!au_opt_test(au_mntflags(sb), UDBA_NONE))
26434+ AuDebugOn(!err && au_dbrange_test(dentry));
26435+ else if (!err)
26436+ err = au_dbrange_test(dentry);
027c5e7a
AM
26437+ if (unlikely(err))
26438+ aufs_read_unlock(dentry, flags);
e49829fe
JR
26439+ }
26440+
027c5e7a 26441+out:
e49829fe 26442+ return err;
1facf9fc 26443+}
26444+
26445+void aufs_read_unlock(struct dentry *dentry, int flags)
26446+{
26447+ if (au_ftest_lock(flags, DW))
26448+ di_write_unlock(dentry);
26449+ else
26450+ di_read_unlock(dentry, flags);
26451+ si_read_unlock(dentry->d_sb);
26452+}
26453+
26454+void aufs_write_lock(struct dentry *dentry)
26455+{
e49829fe 26456+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 26457+ di_write_lock_child(dentry);
26458+}
26459+
26460+void aufs_write_unlock(struct dentry *dentry)
26461+{
26462+ di_write_unlock(dentry);
26463+ si_write_unlock(dentry->d_sb);
26464+}
26465+
e49829fe 26466+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 26467+{
e49829fe 26468+ int err;
027c5e7a
AM
26469+ unsigned int sigen;
26470+ struct super_block *sb;
e49829fe 26471+
027c5e7a
AM
26472+ sb = d1->d_sb;
26473+ err = si_read_lock(sb, flags);
26474+ if (unlikely(err))
26475+ goto out;
26476+
26477+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
26478+
26479+ if (au_ftest_lock(flags, GEN)) {
26480+ sigen = au_sigen(sb);
26481+ err = au_digen_test(d1, sigen);
26482+ AuDebugOn(!err && au_dbrange_test(d1));
26483+ if (!err) {
26484+ err = au_digen_test(d2, sigen);
26485+ AuDebugOn(!err && au_dbrange_test(d2));
26486+ }
26487+ if (unlikely(err))
26488+ aufs_read_and_write_unlock2(d1, d2);
26489+ }
26490+
26491+out:
e49829fe 26492+ return err;
1facf9fc 26493+}
26494+
26495+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
26496+{
26497+ di_write_unlock2(d1, d2);
26498+ si_read_unlock(d1->d_sb);
26499+}
b752ccd1
AM
26500+
26501+/* ---------------------------------------------------------------------- */
26502+
26503+int si_pid_test_slow(struct super_block *sb)
26504+{
26505+ void *p;
26506+
26507+ rcu_read_lock();
26508+ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
26509+ rcu_read_unlock();
26510+
027c5e7a 26511+ return (long)!!p;
b752ccd1
AM
26512+}
26513+
26514+void si_pid_set_slow(struct super_block *sb)
26515+{
26516+ int err;
26517+ struct au_sbinfo *sbinfo;
26518+
26519+ AuDebugOn(si_pid_test_slow(sb));
26520+
26521+ sbinfo = au_sbi(sb);
26522+ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
26523+ AuDebugOn(err);
26524+ spin_lock(&sbinfo->au_si_pid.tree_lock);
26525+ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
027c5e7a 26526+ /*any valid ptr*/sb);
b752ccd1
AM
26527+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
26528+ AuDebugOn(err);
26529+ radix_tree_preload_end();
26530+}
26531+
26532+void si_pid_clr_slow(struct super_block *sb)
26533+{
26534+ void *p;
26535+ struct au_sbinfo *sbinfo;
26536+
26537+ AuDebugOn(!si_pid_test_slow(sb));
26538+
26539+ sbinfo = au_sbi(sb);
26540+ spin_lock(&sbinfo->au_si_pid.tree_lock);
26541+ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
26542+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
b752ccd1 26543+}
7f207e10
AM
26544diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
26545--- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 26546+++ linux/fs/aufs/spl.h 2015-09-24 10:47:58.254719746 +0200
523b37e3 26547@@ -0,0 +1,111 @@
1facf9fc 26548+/*
2000de60 26549+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 26550+ *
26551+ * This program, aufs is free software; you can redistribute it and/or modify
26552+ * it under the terms of the GNU General Public License as published by
26553+ * the Free Software Foundation; either version 2 of the License, or
26554+ * (at your option) any later version.
dece6358
AM
26555+ *
26556+ * This program is distributed in the hope that it will be useful,
26557+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26558+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26559+ * GNU General Public License for more details.
26560+ *
26561+ * You should have received a copy of the GNU General Public License
523b37e3 26562+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26563+ */
26564+
26565+/*
26566+ * simple list protected by a spinlock
26567+ */
26568+
26569+#ifndef __AUFS_SPL_H__
26570+#define __AUFS_SPL_H__
26571+
26572+#ifdef __KERNEL__
26573+
1facf9fc 26574+struct au_splhead {
26575+ spinlock_t spin;
26576+ struct list_head head;
26577+};
26578+
26579+static inline void au_spl_init(struct au_splhead *spl)
26580+{
26581+ spin_lock_init(&spl->spin);
26582+ INIT_LIST_HEAD(&spl->head);
26583+}
26584+
26585+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
26586+{
26587+ spin_lock(&spl->spin);
26588+ list_add(list, &spl->head);
26589+ spin_unlock(&spl->spin);
26590+}
26591+
26592+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
26593+{
26594+ spin_lock(&spl->spin);
26595+ list_del(list);
26596+ spin_unlock(&spl->spin);
26597+}
26598+
4a4d8108
AM
26599+static inline void au_spl_del_rcu(struct list_head *list,
26600+ struct au_splhead *spl)
26601+{
26602+ spin_lock(&spl->spin);
26603+ list_del_rcu(list);
26604+ spin_unlock(&spl->spin);
26605+}
26606+
86dc4139
AM
26607+/* ---------------------------------------------------------------------- */
26608+
26609+struct au_sphlhead {
26610+ spinlock_t spin;
26611+ struct hlist_head head;
26612+};
26613+
26614+static inline void au_sphl_init(struct au_sphlhead *sphl)
26615+{
26616+ spin_lock_init(&sphl->spin);
26617+ INIT_HLIST_HEAD(&sphl->head);
26618+}
26619+
26620+static inline void au_sphl_add(struct hlist_node *hlist,
26621+ struct au_sphlhead *sphl)
26622+{
26623+ spin_lock(&sphl->spin);
26624+ hlist_add_head(hlist, &sphl->head);
26625+ spin_unlock(&sphl->spin);
26626+}
26627+
26628+static inline void au_sphl_del(struct hlist_node *hlist,
26629+ struct au_sphlhead *sphl)
26630+{
26631+ spin_lock(&sphl->spin);
26632+ hlist_del(hlist);
26633+ spin_unlock(&sphl->spin);
26634+}
26635+
26636+static inline void au_sphl_del_rcu(struct hlist_node *hlist,
26637+ struct au_sphlhead *sphl)
26638+{
26639+ spin_lock(&sphl->spin);
26640+ hlist_del_rcu(hlist);
26641+ spin_unlock(&sphl->spin);
26642+}
26643+
26644+static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
26645+{
26646+ unsigned long cnt;
26647+ struct hlist_node *pos;
26648+
26649+ cnt = 0;
26650+ spin_lock(&sphl->spin);
26651+ hlist_for_each(pos, &sphl->head)
26652+ cnt++;
26653+ spin_unlock(&sphl->spin);
26654+ return cnt;
26655+}
26656+
1facf9fc 26657+#endif /* __KERNEL__ */
26658+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
26659diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
26660--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
26661+++ linux/fs/aufs/super.c 2015-11-11 17:21:46.922197217 +0100
26662@@ -0,0 +1,1035 @@
1facf9fc 26663+/*
2000de60 26664+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 26665+ *
26666+ * This program, aufs is free software; you can redistribute it and/or modify
26667+ * it under the terms of the GNU General Public License as published by
26668+ * the Free Software Foundation; either version 2 of the License, or
26669+ * (at your option) any later version.
dece6358
AM
26670+ *
26671+ * This program is distributed in the hope that it will be useful,
26672+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26673+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26674+ * GNU General Public License for more details.
26675+ *
26676+ * You should have received a copy of the GNU General Public License
523b37e3 26677+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26678+ */
26679+
26680+/*
26681+ * mount and super_block operations
26682+ */
26683+
f6c5ef8b 26684+#include <linux/mm.h>
1facf9fc 26685+#include <linux/seq_file.h>
26686+#include <linux/statfs.h>
7f207e10 26687+#include <linux/vmalloc.h>
1facf9fc 26688+#include "aufs.h"
26689+
26690+/*
26691+ * super_operations
26692+ */
26693+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
26694+{
26695+ struct au_icntnr *c;
26696+
26697+ c = au_cache_alloc_icntnr();
26698+ if (c) {
027c5e7a 26699+ au_icntnr_init(c);
1facf9fc 26700+ c->vfs_inode.i_version = 1; /* sigen(sb); */
26701+ c->iinfo.ii_hinode = NULL;
26702+ return &c->vfs_inode;
26703+ }
26704+ return NULL;
26705+}
26706+
027c5e7a
AM
26707+static void aufs_destroy_inode_cb(struct rcu_head *head)
26708+{
26709+ struct inode *inode = container_of(head, struct inode, i_rcu);
26710+
b4510431 26711+ INIT_HLIST_HEAD(&inode->i_dentry);
027c5e7a
AM
26712+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
26713+}
26714+
1facf9fc 26715+static void aufs_destroy_inode(struct inode *inode)
26716+{
26717+ au_iinfo_fin(inode);
027c5e7a 26718+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 26719+}
26720+
26721+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
26722+{
26723+ struct inode *inode;
26724+ int err;
26725+
26726+ inode = iget_locked(sb, ino);
26727+ if (unlikely(!inode)) {
26728+ inode = ERR_PTR(-ENOMEM);
26729+ goto out;
26730+ }
26731+ if (!(inode->i_state & I_NEW))
26732+ goto out;
26733+
26734+ err = au_xigen_new(inode);
26735+ if (!err)
26736+ err = au_iinfo_init(inode);
26737+ if (!err)
26738+ inode->i_version++;
26739+ else {
26740+ iget_failed(inode);
26741+ inode = ERR_PTR(err);
26742+ }
26743+
4f0767ce 26744+out:
1facf9fc 26745+ /* never return NULL */
26746+ AuDebugOn(!inode);
26747+ AuTraceErrPtr(inode);
26748+ return inode;
26749+}
26750+
26751+/* lock free root dinfo */
26752+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
26753+{
26754+ int err;
26755+ aufs_bindex_t bindex, bend;
26756+ struct path path;
4a4d8108 26757+ struct au_hdentry *hdp;
1facf9fc 26758+ struct au_branch *br;
076b876e 26759+ au_br_perm_str_t perm;
1facf9fc 26760+
26761+ err = 0;
26762+ bend = au_sbend(sb);
4a4d8108 26763+ hdp = au_di(sb->s_root)->di_hdentry;
1facf9fc 26764+ for (bindex = 0; !err && bindex <= bend; bindex++) {
26765+ br = au_sbr(sb, bindex);
86dc4139 26766+ path.mnt = au_br_mnt(br);
4a4d8108 26767+ path.dentry = hdp[bindex].hd_dentry;
1facf9fc 26768+ err = au_seq_path(seq, &path);
79b8bda9 26769+ if (!err) {
076b876e 26770+ au_optstr_br_perm(&perm, br->br_perm);
79b8bda9
AM
26771+ seq_printf(seq, "=%s", perm.a);
26772+ if (bindex != bend)
26773+ seq_putc(seq, ':');
1e00d052 26774+ }
1facf9fc 26775+ }
79b8bda9
AM
26776+ if (unlikely(err || seq_has_overflowed(seq)))
26777+ err = -E2BIG;
1facf9fc 26778+
26779+ return err;
26780+}
26781+
26782+static void au_show_wbr_create(struct seq_file *m, int v,
26783+ struct au_sbinfo *sbinfo)
26784+{
26785+ const char *pat;
26786+
dece6358
AM
26787+ AuRwMustAnyLock(&sbinfo->si_rwsem);
26788+
c2b27bf2 26789+ seq_puts(m, ",create=");
1facf9fc 26790+ pat = au_optstr_wbr_create(v);
26791+ switch (v) {
26792+ case AuWbrCreate_TDP:
26793+ case AuWbrCreate_RR:
26794+ case AuWbrCreate_MFS:
26795+ case AuWbrCreate_PMFS:
c2b27bf2 26796+ seq_puts(m, pat);
1facf9fc 26797+ break;
26798+ case AuWbrCreate_MFSV:
26799+ seq_printf(m, /*pat*/"mfs:%lu",
e49829fe
JR
26800+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26801+ / MSEC_PER_SEC);
1facf9fc 26802+ break;
26803+ case AuWbrCreate_PMFSV:
26804+ seq_printf(m, /*pat*/"pmfs:%lu",
e49829fe
JR
26805+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26806+ / MSEC_PER_SEC);
1facf9fc 26807+ break;
26808+ case AuWbrCreate_MFSRR:
26809+ seq_printf(m, /*pat*/"mfsrr:%llu",
26810+ sbinfo->si_wbr_mfs.mfsrr_watermark);
26811+ break;
26812+ case AuWbrCreate_MFSRRV:
26813+ seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
26814+ sbinfo->si_wbr_mfs.mfsrr_watermark,
e49829fe
JR
26815+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26816+ / MSEC_PER_SEC);
1facf9fc 26817+ break;
392086de
AM
26818+ case AuWbrCreate_PMFSRR:
26819+ seq_printf(m, /*pat*/"pmfsrr:%llu",
26820+ sbinfo->si_wbr_mfs.mfsrr_watermark);
26821+ break;
26822+ case AuWbrCreate_PMFSRRV:
26823+ seq_printf(m, /*pat*/"pmfsrr:%llu:%lu",
26824+ sbinfo->si_wbr_mfs.mfsrr_watermark,
26825+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26826+ / MSEC_PER_SEC);
26827+ break;
1facf9fc 26828+ }
26829+}
26830+
7eafdf33 26831+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 26832+{
26833+#ifdef CONFIG_SYSFS
26834+ return 0;
26835+#else
26836+ int err;
26837+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
26838+ aufs_bindex_t bindex, brid;
1facf9fc 26839+ struct qstr *name;
26840+ struct file *f;
26841+ struct dentry *d, *h_root;
4a4d8108 26842+ struct au_hdentry *hdp;
1facf9fc 26843+
dece6358
AM
26844+ AuRwMustAnyLock(&sbinfo->si_rwsem);
26845+
1facf9fc 26846+ err = 0;
1facf9fc 26847+ f = au_sbi(sb)->si_xib;
26848+ if (!f)
26849+ goto out;
26850+
26851+ /* stop printing the default xino path on the first writable branch */
26852+ h_root = NULL;
26853+ brid = au_xino_brid(sb);
26854+ if (brid >= 0) {
26855+ bindex = au_br_index(sb, brid);
4a4d8108
AM
26856+ hdp = au_di(sb->s_root)->di_hdentry;
26857+ h_root = hdp[0 + bindex].hd_dentry;
1facf9fc 26858+ }
2000de60 26859+ d = f->f_path.dentry;
1facf9fc 26860+ name = &d->d_name;
26861+ /* safe ->d_parent because the file is unlinked */
26862+ if (d->d_parent == h_root
26863+ && name->len == len
26864+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
26865+ goto out;
26866+
26867+ seq_puts(seq, ",xino=");
26868+ err = au_xino_path(seq, f);
26869+
4f0767ce 26870+out:
1facf9fc 26871+ return err;
26872+#endif
26873+}
26874+
26875+/* seq_file will re-call me in case of too long string */
7eafdf33 26876+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 26877+{
027c5e7a 26878+ int err;
1facf9fc 26879+ unsigned int mnt_flags, v;
26880+ struct super_block *sb;
26881+ struct au_sbinfo *sbinfo;
26882+
26883+#define AuBool(name, str) do { \
26884+ v = au_opt_test(mnt_flags, name); \
26885+ if (v != au_opt_test(AuOpt_Def, name)) \
26886+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
26887+} while (0)
26888+
26889+#define AuStr(name, str) do { \
26890+ v = mnt_flags & AuOptMask_##name; \
26891+ if (v != (AuOpt_Def & AuOptMask_##name)) \
26892+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
26893+} while (0)
26894+
26895+#define AuUInt(name, str, val) do { \
26896+ if (val != AUFS_##name##_DEF) \
26897+ seq_printf(m, "," #str "=%u", val); \
26898+} while (0)
26899+
7eafdf33 26900+ sb = dentry->d_sb;
c1595e42
JR
26901+ if (sb->s_flags & MS_POSIXACL)
26902+ seq_puts(m, ",acl");
26903+
26904+ /* lock free root dinfo */
1facf9fc 26905+ si_noflush_read_lock(sb);
26906+ sbinfo = au_sbi(sb);
26907+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
26908+
26909+ mnt_flags = au_mntflags(sb);
26910+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 26911+ err = au_show_xino(m, sb);
1facf9fc 26912+ if (unlikely(err))
26913+ goto out;
26914+ } else
26915+ seq_puts(m, ",noxino");
26916+
26917+ AuBool(TRUNC_XINO, trunc_xino);
26918+ AuStr(UDBA, udba);
dece6358 26919+ AuBool(SHWH, shwh);
1facf9fc 26920+ AuBool(PLINK, plink);
4a4d8108 26921+ AuBool(DIO, dio);
076b876e 26922+ AuBool(DIRPERM1, dirperm1);
1facf9fc 26923+
26924+ v = sbinfo->si_wbr_create;
26925+ if (v != AuWbrCreate_Def)
26926+ au_show_wbr_create(m, v, sbinfo);
26927+
26928+ v = sbinfo->si_wbr_copyup;
26929+ if (v != AuWbrCopyup_Def)
26930+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
26931+
26932+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
26933+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
26934+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
26935+
26936+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
26937+
027c5e7a
AM
26938+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
26939+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 26940+
26941+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
26942+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
26943+
076b876e
AM
26944+ au_fhsm_show(m, sbinfo);
26945+
1facf9fc 26946+ AuBool(SUM, sum);
26947+ /* AuBool(SUM_W, wsum); */
26948+ AuBool(WARN_PERM, warn_perm);
26949+ AuBool(VERBOSE, verbose);
26950+
4f0767ce 26951+out:
1facf9fc 26952+ /* be sure to print "br:" last */
26953+ if (!sysaufs_brs) {
26954+ seq_puts(m, ",br:");
26955+ au_show_brs(m, sb);
26956+ }
26957+ si_read_unlock(sb);
26958+ return 0;
26959+
1facf9fc 26960+#undef AuBool
26961+#undef AuStr
4a4d8108 26962+#undef AuUInt
1facf9fc 26963+}
26964+
26965+/* ---------------------------------------------------------------------- */
26966+
26967+/* sum mode which returns the summation for statfs(2) */
26968+
26969+static u64 au_add_till_max(u64 a, u64 b)
26970+{
26971+ u64 old;
26972+
26973+ old = a;
26974+ a += b;
92d182d2
AM
26975+ if (old <= a)
26976+ return a;
26977+ return ULLONG_MAX;
26978+}
26979+
26980+static u64 au_mul_till_max(u64 a, long mul)
26981+{
26982+ u64 old;
26983+
26984+ old = a;
26985+ a *= mul;
26986+ if (old <= a)
1facf9fc 26987+ return a;
26988+ return ULLONG_MAX;
26989+}
26990+
26991+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
26992+{
26993+ int err;
92d182d2 26994+ long bsize, factor;
1facf9fc 26995+ u64 blocks, bfree, bavail, files, ffree;
26996+ aufs_bindex_t bend, bindex, i;
26997+ unsigned char shared;
7f207e10 26998+ struct path h_path;
1facf9fc 26999+ struct super_block *h_sb;
27000+
92d182d2
AM
27001+ err = 0;
27002+ bsize = LONG_MAX;
27003+ files = 0;
27004+ ffree = 0;
1facf9fc 27005+ blocks = 0;
27006+ bfree = 0;
27007+ bavail = 0;
1facf9fc 27008+ bend = au_sbend(sb);
92d182d2 27009+ for (bindex = 0; bindex <= bend; bindex++) {
7f207e10
AM
27010+ h_path.mnt = au_sbr_mnt(sb, bindex);
27011+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 27012+ shared = 0;
92d182d2 27013+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 27014+ shared = (au_sbr_sb(sb, i) == h_sb);
27015+ if (shared)
27016+ continue;
27017+
27018+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
27019+ h_path.dentry = h_path.mnt->mnt_root;
27020+ err = vfs_statfs(&h_path, buf);
1facf9fc 27021+ if (unlikely(err))
27022+ goto out;
27023+
92d182d2
AM
27024+ if (bsize > buf->f_bsize) {
27025+ /*
27026+ * we will reduce bsize, so we have to expand blocks
27027+ * etc. to match them again
27028+ */
27029+ factor = (bsize / buf->f_bsize);
27030+ blocks = au_mul_till_max(blocks, factor);
27031+ bfree = au_mul_till_max(bfree, factor);
27032+ bavail = au_mul_till_max(bavail, factor);
27033+ bsize = buf->f_bsize;
27034+ }
27035+
27036+ factor = (buf->f_bsize / bsize);
27037+ blocks = au_add_till_max(blocks,
27038+ au_mul_till_max(buf->f_blocks, factor));
27039+ bfree = au_add_till_max(bfree,
27040+ au_mul_till_max(buf->f_bfree, factor));
27041+ bavail = au_add_till_max(bavail,
27042+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 27043+ files = au_add_till_max(files, buf->f_files);
27044+ ffree = au_add_till_max(ffree, buf->f_ffree);
27045+ }
27046+
92d182d2 27047+ buf->f_bsize = bsize;
1facf9fc 27048+ buf->f_blocks = blocks;
27049+ buf->f_bfree = bfree;
27050+ buf->f_bavail = bavail;
27051+ buf->f_files = files;
27052+ buf->f_ffree = ffree;
92d182d2 27053+ buf->f_frsize = 0;
1facf9fc 27054+
4f0767ce 27055+out:
1facf9fc 27056+ return err;
27057+}
27058+
27059+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
27060+{
27061+ int err;
7f207e10 27062+ struct path h_path;
1facf9fc 27063+ struct super_block *sb;
27064+
27065+ /* lock free root dinfo */
27066+ sb = dentry->d_sb;
27067+ si_noflush_read_lock(sb);
7f207e10 27068+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 27069+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
27070+ h_path.mnt = au_sbr_mnt(sb, 0);
27071+ h_path.dentry = h_path.mnt->mnt_root;
27072+ err = vfs_statfs(&h_path, buf);
27073+ } else
1facf9fc 27074+ err = au_statfs_sum(sb, buf);
27075+ si_read_unlock(sb);
27076+
27077+ if (!err) {
27078+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 27079+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 27080+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
27081+ }
27082+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
27083+
27084+ return err;
27085+}
27086+
27087+/* ---------------------------------------------------------------------- */
27088+
537831f9
AM
27089+static int aufs_sync_fs(struct super_block *sb, int wait)
27090+{
27091+ int err, e;
27092+ aufs_bindex_t bend, bindex;
27093+ struct au_branch *br;
27094+ struct super_block *h_sb;
27095+
27096+ err = 0;
27097+ si_noflush_read_lock(sb);
27098+ bend = au_sbend(sb);
27099+ for (bindex = 0; bindex <= bend; bindex++) {
27100+ br = au_sbr(sb, bindex);
27101+ if (!au_br_writable(br->br_perm))
27102+ continue;
27103+
27104+ h_sb = au_sbr_sb(sb, bindex);
27105+ if (h_sb->s_op->sync_fs) {
27106+ e = h_sb->s_op->sync_fs(h_sb, wait);
27107+ if (unlikely(e && !err))
27108+ err = e;
27109+ /* go on even if an error happens */
27110+ }
27111+ }
27112+ si_read_unlock(sb);
27113+
27114+ return err;
27115+}
27116+
27117+/* ---------------------------------------------------------------------- */
27118+
1facf9fc 27119+/* final actions when unmounting a file system */
27120+static void aufs_put_super(struct super_block *sb)
27121+{
27122+ struct au_sbinfo *sbinfo;
27123+
27124+ sbinfo = au_sbi(sb);
27125+ if (!sbinfo)
27126+ return;
27127+
1facf9fc 27128+ dbgaufs_si_fin(sbinfo);
27129+ kobject_put(&sbinfo->si_kobj);
27130+}
27131+
27132+/* ---------------------------------------------------------------------- */
27133+
7f207e10
AM
27134+void au_array_free(void *array)
27135+{
27136+ if (array) {
27137+ if (!is_vmalloc_addr(array))
27138+ kfree(array);
27139+ else
27140+ vfree(array);
27141+ }
27142+}
27143+
79b8bda9
AM
27144+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
27145+ struct super_block *sb, void *arg)
7f207e10
AM
27146+{
27147+ void *array;
076b876e 27148+ unsigned long long n, sz;
7f207e10
AM
27149+
27150+ array = NULL;
27151+ n = 0;
27152+ if (!*hint)
27153+ goto out;
27154+
27155+ if (*hint > ULLONG_MAX / sizeof(array)) {
27156+ array = ERR_PTR(-EMFILE);
27157+ pr_err("hint %llu\n", *hint);
27158+ goto out;
27159+ }
27160+
076b876e
AM
27161+ sz = sizeof(array) * *hint;
27162+ array = kzalloc(sz, GFP_NOFS);
7f207e10 27163+ if (unlikely(!array))
076b876e 27164+ array = vzalloc(sz);
7f207e10
AM
27165+ if (unlikely(!array)) {
27166+ array = ERR_PTR(-ENOMEM);
27167+ goto out;
27168+ }
27169+
79b8bda9 27170+ n = cb(sb, array, *hint, arg);
7f207e10
AM
27171+ AuDebugOn(n > *hint);
27172+
27173+out:
27174+ *hint = n;
27175+ return array;
27176+}
27177+
79b8bda9 27178+static unsigned long long au_iarray_cb(struct super_block *sb, void *a,
7f207e10
AM
27179+ unsigned long long max __maybe_unused,
27180+ void *arg)
27181+{
27182+ unsigned long long n;
27183+ struct inode **p, *inode;
27184+ struct list_head *head;
27185+
27186+ n = 0;
27187+ p = a;
27188+ head = arg;
79b8bda9 27189+ spin_lock(&sb->s_inode_list_lock);
7f207e10
AM
27190+ list_for_each_entry(inode, head, i_sb_list) {
27191+ if (!is_bad_inode(inode)
27192+ && au_ii(inode)->ii_bstart >= 0) {
2cbb1c4b
JR
27193+ spin_lock(&inode->i_lock);
27194+ if (atomic_read(&inode->i_count)) {
27195+ au_igrab(inode);
27196+ *p++ = inode;
27197+ n++;
27198+ AuDebugOn(n > max);
27199+ }
27200+ spin_unlock(&inode->i_lock);
7f207e10
AM
27201+ }
27202+ }
79b8bda9 27203+ spin_unlock(&sb->s_inode_list_lock);
7f207e10
AM
27204+
27205+ return n;
27206+}
27207+
27208+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
27209+{
27210+ *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
79b8bda9 27211+ return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes);
7f207e10
AM
27212+}
27213+
27214+void au_iarray_free(struct inode **a, unsigned long long max)
27215+{
27216+ unsigned long long ull;
27217+
27218+ for (ull = 0; ull < max; ull++)
27219+ iput(a[ull]);
27220+ au_array_free(a);
27221+}
27222+
27223+/* ---------------------------------------------------------------------- */
27224+
1facf9fc 27225+/*
27226+ * refresh dentry and inode at remount time.
27227+ */
027c5e7a
AM
27228+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
27229+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
27230+ struct dentry *parent)
1facf9fc 27231+{
27232+ int err;
1facf9fc 27233+
27234+ di_write_lock_child(dentry);
1facf9fc 27235+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
27236+ err = au_refresh_dentry(dentry, parent);
27237+ if (!err && dir_flags)
5527c038 27238+ au_hn_reset(d_inode(dentry), dir_flags);
1facf9fc 27239+ di_read_unlock(parent, AuLock_IR);
1facf9fc 27240+ di_write_unlock(dentry);
27241+
27242+ return err;
27243+}
27244+
027c5e7a
AM
27245+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
27246+ struct au_sbinfo *sbinfo,
79b8bda9 27247+ const unsigned int dir_flags, unsigned int do_dop)
1facf9fc 27248+{
027c5e7a
AM
27249+ int err;
27250+ struct dentry *parent;
027c5e7a
AM
27251+
27252+ err = 0;
27253+ parent = dget_parent(dentry);
27254+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
5527c038
JR
27255+ if (d_really_is_positive(dentry)) {
27256+ if (!d_is_dir(dentry))
027c5e7a
AM
27257+ err = au_do_refresh(dentry, /*dir_flags*/0,
27258+ parent);
27259+ else {
27260+ err = au_do_refresh(dentry, dir_flags, parent);
27261+ if (unlikely(err))
27262+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
27263+ }
27264+ } else
27265+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
27266+ AuDbgDentry(dentry);
27267+ }
27268+ dput(parent);
27269+
79b8bda9
AM
27270+ if (!err) {
27271+ if (do_dop)
27272+ au_refresh_dop(dentry, /*force_reval*/0);
27273+ } else
27274+ au_refresh_dop(dentry, /*force_reval*/1);
27275+
027c5e7a
AM
27276+ AuTraceErr(err);
27277+ return err;
1facf9fc 27278+}
27279+
79b8bda9 27280+static int au_refresh_d(struct super_block *sb, unsigned int do_dop)
1facf9fc 27281+{
27282+ int err, i, j, ndentry, e;
027c5e7a 27283+ unsigned int sigen;
1facf9fc 27284+ struct au_dcsub_pages dpages;
27285+ struct au_dpage *dpage;
027c5e7a
AM
27286+ struct dentry **dentries, *d;
27287+ struct au_sbinfo *sbinfo;
27288+ struct dentry *root = sb->s_root;
5527c038 27289+ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1);
1facf9fc 27290+
79b8bda9
AM
27291+ if (do_dop)
27292+ au_refresh_dop(root, /*force_reval*/0);
27293+
027c5e7a
AM
27294+ err = au_dpages_init(&dpages, GFP_NOFS);
27295+ if (unlikely(err))
1facf9fc 27296+ goto out;
027c5e7a
AM
27297+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
27298+ if (unlikely(err))
1facf9fc 27299+ goto out_dpages;
1facf9fc 27300+
027c5e7a
AM
27301+ sigen = au_sigen(sb);
27302+ sbinfo = au_sbi(sb);
27303+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 27304+ dpage = dpages.dpages + i;
27305+ dentries = dpage->dentries;
27306+ ndentry = dpage->ndentry;
027c5e7a 27307+ for (j = 0; j < ndentry; j++) {
1facf9fc 27308+ d = dentries[j];
79b8bda9
AM
27309+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags,
27310+ do_dop);
027c5e7a
AM
27311+ if (unlikely(e && !err))
27312+ err = e;
27313+ /* go on even err */
1facf9fc 27314+ }
27315+ }
27316+
4f0767ce 27317+out_dpages:
1facf9fc 27318+ au_dpages_free(&dpages);
4f0767ce 27319+out:
1facf9fc 27320+ return err;
27321+}
27322+
027c5e7a 27323+static int au_refresh_i(struct super_block *sb)
1facf9fc 27324+{
027c5e7a
AM
27325+ int err, e;
27326+ unsigned int sigen;
27327+ unsigned long long max, ull;
27328+ struct inode *inode, **array;
1facf9fc 27329+
027c5e7a
AM
27330+ array = au_iarray_alloc(sb, &max);
27331+ err = PTR_ERR(array);
27332+ if (IS_ERR(array))
27333+ goto out;
1facf9fc 27334+
27335+ err = 0;
027c5e7a
AM
27336+ sigen = au_sigen(sb);
27337+ for (ull = 0; ull < max; ull++) {
27338+ inode = array[ull];
076b876e
AM
27339+ if (unlikely(!inode))
27340+ break;
537831f9 27341+ if (au_iigen(inode, NULL) != sigen) {
1facf9fc 27342+ ii_write_lock_child(inode);
027c5e7a 27343+ e = au_refresh_hinode_self(inode);
1facf9fc 27344+ ii_write_unlock(inode);
27345+ if (unlikely(e)) {
027c5e7a 27346+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 27347+ if (!err)
27348+ err = e;
27349+ /* go on even if err */
27350+ }
27351+ }
1facf9fc 27352+ }
27353+
027c5e7a 27354+ au_iarray_free(array, max);
1facf9fc 27355+
4f0767ce 27356+out:
1facf9fc 27357+ return err;
27358+}
27359+
79b8bda9 27360+static void au_remount_refresh(struct super_block *sb, unsigned int do_dop)
1facf9fc 27361+{
027c5e7a
AM
27362+ int err, e;
27363+ unsigned int udba;
27364+ aufs_bindex_t bindex, bend;
1facf9fc 27365+ struct dentry *root;
27366+ struct inode *inode;
027c5e7a 27367+ struct au_branch *br;
79b8bda9 27368+ struct au_sbinfo *sbi;
1facf9fc 27369+
27370+ au_sigen_inc(sb);
79b8bda9
AM
27371+ sbi = au_sbi(sb);
27372+ au_fclr_si(sbi, FAILED_REFRESH_DIR);
1facf9fc 27373+
27374+ root = sb->s_root;
27375+ DiMustNoWaiters(root);
5527c038 27376+ inode = d_inode(root);
1facf9fc 27377+ IiMustNoWaiters(inode);
1facf9fc 27378+
027c5e7a
AM
27379+ udba = au_opt_udba(sb);
27380+ bend = au_sbend(sb);
27381+ for (bindex = 0; bindex <= bend; bindex++) {
27382+ br = au_sbr(sb, bindex);
27383+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 27384+ if (unlikely(err))
027c5e7a
AM
27385+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
27386+ bindex, err);
27387+ /* go on even if err */
1facf9fc 27388+ }
027c5e7a 27389+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 27390+
79b8bda9
AM
27391+ if (do_dop) {
27392+ if (au_ftest_si(sbi, NO_DREVAL)) {
27393+ AuDebugOn(sb->s_d_op == &aufs_dop_noreval);
27394+ sb->s_d_op = &aufs_dop_noreval;
27395+ } else {
27396+ AuDebugOn(sb->s_d_op == &aufs_dop);
27397+ sb->s_d_op = &aufs_dop;
27398+ }
27399+ pr_info("reset to %pf\n", sb->s_d_op);
27400+ }
27401+
027c5e7a 27402+ di_write_unlock(root);
79b8bda9 27403+ err = au_refresh_d(sb, do_dop);
027c5e7a
AM
27404+ e = au_refresh_i(sb);
27405+ if (unlikely(e && !err))
27406+ err = e;
1facf9fc 27407+ /* aufs_write_lock() calls ..._child() */
27408+ di_write_lock_child(root);
027c5e7a
AM
27409+
27410+ au_cpup_attr_all(inode, /*force*/1);
27411+
27412+ if (unlikely(err))
27413+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 27414+}
27415+
27416+/* stop extra interpretation of errno in mount(8), and strange error messages */
27417+static int cvt_err(int err)
27418+{
27419+ AuTraceErr(err);
27420+
27421+ switch (err) {
27422+ case -ENOENT:
27423+ case -ENOTDIR:
27424+ case -EEXIST:
27425+ case -EIO:
27426+ err = -EINVAL;
27427+ }
27428+ return err;
27429+}
27430+
27431+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
27432+{
4a4d8108
AM
27433+ int err, do_dx;
27434+ unsigned int mntflags;
1facf9fc 27435+ struct au_opts opts;
27436+ struct dentry *root;
27437+ struct inode *inode;
27438+ struct au_sbinfo *sbinfo;
27439+
27440+ err = 0;
27441+ root = sb->s_root;
27442+ if (!data || !*data) {
e49829fe
JR
27443+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
27444+ if (!err) {
27445+ di_write_lock_child(root);
27446+ err = au_opts_verify(sb, *flags, /*pending*/0);
27447+ aufs_write_unlock(root);
27448+ }
1facf9fc 27449+ goto out;
27450+ }
27451+
27452+ err = -ENOMEM;
27453+ memset(&opts, 0, sizeof(opts));
27454+ opts.opt = (void *)__get_free_page(GFP_NOFS);
27455+ if (unlikely(!opts.opt))
27456+ goto out;
27457+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
27458+ opts.flags = AuOpts_REMOUNT;
27459+ opts.sb_flags = *flags;
27460+
27461+ /* parse it before aufs lock */
27462+ err = au_opts_parse(sb, data, &opts);
27463+ if (unlikely(err))
27464+ goto out_opts;
27465+
27466+ sbinfo = au_sbi(sb);
5527c038 27467+ inode = d_inode(root);
1facf9fc 27468+ mutex_lock(&inode->i_mutex);
e49829fe
JR
27469+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
27470+ if (unlikely(err))
27471+ goto out_mtx;
27472+ di_write_lock_child(root);
1facf9fc 27473+
27474+ /* au_opts_remount() may return an error */
27475+ err = au_opts_remount(sb, &opts);
27476+ au_opts_free(&opts);
27477+
027c5e7a 27478+ if (au_ftest_opts(opts.flags, REFRESH))
79b8bda9 27479+ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_DOP));
1facf9fc 27480+
4a4d8108
AM
27481+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
27482+ mntflags = au_mntflags(sb);
27483+ do_dx = !!au_opt_test(mntflags, DIO);
27484+ au_dy_arefresh(do_dx);
27485+ }
27486+
076b876e 27487+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
1facf9fc 27488+ aufs_write_unlock(root);
953406b4 27489+
e49829fe
JR
27490+out_mtx:
27491+ mutex_unlock(&inode->i_mutex);
4f0767ce 27492+out_opts:
1facf9fc 27493+ free_page((unsigned long)opts.opt);
4f0767ce 27494+out:
1facf9fc 27495+ err = cvt_err(err);
27496+ AuTraceErr(err);
27497+ return err;
27498+}
27499+
4a4d8108 27500+static const struct super_operations aufs_sop = {
1facf9fc 27501+ .alloc_inode = aufs_alloc_inode,
27502+ .destroy_inode = aufs_destroy_inode,
b752ccd1 27503+ /* always deleting, no clearing */
1facf9fc 27504+ .drop_inode = generic_delete_inode,
27505+ .show_options = aufs_show_options,
27506+ .statfs = aufs_statfs,
27507+ .put_super = aufs_put_super,
537831f9 27508+ .sync_fs = aufs_sync_fs,
1facf9fc 27509+ .remount_fs = aufs_remount_fs
27510+};
27511+
27512+/* ---------------------------------------------------------------------- */
27513+
27514+static int alloc_root(struct super_block *sb)
27515+{
27516+ int err;
27517+ struct inode *inode;
27518+ struct dentry *root;
27519+
27520+ err = -ENOMEM;
27521+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
27522+ err = PTR_ERR(inode);
27523+ if (IS_ERR(inode))
27524+ goto out;
27525+
27526+ inode->i_op = &aufs_dir_iop;
27527+ inode->i_fop = &aufs_dir_fop;
27528+ inode->i_mode = S_IFDIR;
9dbd164d 27529+ set_nlink(inode, 2);
1facf9fc 27530+ unlock_new_inode(inode);
27531+
92d182d2 27532+ root = d_make_root(inode);
1facf9fc 27533+ if (unlikely(!root))
92d182d2 27534+ goto out;
1facf9fc 27535+ err = PTR_ERR(root);
27536+ if (IS_ERR(root))
92d182d2 27537+ goto out;
1facf9fc 27538+
4a4d8108 27539+ err = au_di_init(root);
1facf9fc 27540+ if (!err) {
27541+ sb->s_root = root;
27542+ return 0; /* success */
27543+ }
27544+ dput(root);
1facf9fc 27545+
4f0767ce 27546+out:
1facf9fc 27547+ return err;
1facf9fc 27548+}
27549+
27550+static int aufs_fill_super(struct super_block *sb, void *raw_data,
27551+ int silent __maybe_unused)
27552+{
27553+ int err;
27554+ struct au_opts opts;
79b8bda9 27555+ struct au_sbinfo *sbinfo;
1facf9fc 27556+ struct dentry *root;
27557+ struct inode *inode;
27558+ char *arg = raw_data;
27559+
27560+ if (unlikely(!arg || !*arg)) {
27561+ err = -EINVAL;
4a4d8108 27562+ pr_err("no arg\n");
1facf9fc 27563+ goto out;
27564+ }
27565+
27566+ err = -ENOMEM;
27567+ memset(&opts, 0, sizeof(opts));
27568+ opts.opt = (void *)__get_free_page(GFP_NOFS);
27569+ if (unlikely(!opts.opt))
27570+ goto out;
27571+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
27572+ opts.sb_flags = sb->s_flags;
27573+
27574+ err = au_si_alloc(sb);
27575+ if (unlikely(err))
27576+ goto out_opts;
79b8bda9 27577+ sbinfo = au_sbi(sb);
1facf9fc 27578+
27579+ /* all timestamps always follow the ones on the branch */
27580+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
27581+ sb->s_op = &aufs_sop;
027c5e7a 27582+ sb->s_d_op = &aufs_dop;
1facf9fc 27583+ sb->s_magic = AUFS_SUPER_MAGIC;
27584+ sb->s_maxbytes = 0;
c1595e42 27585+ sb->s_stack_depth = 1;
1facf9fc 27586+ au_export_init(sb);
c1595e42 27587+ /* au_xattr_init(sb); */
1facf9fc 27588+
27589+ err = alloc_root(sb);
27590+ if (unlikely(err)) {
27591+ si_write_unlock(sb);
27592+ goto out_info;
27593+ }
27594+ root = sb->s_root;
5527c038 27595+ inode = d_inode(root);
1facf9fc 27596+
27597+ /*
27598+ * actually we can parse options regardless aufs lock here.
27599+ * but at remount time, parsing must be done before aufs lock.
27600+ * so we follow the same rule.
27601+ */
27602+ ii_write_lock_parent(inode);
27603+ aufs_write_unlock(root);
27604+ err = au_opts_parse(sb, arg, &opts);
27605+ if (unlikely(err))
27606+ goto out_root;
27607+
27608+ /* lock vfs_inode first, then aufs. */
27609+ mutex_lock(&inode->i_mutex);
1facf9fc 27610+ aufs_write_lock(root);
27611+ err = au_opts_mount(sb, &opts);
27612+ au_opts_free(&opts);
79b8bda9
AM
27613+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) {
27614+ sb->s_d_op = &aufs_dop_noreval;
27615+ pr_info("%pf\n", sb->s_d_op);
27616+ au_refresh_dop(root, /*force_reval*/0);
27617+ }
1facf9fc 27618+ aufs_write_unlock(root);
27619+ mutex_unlock(&inode->i_mutex);
4a4d8108
AM
27620+ if (!err)
27621+ goto out_opts; /* success */
1facf9fc 27622+
4f0767ce 27623+out_root:
1facf9fc 27624+ dput(root);
27625+ sb->s_root = NULL;
4f0767ce 27626+out_info:
79b8bda9
AM
27627+ dbgaufs_si_fin(sbinfo);
27628+ kobject_put(&sbinfo->si_kobj);
1facf9fc 27629+ sb->s_fs_info = NULL;
4f0767ce 27630+out_opts:
1facf9fc 27631+ free_page((unsigned long)opts.opt);
4f0767ce 27632+out:
1facf9fc 27633+ AuTraceErr(err);
27634+ err = cvt_err(err);
27635+ AuTraceErr(err);
27636+ return err;
27637+}
27638+
27639+/* ---------------------------------------------------------------------- */
27640+
027c5e7a
AM
27641+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
27642+ const char *dev_name __maybe_unused,
27643+ void *raw_data)
1facf9fc 27644+{
027c5e7a 27645+ struct dentry *root;
1facf9fc 27646+ struct super_block *sb;
27647+
27648+ /* all timestamps always follow the ones on the branch */
27649+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
27650+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
27651+ if (IS_ERR(root))
27652+ goto out;
27653+
27654+ sb = root->d_sb;
27655+ si_write_lock(sb, !AuLock_FLUSH);
27656+ sysaufs_brs_add(sb, 0);
27657+ si_write_unlock(sb);
27658+ au_sbilist_add(sb);
27659+
27660+out:
27661+ return root;
1facf9fc 27662+}
27663+
e49829fe
JR
27664+static void aufs_kill_sb(struct super_block *sb)
27665+{
27666+ struct au_sbinfo *sbinfo;
27667+
27668+ sbinfo = au_sbi(sb);
27669+ if (sbinfo) {
27670+ au_sbilist_del(sb);
27671+ aufs_write_lock(sb->s_root);
076b876e 27672+ au_fhsm_fin(sb);
e49829fe
JR
27673+ if (sbinfo->si_wbr_create_ops->fin)
27674+ sbinfo->si_wbr_create_ops->fin(sb);
27675+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
27676+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
79b8bda9 27677+ au_remount_refresh(sb, /*do_dop*/0);
e49829fe
JR
27678+ }
27679+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
27680+ au_plink_put(sb, /*verbose*/1);
27681+ au_xino_clr(sb);
1e00d052 27682+ sbinfo->si_sb = NULL;
e49829fe 27683+ aufs_write_unlock(sb->s_root);
e49829fe
JR
27684+ au_nwt_flush(&sbinfo->si_nowait);
27685+ }
98d9a5b1 27686+ kill_anon_super(sb);
e49829fe
JR
27687+}
27688+
1facf9fc 27689+struct file_system_type aufs_fs_type = {
27690+ .name = AUFS_FSTYPE,
c06a8ce3
AM
27691+ /* a race between rename and others */
27692+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 27693+ .mount = aufs_mount,
e49829fe 27694+ .kill_sb = aufs_kill_sb,
1facf9fc 27695+ /* no need to __module_get() and module_put(). */
27696+ .owner = THIS_MODULE,
27697+};
7f207e10
AM
27698diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
27699--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
27700+++ linux/fs/aufs/super.h 2015-11-11 17:21:46.922197217 +0100
27701@@ -0,0 +1,640 @@
1facf9fc 27702+/*
2000de60 27703+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 27704+ *
27705+ * This program, aufs is free software; you can redistribute it and/or modify
27706+ * it under the terms of the GNU General Public License as published by
27707+ * the Free Software Foundation; either version 2 of the License, or
27708+ * (at your option) any later version.
dece6358
AM
27709+ *
27710+ * This program is distributed in the hope that it will be useful,
27711+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27712+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27713+ * GNU General Public License for more details.
27714+ *
27715+ * You should have received a copy of the GNU General Public License
523b37e3 27716+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27717+ */
27718+
27719+/*
27720+ * super_block operations
27721+ */
27722+
27723+#ifndef __AUFS_SUPER_H__
27724+#define __AUFS_SUPER_H__
27725+
27726+#ifdef __KERNEL__
27727+
27728+#include <linux/fs.h>
5527c038 27729+#include <linux/kobject.h>
1facf9fc 27730+#include "rwsem.h"
27731+#include "spl.h"
27732+#include "wkq.h"
27733+
1facf9fc 27734+/* policies to select one among multiple writable branches */
27735+struct au_wbr_copyup_operations {
27736+ int (*copyup)(struct dentry *dentry);
27737+};
27738+
392086de
AM
27739+#define AuWbr_DIR 1 /* target is a dir */
27740+#define AuWbr_PARENT (1 << 1) /* always require a parent */
27741+
27742+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
27743+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
27744+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
27745+
1facf9fc 27746+struct au_wbr_create_operations {
392086de 27747+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 27748+ int (*init)(struct super_block *sb);
27749+ int (*fin)(struct super_block *sb);
27750+};
27751+
27752+struct au_wbr_mfs {
27753+ struct mutex mfs_lock; /* protect this structure */
27754+ unsigned long mfs_jiffy;
27755+ unsigned long mfs_expire;
27756+ aufs_bindex_t mfs_bindex;
27757+
27758+ unsigned long long mfsrr_bytes;
27759+ unsigned long long mfsrr_watermark;
27760+};
27761+
86dc4139
AM
27762+struct pseudo_link {
27763+ union {
27764+ struct hlist_node hlist;
27765+ struct rcu_head rcu;
27766+ };
27767+ struct inode *inode;
27768+};
27769+
27770+#define AuPlink_NHASH 100
27771+static inline int au_plink_hash(ino_t ino)
27772+{
27773+ return ino % AuPlink_NHASH;
27774+}
27775+
076b876e
AM
27776+/* File-based Hierarchical Storage Management */
27777+struct au_fhsm {
27778+#ifdef CONFIG_AUFS_FHSM
27779+ /* allow only one process who can receive the notification */
27780+ spinlock_t fhsm_spin;
27781+ pid_t fhsm_pid;
27782+ wait_queue_head_t fhsm_wqh;
27783+ atomic_t fhsm_readable;
27784+
c1595e42 27785+ /* these are protected by si_rwsem */
076b876e 27786+ unsigned long fhsm_expire;
c1595e42 27787+ aufs_bindex_t fhsm_bottom;
076b876e
AM
27788+#endif
27789+};
27790+
1facf9fc 27791+struct au_branch;
27792+struct au_sbinfo {
27793+ /* nowait tasks in the system-wide workqueue */
27794+ struct au_nowait_tasks si_nowait;
27795+
b752ccd1
AM
27796+ /*
27797+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
27798+ * rwsem for au_sbinfo is necessary.
27799+ */
dece6358 27800+ struct au_rwsem si_rwsem;
1facf9fc 27801+
b752ccd1
AM
27802+ /* prevent recursive locking in deleting inode */
27803+ struct {
27804+ unsigned long *bitmap;
27805+ spinlock_t tree_lock;
27806+ struct radix_tree_root tree;
27807+ } au_si_pid;
27808+
7f207e10 27809+ /*
523b37e3
AM
27810+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
27811+ * remount.
7f207e10
AM
27812+ */
27813+ atomic_long_t si_ninodes, si_nfiles;
27814+
1facf9fc 27815+ /* branch management */
27816+ unsigned int si_generation;
27817+
2000de60 27818+ /* see AuSi_ flags */
1facf9fc 27819+ unsigned char au_si_status;
27820+
27821+ aufs_bindex_t si_bend;
7f207e10
AM
27822+
27823+ /* dirty trick to keep br_id plus */
27824+ unsigned int si_last_br_id :
27825+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 27826+ struct au_branch **si_branch;
27827+
27828+ /* policy to select a writable branch */
27829+ unsigned char si_wbr_copyup;
27830+ unsigned char si_wbr_create;
27831+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
27832+ struct au_wbr_create_operations *si_wbr_create_ops;
27833+
27834+ /* round robin */
27835+ atomic_t si_wbr_rr_next;
27836+
27837+ /* most free space */
27838+ struct au_wbr_mfs si_wbr_mfs;
27839+
076b876e
AM
27840+ /* File-based Hierarchical Storage Management */
27841+ struct au_fhsm si_fhsm;
27842+
1facf9fc 27843+ /* mount flags */
27844+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
27845+ unsigned int si_mntflags;
27846+
c2c0f25c
AM
27847+ /* symlink to follow_link() and put_link() */
27848+ struct au_sphlhead si_symlink;
27849+
1facf9fc 27850+ /* external inode number (bitmap and translation table) */
5527c038
JR
27851+ vfs_readf_t si_xread;
27852+ vfs_writef_t si_xwrite;
1facf9fc 27853+ struct file *si_xib;
27854+ struct mutex si_xib_mtx; /* protect xib members */
27855+ unsigned long *si_xib_buf;
27856+ unsigned long si_xib_last_pindex;
27857+ int si_xib_next_bit;
27858+ aufs_bindex_t si_xino_brid;
392086de
AM
27859+ unsigned long si_xino_jiffy;
27860+ unsigned long si_xino_expire;
1facf9fc 27861+ /* reserved for future use */
27862+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
27863+
27864+#ifdef CONFIG_AUFS_EXPORT
27865+ /* i_generation */
27866+ struct file *si_xigen;
27867+ atomic_t si_xigen_next;
27868+#endif
27869+
b912730e
AM
27870+ /* dirty trick to suppoer atomic_open */
27871+ struct au_sphlhead si_aopen;
27872+
1facf9fc 27873+ /* vdir parameters */
e49829fe 27874+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 27875+ unsigned int si_rdblk; /* deblk size */
27876+ unsigned int si_rdhash; /* hash size */
27877+
27878+ /*
27879+ * If the number of whiteouts are larger than si_dirwh, leave all of
27880+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
27881+ * future fsck.aufs or kernel thread will remove them later.
27882+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
27883+ */
27884+ unsigned int si_dirwh;
27885+
1facf9fc 27886+ /* pseudo_link list */
86dc4139 27887+ struct au_sphlhead si_plink[AuPlink_NHASH];
1facf9fc 27888+ wait_queue_head_t si_plink_wq;
4a4d8108 27889+ spinlock_t si_plink_maint_lock;
e49829fe 27890+ pid_t si_plink_maint_pid;
1facf9fc 27891+
523b37e3
AM
27892+ /* file list */
27893+ struct au_sphlhead si_files;
27894+
1facf9fc 27895+ /*
27896+ * sysfs and lifetime management.
27897+ * this is not a small structure and it may be a waste of memory in case
27898+ * of sysfs is disabled, particulary when many aufs-es are mounted.
27899+ * but using sysfs is majority.
27900+ */
27901+ struct kobject si_kobj;
27902+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
27903+ struct dentry *si_dbgaufs;
27904+ struct dentry *si_dbgaufs_plink;
27905+ struct dentry *si_dbgaufs_xib;
1facf9fc 27906+#ifdef CONFIG_AUFS_EXPORT
27907+ struct dentry *si_dbgaufs_xigen;
27908+#endif
27909+#endif
27910+
e49829fe
JR
27911+#ifdef CONFIG_AUFS_SBILIST
27912+ struct list_head si_list;
27913+#endif
27914+
1facf9fc 27915+ /* dirty, necessary for unmounting, sysfs and sysrq */
27916+ struct super_block *si_sb;
27917+};
27918+
dece6358
AM
27919+/* sbinfo status flags */
27920+/*
27921+ * set true when refresh_dirs() failed at remount time.
27922+ * then try refreshing dirs at access time again.
27923+ * if it is false, refreshing dirs at access time is unnecesary
27924+ */
027c5e7a 27925+#define AuSi_FAILED_REFRESH_DIR 1
076b876e
AM
27926+
27927+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
79b8bda9 27928+#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */
076b876e
AM
27929+
27930+#ifndef CONFIG_AUFS_FHSM
27931+#undef AuSi_FHSM
27932+#define AuSi_FHSM 0
27933+#endif
27934+
dece6358
AM
27935+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
27936+ unsigned int flag)
27937+{
27938+ AuRwMustAnyLock(&sbi->si_rwsem);
27939+ return sbi->au_si_status & flag;
27940+}
27941+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
27942+#define au_fset_si(sbinfo, name) do { \
27943+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
27944+ (sbinfo)->au_si_status |= AuSi_##name; \
27945+} while (0)
27946+#define au_fclr_si(sbinfo, name) do { \
27947+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
27948+ (sbinfo)->au_si_status &= ~AuSi_##name; \
27949+} while (0)
27950+
1facf9fc 27951+/* ---------------------------------------------------------------------- */
27952+
27953+/* policy to select one among writable branches */
4a4d8108
AM
27954+#define AuWbrCopyup(sbinfo, ...) \
27955+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
27956+#define AuWbrCreate(sbinfo, ...) \
27957+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 27958+
27959+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
27960+#define AuLock_DW 1 /* write-lock dentry */
27961+#define AuLock_IR (1 << 1) /* read-lock inode */
27962+#define AuLock_IW (1 << 2) /* write-lock inode */
27963+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
27964+#define AuLock_DIR (1 << 4) /* target is a dir */
e49829fe
JR
27965+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
27966+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 27967+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 27968+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
27969+#define au_fset_lock(flags, name) \
27970+ do { (flags) |= AuLock_##name; } while (0)
27971+#define au_fclr_lock(flags, name) \
27972+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 27973+
27974+/* ---------------------------------------------------------------------- */
27975+
27976+/* super.c */
27977+extern struct file_system_type aufs_fs_type;
27978+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
79b8bda9
AM
27979+typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array,
27980+ unsigned long long max, void *arg);
7f207e10 27981+void au_array_free(void *array);
79b8bda9
AM
27982+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb,
27983+ struct super_block *sb, void *arg);
7f207e10
AM
27984+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
27985+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 27986+
27987+/* sbinfo.c */
27988+void au_si_free(struct kobject *kobj);
27989+int au_si_alloc(struct super_block *sb);
27990+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
27991+
27992+unsigned int au_sigen_inc(struct super_block *sb);
27993+aufs_bindex_t au_new_br_id(struct super_block *sb);
27994+
e49829fe
JR
27995+int si_read_lock(struct super_block *sb, int flags);
27996+int si_write_lock(struct super_block *sb, int flags);
27997+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 27998+void aufs_read_unlock(struct dentry *dentry, int flags);
27999+void aufs_write_lock(struct dentry *dentry);
28000+void aufs_write_unlock(struct dentry *dentry);
e49829fe 28001+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 28002+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
28003+
b752ccd1
AM
28004+int si_pid_test_slow(struct super_block *sb);
28005+void si_pid_set_slow(struct super_block *sb);
28006+void si_pid_clr_slow(struct super_block *sb);
28007+
1facf9fc 28008+/* wbr_policy.c */
28009+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
28010+extern struct au_wbr_create_operations au_wbr_create_ops[];
28011+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2 28012+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
076b876e 28013+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart);
c2b27bf2
AM
28014+
28015+/* mvdown.c */
28016+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 28017+
076b876e
AM
28018+#ifdef CONFIG_AUFS_FHSM
28019+/* fhsm.c */
28020+
28021+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
28022+{
28023+ pid_t pid;
28024+
28025+ spin_lock(&fhsm->fhsm_spin);
28026+ pid = fhsm->fhsm_pid;
28027+ spin_unlock(&fhsm->fhsm_spin);
28028+
28029+ return pid;
28030+}
28031+
28032+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
28033+void au_fhsm_wrote_all(struct super_block *sb, int force);
28034+int au_fhsm_fd(struct super_block *sb, int oflags);
28035+int au_fhsm_br_alloc(struct au_branch *br);
c1595e42 28036+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
076b876e
AM
28037+void au_fhsm_fin(struct super_block *sb);
28038+void au_fhsm_init(struct au_sbinfo *sbinfo);
28039+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
28040+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
28041+#else
28042+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
28043+ int force)
28044+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
28045+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
c1595e42
JR
28046+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
28047+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
28048+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
076b876e
AM
28049+AuStubVoid(au_fhsm_fin, struct super_block *sb)
28050+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
28051+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
28052+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
28053+#endif
28054+
1facf9fc 28055+/* ---------------------------------------------------------------------- */
28056+
28057+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
28058+{
28059+ return sb->s_fs_info;
28060+}
28061+
28062+/* ---------------------------------------------------------------------- */
28063+
28064+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 28065+int au_test_nfsd(void);
1facf9fc 28066+void au_export_init(struct super_block *sb);
b752ccd1 28067+void au_xigen_inc(struct inode *inode);
1facf9fc 28068+int au_xigen_new(struct inode *inode);
28069+int au_xigen_set(struct super_block *sb, struct file *base);
28070+void au_xigen_clr(struct super_block *sb);
28071+
28072+static inline int au_busy_or_stale(void)
28073+{
b752ccd1 28074+ if (!au_test_nfsd())
1facf9fc 28075+ return -EBUSY;
28076+ return -ESTALE;
28077+}
28078+#else
b752ccd1 28079+AuStubInt0(au_test_nfsd, void)
a2a7ad62 28080+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 28081+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
28082+AuStubInt0(au_xigen_new, struct inode *inode)
28083+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
28084+AuStubVoid(au_xigen_clr, struct super_block *sb)
c1595e42 28085+AuStub(int, au_busy_or_stale, return -EBUSY, void)
1facf9fc 28086+#endif /* CONFIG_AUFS_EXPORT */
28087+
28088+/* ---------------------------------------------------------------------- */
28089+
e49829fe
JR
28090+#ifdef CONFIG_AUFS_SBILIST
28091+/* module.c */
28092+extern struct au_splhead au_sbilist;
28093+
28094+static inline void au_sbilist_init(void)
28095+{
28096+ au_spl_init(&au_sbilist);
28097+}
28098+
28099+static inline void au_sbilist_add(struct super_block *sb)
28100+{
28101+ au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
28102+}
28103+
28104+static inline void au_sbilist_del(struct super_block *sb)
28105+{
28106+ au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
28107+}
53392da6
AM
28108+
28109+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
28110+static inline void au_sbilist_lock(void)
28111+{
28112+ spin_lock(&au_sbilist.spin);
28113+}
28114+
28115+static inline void au_sbilist_unlock(void)
28116+{
28117+ spin_unlock(&au_sbilist.spin);
28118+}
28119+#define AuGFP_SBILIST GFP_ATOMIC
28120+#else
28121+AuStubVoid(au_sbilist_lock, void)
28122+AuStubVoid(au_sbilist_unlock, void)
28123+#define AuGFP_SBILIST GFP_NOFS
28124+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
28125+#else
28126+AuStubVoid(au_sbilist_init, void)
c1595e42
JR
28127+AuStubVoid(au_sbilist_add, struct super_block *sb)
28128+AuStubVoid(au_sbilist_del, struct super_block *sb)
53392da6
AM
28129+AuStubVoid(au_sbilist_lock, void)
28130+AuStubVoid(au_sbilist_unlock, void)
28131+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
28132+#endif
28133+
28134+/* ---------------------------------------------------------------------- */
28135+
1facf9fc 28136+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
28137+{
dece6358 28138+ /*
c1595e42 28139+ * This function is a dynamic '__init' function actually,
dece6358
AM
28140+ * so the tiny check for si_rwsem is unnecessary.
28141+ */
28142+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 28143+#ifdef CONFIG_DEBUG_FS
28144+ sbinfo->si_dbgaufs = NULL;
86dc4139 28145+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 28146+ sbinfo->si_dbgaufs_xib = NULL;
28147+#ifdef CONFIG_AUFS_EXPORT
28148+ sbinfo->si_dbgaufs_xigen = NULL;
28149+#endif
28150+#endif
28151+}
28152+
28153+/* ---------------------------------------------------------------------- */
28154+
b752ccd1
AM
28155+static inline pid_t si_pid_bit(void)
28156+{
28157+ /* the origin of pid is 1, but the bitmap's is 0 */
28158+ return current->pid - 1;
28159+}
28160+
28161+static inline int si_pid_test(struct super_block *sb)
28162+{
076b876e
AM
28163+ pid_t bit;
28164+
28165+ bit = si_pid_bit();
b752ccd1
AM
28166+ if (bit < PID_MAX_DEFAULT)
28167+ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
c1595e42 28168+ return si_pid_test_slow(sb);
b752ccd1
AM
28169+}
28170+
28171+static inline void si_pid_set(struct super_block *sb)
28172+{
076b876e
AM
28173+ pid_t bit;
28174+
28175+ bit = si_pid_bit();
b752ccd1
AM
28176+ if (bit < PID_MAX_DEFAULT) {
28177+ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
28178+ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
28179+ /* smp_mb(); */
28180+ } else
28181+ si_pid_set_slow(sb);
28182+}
28183+
28184+static inline void si_pid_clr(struct super_block *sb)
28185+{
076b876e
AM
28186+ pid_t bit;
28187+
28188+ bit = si_pid_bit();
b752ccd1
AM
28189+ if (bit < PID_MAX_DEFAULT) {
28190+ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
28191+ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
28192+ /* smp_mb(); */
28193+ } else
28194+ si_pid_clr_slow(sb);
28195+}
28196+
28197+/* ---------------------------------------------------------------------- */
28198+
1facf9fc 28199+/* lock superblock. mainly for entry point functions */
28200+/*
b752ccd1
AM
28201+ * __si_read_lock, __si_write_lock,
28202+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 28203+ */
b752ccd1 28204+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 28205+
dece6358
AM
28206+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
28207+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
28208+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
28209+
b752ccd1
AM
28210+static inline void si_noflush_read_lock(struct super_block *sb)
28211+{
28212+ __si_read_lock(sb);
28213+ si_pid_set(sb);
28214+}
28215+
28216+static inline int si_noflush_read_trylock(struct super_block *sb)
28217+{
076b876e
AM
28218+ int locked;
28219+
28220+ locked = __si_read_trylock(sb);
b752ccd1
AM
28221+ if (locked)
28222+ si_pid_set(sb);
28223+ return locked;
28224+}
28225+
28226+static inline void si_noflush_write_lock(struct super_block *sb)
28227+{
28228+ __si_write_lock(sb);
28229+ si_pid_set(sb);
28230+}
28231+
28232+static inline int si_noflush_write_trylock(struct super_block *sb)
28233+{
076b876e
AM
28234+ int locked;
28235+
28236+ locked = __si_write_trylock(sb);
b752ccd1
AM
28237+ if (locked)
28238+ si_pid_set(sb);
28239+ return locked;
28240+}
28241+
7e9cd9fe 28242+#if 0 /* reserved */
1facf9fc 28243+static inline int si_read_trylock(struct super_block *sb, int flags)
28244+{
28245+ if (au_ftest_lock(flags, FLUSH))
28246+ au_nwt_flush(&au_sbi(sb)->si_nowait);
28247+ return si_noflush_read_trylock(sb);
28248+}
e49829fe 28249+#endif
1facf9fc 28250+
b752ccd1
AM
28251+static inline void si_read_unlock(struct super_block *sb)
28252+{
28253+ si_pid_clr(sb);
28254+ __si_read_unlock(sb);
28255+}
28256+
7e9cd9fe 28257+#if 0 /* reserved */
1facf9fc 28258+static inline int si_write_trylock(struct super_block *sb, int flags)
28259+{
28260+ if (au_ftest_lock(flags, FLUSH))
28261+ au_nwt_flush(&au_sbi(sb)->si_nowait);
28262+ return si_noflush_write_trylock(sb);
28263+}
b752ccd1
AM
28264+#endif
28265+
28266+static inline void si_write_unlock(struct super_block *sb)
28267+{
28268+ si_pid_clr(sb);
28269+ __si_write_unlock(sb);
28270+}
28271+
7e9cd9fe 28272+#if 0 /* reserved */
b752ccd1
AM
28273+static inline void si_downgrade_lock(struct super_block *sb)
28274+{
28275+ __si_downgrade_lock(sb);
28276+}
28277+#endif
1facf9fc 28278+
28279+/* ---------------------------------------------------------------------- */
28280+
28281+static inline aufs_bindex_t au_sbend(struct super_block *sb)
28282+{
dece6358 28283+ SiMustAnyLock(sb);
1facf9fc 28284+ return au_sbi(sb)->si_bend;
28285+}
28286+
28287+static inline unsigned int au_mntflags(struct super_block *sb)
28288+{
dece6358 28289+ SiMustAnyLock(sb);
1facf9fc 28290+ return au_sbi(sb)->si_mntflags;
28291+}
28292+
28293+static inline unsigned int au_sigen(struct super_block *sb)
28294+{
dece6358 28295+ SiMustAnyLock(sb);
1facf9fc 28296+ return au_sbi(sb)->si_generation;
28297+}
28298+
7f207e10
AM
28299+static inline void au_ninodes_inc(struct super_block *sb)
28300+{
28301+ atomic_long_inc(&au_sbi(sb)->si_ninodes);
28302+}
28303+
28304+static inline void au_ninodes_dec(struct super_block *sb)
28305+{
28306+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
28307+ atomic_long_dec(&au_sbi(sb)->si_ninodes);
28308+}
28309+
28310+static inline void au_nfiles_inc(struct super_block *sb)
28311+{
28312+ atomic_long_inc(&au_sbi(sb)->si_nfiles);
28313+}
28314+
28315+static inline void au_nfiles_dec(struct super_block *sb)
28316+{
28317+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
28318+ atomic_long_dec(&au_sbi(sb)->si_nfiles);
28319+}
28320+
1facf9fc 28321+static inline struct au_branch *au_sbr(struct super_block *sb,
28322+ aufs_bindex_t bindex)
28323+{
dece6358 28324+ SiMustAnyLock(sb);
1facf9fc 28325+ return au_sbi(sb)->si_branch[0 + bindex];
28326+}
28327+
28328+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
28329+{
dece6358 28330+ SiMustWriteLock(sb);
1facf9fc 28331+ au_sbi(sb)->si_xino_brid = brid;
28332+}
28333+
28334+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
28335+{
dece6358 28336+ SiMustAnyLock(sb);
1facf9fc 28337+ return au_sbi(sb)->si_xino_brid;
28338+}
28339+
28340+#endif /* __KERNEL__ */
28341+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
28342diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
28343--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 28344+++ linux/fs/aufs/sysaufs.c 2015-09-24 10:47:58.254719746 +0200
523b37e3 28345@@ -0,0 +1,104 @@
1facf9fc 28346+/*
2000de60 28347+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28348+ *
28349+ * This program, aufs is free software; you can redistribute it and/or modify
28350+ * it under the terms of the GNU General Public License as published by
28351+ * the Free Software Foundation; either version 2 of the License, or
28352+ * (at your option) any later version.
dece6358
AM
28353+ *
28354+ * This program is distributed in the hope that it will be useful,
28355+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28356+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28357+ * GNU General Public License for more details.
28358+ *
28359+ * You should have received a copy of the GNU General Public License
523b37e3 28360+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28361+ */
28362+
28363+/*
28364+ * sysfs interface and lifetime management
28365+ * they are necessary regardless sysfs is disabled.
28366+ */
28367+
1facf9fc 28368+#include <linux/random.h>
1facf9fc 28369+#include "aufs.h"
28370+
28371+unsigned long sysaufs_si_mask;
e49829fe 28372+struct kset *sysaufs_kset;
1facf9fc 28373+
28374+#define AuSiAttr(_name) { \
28375+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
28376+ .show = sysaufs_si_##_name, \
28377+}
28378+
28379+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
28380+struct attribute *sysaufs_si_attrs[] = {
28381+ &sysaufs_si_attr_xi_path.attr,
28382+ NULL,
28383+};
28384+
4a4d8108 28385+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 28386+ .show = sysaufs_si_show
28387+};
28388+
28389+static struct kobj_type au_sbi_ktype = {
28390+ .release = au_si_free,
28391+ .sysfs_ops = &au_sbi_ops,
28392+ .default_attrs = sysaufs_si_attrs
28393+};
28394+
28395+/* ---------------------------------------------------------------------- */
28396+
28397+int sysaufs_si_init(struct au_sbinfo *sbinfo)
28398+{
28399+ int err;
28400+
e49829fe 28401+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 28402+ /* cf. sysaufs_name() */
28403+ err = kobject_init_and_add
e49829fe 28404+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 28405+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
28406+
28407+ dbgaufs_si_null(sbinfo);
28408+ if (!err) {
28409+ err = dbgaufs_si_init(sbinfo);
28410+ if (unlikely(err))
28411+ kobject_put(&sbinfo->si_kobj);
28412+ }
28413+ return err;
28414+}
28415+
28416+void sysaufs_fin(void)
28417+{
28418+ dbgaufs_fin();
e49829fe
JR
28419+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
28420+ kset_unregister(sysaufs_kset);
1facf9fc 28421+}
28422+
28423+int __init sysaufs_init(void)
28424+{
28425+ int err;
28426+
28427+ do {
28428+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
28429+ } while (!sysaufs_si_mask);
28430+
4a4d8108 28431+ err = -EINVAL;
e49829fe
JR
28432+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
28433+ if (unlikely(!sysaufs_kset))
4a4d8108 28434+ goto out;
e49829fe
JR
28435+ err = PTR_ERR(sysaufs_kset);
28436+ if (IS_ERR(sysaufs_kset))
1facf9fc 28437+ goto out;
e49829fe 28438+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 28439+ if (unlikely(err)) {
e49829fe 28440+ kset_unregister(sysaufs_kset);
1facf9fc 28441+ goto out;
28442+ }
28443+
28444+ err = dbgaufs_init();
28445+ if (unlikely(err))
28446+ sysaufs_fin();
4f0767ce 28447+out:
1facf9fc 28448+ return err;
28449+}
7f207e10
AM
28450diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
28451--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 28452+++ linux/fs/aufs/sysaufs.h 2015-09-24 10:47:58.254719746 +0200
c1595e42 28453@@ -0,0 +1,101 @@
1facf9fc 28454+/*
2000de60 28455+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28456+ *
28457+ * This program, aufs is free software; you can redistribute it and/or modify
28458+ * it under the terms of the GNU General Public License as published by
28459+ * the Free Software Foundation; either version 2 of the License, or
28460+ * (at your option) any later version.
dece6358
AM
28461+ *
28462+ * This program is distributed in the hope that it will be useful,
28463+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28464+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28465+ * GNU General Public License for more details.
28466+ *
28467+ * You should have received a copy of the GNU General Public License
523b37e3 28468+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28469+ */
28470+
28471+/*
28472+ * sysfs interface and mount lifetime management
28473+ */
28474+
28475+#ifndef __SYSAUFS_H__
28476+#define __SYSAUFS_H__
28477+
28478+#ifdef __KERNEL__
28479+
1facf9fc 28480+#include <linux/sysfs.h>
1facf9fc 28481+#include "module.h"
28482+
dece6358
AM
28483+struct super_block;
28484+struct au_sbinfo;
28485+
1facf9fc 28486+struct sysaufs_si_attr {
28487+ struct attribute attr;
28488+ int (*show)(struct seq_file *seq, struct super_block *sb);
28489+};
28490+
28491+/* ---------------------------------------------------------------------- */
28492+
28493+/* sysaufs.c */
28494+extern unsigned long sysaufs_si_mask;
e49829fe 28495+extern struct kset *sysaufs_kset;
1facf9fc 28496+extern struct attribute *sysaufs_si_attrs[];
28497+int sysaufs_si_init(struct au_sbinfo *sbinfo);
28498+int __init sysaufs_init(void);
28499+void sysaufs_fin(void);
28500+
28501+/* ---------------------------------------------------------------------- */
28502+
28503+/* some people doesn't like to show a pointer in kernel */
28504+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
28505+{
28506+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
28507+}
28508+
28509+#define SysaufsSiNamePrefix "si_"
28510+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
28511+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
28512+{
28513+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
28514+ sysaufs_si_id(sbinfo));
28515+}
28516+
28517+struct au_branch;
28518+#ifdef CONFIG_SYSFS
28519+/* sysfs.c */
28520+extern struct attribute_group *sysaufs_attr_group;
28521+
28522+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
28523+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
28524+ char *buf);
076b876e
AM
28525+long au_brinfo_ioctl(struct file *file, unsigned long arg);
28526+#ifdef CONFIG_COMPAT
28527+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
28528+#endif
1facf9fc 28529+
28530+void sysaufs_br_init(struct au_branch *br);
28531+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
28532+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
28533+
28534+#define sysaufs_brs_init() do {} while (0)
28535+
28536+#else
28537+#define sysaufs_attr_group NULL
28538+
4a4d8108 28539+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
c1595e42
JR
28540+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
28541+ struct attribute *attr, char *buf)
4a4d8108
AM
28542+AuStubVoid(sysaufs_br_init, struct au_branch *br)
28543+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
28544+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 28545+
28546+static inline void sysaufs_brs_init(void)
28547+{
28548+ sysaufs_brs = 0;
28549+}
28550+
28551+#endif /* CONFIG_SYSFS */
28552+
28553+#endif /* __KERNEL__ */
28554+#endif /* __SYSAUFS_H__ */
7f207e10
AM
28555diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
28556--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
28557+++ linux/fs/aufs/sysfs.c 2015-11-11 17:21:46.922197217 +0100
28558@@ -0,0 +1,376 @@
1facf9fc 28559+/*
2000de60 28560+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28561+ *
28562+ * This program, aufs is free software; you can redistribute it and/or modify
28563+ * it under the terms of the GNU General Public License as published by
28564+ * the Free Software Foundation; either version 2 of the License, or
28565+ * (at your option) any later version.
dece6358
AM
28566+ *
28567+ * This program is distributed in the hope that it will be useful,
28568+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28569+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28570+ * GNU General Public License for more details.
28571+ *
28572+ * You should have received a copy of the GNU General Public License
523b37e3 28573+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28574+ */
28575+
28576+/*
28577+ * sysfs interface
28578+ */
28579+
076b876e 28580+#include <linux/compat.h>
1facf9fc 28581+#include <linux/seq_file.h>
1facf9fc 28582+#include "aufs.h"
28583+
4a4d8108
AM
28584+#ifdef CONFIG_AUFS_FS_MODULE
28585+/* this entry violates the "one line per file" policy of sysfs */
28586+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
28587+ char *buf)
28588+{
28589+ ssize_t err;
28590+ static char *conf =
28591+/* this file is generated at compiling */
28592+#include "conf.str"
28593+ ;
28594+
28595+ err = snprintf(buf, PAGE_SIZE, conf);
28596+ if (unlikely(err >= PAGE_SIZE))
28597+ err = -EFBIG;
28598+ return err;
28599+}
28600+
28601+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
28602+#endif
28603+
1facf9fc 28604+static struct attribute *au_attr[] = {
4a4d8108
AM
28605+#ifdef CONFIG_AUFS_FS_MODULE
28606+ &au_config_attr.attr,
28607+#endif
1facf9fc 28608+ NULL, /* need to NULL terminate the list of attributes */
28609+};
28610+
28611+static struct attribute_group sysaufs_attr_group_body = {
28612+ .attrs = au_attr
28613+};
28614+
28615+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
28616+
28617+/* ---------------------------------------------------------------------- */
28618+
28619+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
28620+{
28621+ int err;
28622+
dece6358
AM
28623+ SiMustAnyLock(sb);
28624+
1facf9fc 28625+ err = 0;
28626+ if (au_opt_test(au_mntflags(sb), XINO)) {
28627+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
28628+ seq_putc(seq, '\n');
28629+ }
28630+ return err;
28631+}
28632+
28633+/*
28634+ * the lifetime of branch is independent from the entry under sysfs.
28635+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
28636+ * unlinked.
28637+ */
28638+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 28639+ aufs_bindex_t bindex, int idx)
1facf9fc 28640+{
1e00d052 28641+ int err;
1facf9fc 28642+ struct path path;
28643+ struct dentry *root;
28644+ struct au_branch *br;
076b876e 28645+ au_br_perm_str_t perm;
1facf9fc 28646+
28647+ AuDbg("b%d\n", bindex);
28648+
1e00d052 28649+ err = 0;
1facf9fc 28650+ root = sb->s_root;
28651+ di_read_lock_parent(root, !AuLock_IR);
28652+ br = au_sbr(sb, bindex);
392086de
AM
28653+
28654+ switch (idx) {
28655+ case AuBrSysfs_BR:
28656+ path.mnt = au_br_mnt(br);
28657+ path.dentry = au_h_dptr(root, bindex);
79b8bda9
AM
28658+ err = au_seq_path(seq, &path);
28659+ if (!err) {
28660+ au_optstr_br_perm(&perm, br->br_perm);
28661+ seq_printf(seq, "=%s\n", perm.a);
28662+ }
392086de
AM
28663+ break;
28664+ case AuBrSysfs_BRID:
79b8bda9 28665+ seq_printf(seq, "%d\n", br->br_id);
392086de
AM
28666+ break;
28667+ }
076b876e 28668+ di_read_unlock(root, !AuLock_IR);
79b8bda9 28669+ if (unlikely(err || seq_has_overflowed(seq)))
076b876e 28670+ err = -E2BIG;
392086de 28671+
1e00d052 28672+ return err;
1facf9fc 28673+}
28674+
28675+/* ---------------------------------------------------------------------- */
28676+
28677+static struct seq_file *au_seq(char *p, ssize_t len)
28678+{
28679+ struct seq_file *seq;
28680+
28681+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
28682+ if (seq) {
28683+ /* mutex_init(&seq.lock); */
28684+ seq->buf = p;
28685+ seq->size = len;
28686+ return seq; /* success */
28687+ }
28688+
28689+ seq = ERR_PTR(-ENOMEM);
28690+ return seq;
28691+}
28692+
392086de
AM
28693+#define SysaufsBr_PREFIX "br"
28694+#define SysaufsBrid_PREFIX "brid"
1facf9fc 28695+
28696+/* todo: file size may exceed PAGE_SIZE */
28697+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 28698+ char *buf)
1facf9fc 28699+{
28700+ ssize_t err;
392086de 28701+ int idx;
1facf9fc 28702+ long l;
28703+ aufs_bindex_t bend;
28704+ struct au_sbinfo *sbinfo;
28705+ struct super_block *sb;
28706+ struct seq_file *seq;
28707+ char *name;
28708+ struct attribute **cattr;
28709+
28710+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
28711+ sb = sbinfo->si_sb;
1308ab2a 28712+
28713+ /*
28714+ * prevent a race condition between sysfs and aufs.
28715+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
28716+ * prohibits maintaining the sysfs entries.
28717+ * hew we acquire read lock after sysfs_get_active_two().
28718+ * on the other hand, the remount process may maintain the sysfs/aufs
28719+ * entries after acquiring write lock.
28720+ * it can cause a deadlock.
28721+ * simply we gave up processing read here.
28722+ */
28723+ err = -EBUSY;
28724+ if (unlikely(!si_noflush_read_trylock(sb)))
28725+ goto out;
1facf9fc 28726+
28727+ seq = au_seq(buf, PAGE_SIZE);
28728+ err = PTR_ERR(seq);
28729+ if (IS_ERR(seq))
1308ab2a 28730+ goto out_unlock;
1facf9fc 28731+
28732+ name = (void *)attr->name;
28733+ cattr = sysaufs_si_attrs;
28734+ while (*cattr) {
28735+ if (!strcmp(name, (*cattr)->name)) {
28736+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
28737+ ->show(seq, sb);
28738+ goto out_seq;
28739+ }
28740+ cattr++;
28741+ }
28742+
392086de
AM
28743+ if (!strncmp(name, SysaufsBrid_PREFIX,
28744+ sizeof(SysaufsBrid_PREFIX) - 1)) {
28745+ idx = AuBrSysfs_BRID;
28746+ name += sizeof(SysaufsBrid_PREFIX) - 1;
28747+ } else if (!strncmp(name, SysaufsBr_PREFIX,
28748+ sizeof(SysaufsBr_PREFIX) - 1)) {
28749+ idx = AuBrSysfs_BR;
1facf9fc 28750+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
28751+ } else
28752+ BUG();
28753+
28754+ err = kstrtol(name, 10, &l);
28755+ if (!err) {
28756+ bend = au_sbend(sb);
28757+ if (l <= bend)
28758+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
28759+ else
28760+ err = -ENOENT;
1facf9fc 28761+ }
1facf9fc 28762+
4f0767ce 28763+out_seq:
1facf9fc 28764+ if (!err) {
28765+ err = seq->count;
28766+ /* sysfs limit */
28767+ if (unlikely(err == PAGE_SIZE))
28768+ err = -EFBIG;
28769+ }
28770+ kfree(seq);
4f0767ce 28771+out_unlock:
1facf9fc 28772+ si_read_unlock(sb);
4f0767ce 28773+out:
1facf9fc 28774+ return err;
28775+}
28776+
28777+/* ---------------------------------------------------------------------- */
28778+
076b876e
AM
28779+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
28780+{
28781+ int err;
28782+ int16_t brid;
28783+ aufs_bindex_t bindex, bend;
28784+ size_t sz;
28785+ char *buf;
28786+ struct seq_file *seq;
28787+ struct au_branch *br;
28788+
28789+ si_read_lock(sb, AuLock_FLUSH);
28790+ bend = au_sbend(sb);
28791+ err = bend + 1;
28792+ if (!arg)
28793+ goto out;
28794+
28795+ err = -ENOMEM;
28796+ buf = (void *)__get_free_page(GFP_NOFS);
28797+ if (unlikely(!buf))
28798+ goto out;
28799+
28800+ seq = au_seq(buf, PAGE_SIZE);
28801+ err = PTR_ERR(seq);
28802+ if (IS_ERR(seq))
28803+ goto out_buf;
28804+
28805+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
28806+ for (bindex = 0; bindex <= bend; bindex++, arg++) {
28807+ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg));
28808+ if (unlikely(err))
28809+ break;
28810+
28811+ br = au_sbr(sb, bindex);
28812+ brid = br->br_id;
28813+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
28814+ err = __put_user(brid, &arg->id);
28815+ if (unlikely(err))
28816+ break;
28817+
28818+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
28819+ err = __put_user(br->br_perm, &arg->perm);
28820+ if (unlikely(err))
28821+ break;
28822+
79b8bda9
AM
28823+ err = au_seq_path(seq, &br->br_path);
28824+ if (unlikely(err))
28825+ break;
28826+ seq_putc(seq, '\0');
28827+ if (!seq_has_overflowed(seq)) {
076b876e
AM
28828+ err = copy_to_user(arg->path, seq->buf, seq->count);
28829+ seq->count = 0;
28830+ if (unlikely(err))
28831+ break;
28832+ } else {
28833+ err = -E2BIG;
28834+ goto out_seq;
28835+ }
28836+ }
28837+ if (unlikely(err))
28838+ err = -EFAULT;
28839+
28840+out_seq:
28841+ kfree(seq);
28842+out_buf:
28843+ free_page((unsigned long)buf);
28844+out:
28845+ si_read_unlock(sb);
28846+ return err;
28847+}
28848+
28849+long au_brinfo_ioctl(struct file *file, unsigned long arg)
28850+{
2000de60 28851+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg);
076b876e
AM
28852+}
28853+
28854+#ifdef CONFIG_COMPAT
28855+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
28856+{
2000de60 28857+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg));
076b876e
AM
28858+}
28859+#endif
28860+
28861+/* ---------------------------------------------------------------------- */
28862+
1facf9fc 28863+void sysaufs_br_init(struct au_branch *br)
28864+{
392086de
AM
28865+ int i;
28866+ struct au_brsysfs *br_sysfs;
28867+ struct attribute *attr;
4a4d8108 28868+
392086de
AM
28869+ br_sysfs = br->br_sysfs;
28870+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28871+ attr = &br_sysfs->attr;
28872+ sysfs_attr_init(attr);
28873+ attr->name = br_sysfs->name;
28874+ attr->mode = S_IRUGO;
28875+ br_sysfs++;
28876+ }
1facf9fc 28877+}
28878+
28879+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
28880+{
28881+ struct au_branch *br;
28882+ struct kobject *kobj;
392086de
AM
28883+ struct au_brsysfs *br_sysfs;
28884+ int i;
1facf9fc 28885+ aufs_bindex_t bend;
28886+
28887+ dbgaufs_brs_del(sb, bindex);
28888+
28889+ if (!sysaufs_brs)
28890+ return;
28891+
28892+ kobj = &au_sbi(sb)->si_kobj;
28893+ bend = au_sbend(sb);
28894+ for (; bindex <= bend; bindex++) {
28895+ br = au_sbr(sb, bindex);
392086de
AM
28896+ br_sysfs = br->br_sysfs;
28897+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28898+ sysfs_remove_file(kobj, &br_sysfs->attr);
28899+ br_sysfs++;
28900+ }
1facf9fc 28901+ }
28902+}
28903+
28904+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
28905+{
392086de 28906+ int err, i;
1facf9fc 28907+ aufs_bindex_t bend;
28908+ struct kobject *kobj;
28909+ struct au_branch *br;
392086de 28910+ struct au_brsysfs *br_sysfs;
1facf9fc 28911+
28912+ dbgaufs_brs_add(sb, bindex);
28913+
28914+ if (!sysaufs_brs)
28915+ return;
28916+
28917+ kobj = &au_sbi(sb)->si_kobj;
28918+ bend = au_sbend(sb);
28919+ for (; bindex <= bend; bindex++) {
28920+ br = au_sbr(sb, bindex);
392086de
AM
28921+ br_sysfs = br->br_sysfs;
28922+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
28923+ SysaufsBr_PREFIX "%d", bindex);
28924+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
28925+ SysaufsBrid_PREFIX "%d", bindex);
28926+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28927+ err = sysfs_create_file(kobj, &br_sysfs->attr);
28928+ if (unlikely(err))
28929+ pr_warn("failed %s under sysfs(%d)\n",
28930+ br_sysfs->name, err);
28931+ br_sysfs++;
28932+ }
1facf9fc 28933+ }
28934+}
7f207e10
AM
28935diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
28936--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9 28937+++ linux/fs/aufs/sysrq.c 2015-11-11 17:21:46.922197217 +0100
076b876e 28938@@ -0,0 +1,157 @@
1facf9fc 28939+/*
2000de60 28940+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28941+ *
28942+ * This program, aufs is free software; you can redistribute it and/or modify
28943+ * it under the terms of the GNU General Public License as published by
28944+ * the Free Software Foundation; either version 2 of the License, or
28945+ * (at your option) any later version.
dece6358
AM
28946+ *
28947+ * This program is distributed in the hope that it will be useful,
28948+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28949+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28950+ * GNU General Public License for more details.
28951+ *
28952+ * You should have received a copy of the GNU General Public License
523b37e3 28953+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28954+ */
28955+
28956+/*
28957+ * magic sysrq hanlder
28958+ */
28959+
1facf9fc 28960+/* #include <linux/sysrq.h> */
027c5e7a 28961+#include <linux/writeback.h>
1facf9fc 28962+#include "aufs.h"
28963+
28964+/* ---------------------------------------------------------------------- */
28965+
28966+static void sysrq_sb(struct super_block *sb)
28967+{
28968+ char *plevel;
28969+ struct au_sbinfo *sbinfo;
28970+ struct file *file;
523b37e3
AM
28971+ struct au_sphlhead *files;
28972+ struct au_finfo *finfo;
1facf9fc 28973+
28974+ plevel = au_plevel;
28975+ au_plevel = KERN_WARNING;
1facf9fc 28976+
4a4d8108 28977+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
28978+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
28979+
28980+ sbinfo = au_sbi(sb);
4a4d8108 28981+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 28982+ pr("superblock\n");
1facf9fc 28983+ au_dpri_sb(sb);
027c5e7a
AM
28984+
28985+#if 0
c06a8ce3 28986+ pr("root dentry\n");
1facf9fc 28987+ au_dpri_dentry(sb->s_root);
c06a8ce3 28988+ pr("root inode\n");
5527c038 28989+ au_dpri_inode(d_inode(sb->s_root));
027c5e7a
AM
28990+#endif
28991+
1facf9fc 28992+#if 0
027c5e7a
AM
28993+ do {
28994+ int err, i, j, ndentry;
28995+ struct au_dcsub_pages dpages;
28996+ struct au_dpage *dpage;
28997+
28998+ err = au_dpages_init(&dpages, GFP_ATOMIC);
28999+ if (unlikely(err))
29000+ break;
29001+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
29002+ if (!err)
29003+ for (i = 0; i < dpages.ndpage; i++) {
29004+ dpage = dpages.dpages + i;
29005+ ndentry = dpage->ndentry;
29006+ for (j = 0; j < ndentry; j++)
29007+ au_dpri_dentry(dpage->dentries[j]);
29008+ }
29009+ au_dpages_free(&dpages);
29010+ } while (0);
29011+#endif
29012+
29013+#if 1
29014+ {
29015+ struct inode *i;
076b876e 29016+
c06a8ce3 29017+ pr("isolated inode\n");
79b8bda9 29018+ spin_lock(&sb->s_inode_list_lock);
2cbb1c4b
JR
29019+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
29020+ spin_lock(&i->i_lock);
b4510431 29021+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 29022+ au_dpri_inode(i);
2cbb1c4b
JR
29023+ spin_unlock(&i->i_lock);
29024+ }
79b8bda9 29025+ spin_unlock(&sb->s_inode_list_lock);
027c5e7a 29026+ }
1facf9fc 29027+#endif
c06a8ce3 29028+ pr("files\n");
523b37e3
AM
29029+ files = &au_sbi(sb)->si_files;
29030+ spin_lock(&files->spin);
29031+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
4a4d8108 29032+ umode_t mode;
076b876e 29033+
523b37e3 29034+ file = finfo->fi_file;
c06a8ce3 29035+ mode = file_inode(file)->i_mode;
38d290e6 29036+ if (!special_file(mode))
1facf9fc 29037+ au_dpri_file(file);
523b37e3
AM
29038+ }
29039+ spin_unlock(&files->spin);
c06a8ce3 29040+ pr("done\n");
1facf9fc 29041+
c06a8ce3 29042+#undef pr
1facf9fc 29043+ au_plevel = plevel;
1facf9fc 29044+}
29045+
29046+/* ---------------------------------------------------------------------- */
29047+
29048+/* module parameter */
29049+static char *aufs_sysrq_key = "a";
29050+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
29051+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
29052+
0c5527e5 29053+static void au_sysrq(int key __maybe_unused)
1facf9fc 29054+{
1facf9fc 29055+ struct au_sbinfo *sbinfo;
29056+
027c5e7a 29057+ lockdep_off();
53392da6 29058+ au_sbilist_lock();
e49829fe 29059+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 29060+ sysrq_sb(sbinfo->si_sb);
53392da6 29061+ au_sbilist_unlock();
027c5e7a 29062+ lockdep_on();
1facf9fc 29063+}
29064+
29065+static struct sysrq_key_op au_sysrq_op = {
29066+ .handler = au_sysrq,
29067+ .help_msg = "Aufs",
29068+ .action_msg = "Aufs",
29069+ .enable_mask = SYSRQ_ENABLE_DUMP
29070+};
29071+
29072+/* ---------------------------------------------------------------------- */
29073+
29074+int __init au_sysrq_init(void)
29075+{
29076+ int err;
29077+ char key;
29078+
29079+ err = -1;
29080+ key = *aufs_sysrq_key;
29081+ if ('a' <= key && key <= 'z')
29082+ err = register_sysrq_key(key, &au_sysrq_op);
29083+ if (unlikely(err))
4a4d8108 29084+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 29085+ return err;
29086+}
29087+
29088+void au_sysrq_fin(void)
29089+{
29090+ int err;
076b876e 29091+
1facf9fc 29092+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
29093+ if (unlikely(err))
4a4d8108 29094+ pr_err("err %d (ignored)\n", err);
1facf9fc 29095+}
7f207e10
AM
29096diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
29097--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9 29098+++ linux/fs/aufs/vdir.c 2015-11-11 17:21:46.922197217 +0100
b912730e 29099@@ -0,0 +1,888 @@
1facf9fc 29100+/*
2000de60 29101+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 29102+ *
29103+ * This program, aufs is free software; you can redistribute it and/or modify
29104+ * it under the terms of the GNU General Public License as published by
29105+ * the Free Software Foundation; either version 2 of the License, or
29106+ * (at your option) any later version.
dece6358
AM
29107+ *
29108+ * This program is distributed in the hope that it will be useful,
29109+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29110+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29111+ * GNU General Public License for more details.
29112+ *
29113+ * You should have received a copy of the GNU General Public License
523b37e3 29114+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29115+ */
29116+
29117+/*
29118+ * virtual or vertical directory
29119+ */
29120+
29121+#include "aufs.h"
29122+
dece6358 29123+static unsigned int calc_size(int nlen)
1facf9fc 29124+{
dece6358 29125+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 29126+}
29127+
29128+static int set_deblk_end(union au_vdir_deblk_p *p,
29129+ union au_vdir_deblk_p *deblk_end)
29130+{
29131+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
29132+ p->de->de_str.len = 0;
29133+ /* smp_mb(); */
29134+ return 0;
29135+ }
29136+ return -1; /* error */
29137+}
29138+
29139+/* returns true or false */
29140+static int is_deblk_end(union au_vdir_deblk_p *p,
29141+ union au_vdir_deblk_p *deblk_end)
29142+{
29143+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
29144+ return !p->de->de_str.len;
29145+ return 1;
29146+}
29147+
29148+static unsigned char *last_deblk(struct au_vdir *vdir)
29149+{
29150+ return vdir->vd_deblk[vdir->vd_nblk - 1];
29151+}
29152+
29153+/* ---------------------------------------------------------------------- */
29154+
79b8bda9 29155+/* estimate the appropriate size for name hash table */
1308ab2a 29156+unsigned int au_rdhash_est(loff_t sz)
29157+{
29158+ unsigned int n;
29159+
29160+ n = UINT_MAX;
29161+ sz >>= 10;
29162+ if (sz < n)
29163+ n = sz;
29164+ if (sz < AUFS_RDHASH_DEF)
29165+ n = AUFS_RDHASH_DEF;
4a4d8108 29166+ /* pr_info("n %u\n", n); */
1308ab2a 29167+ return n;
29168+}
29169+
1facf9fc 29170+/*
29171+ * the allocated memory has to be freed by
dece6358 29172+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 29173+ */
dece6358 29174+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 29175+{
1facf9fc 29176+ struct hlist_head *head;
dece6358 29177+ unsigned int u;
076b876e 29178+ size_t sz;
1facf9fc 29179+
076b876e
AM
29180+ sz = sizeof(*nhash->nh_head) * num_hash;
29181+ head = kmalloc(sz, gfp);
dece6358
AM
29182+ if (head) {
29183+ nhash->nh_num = num_hash;
29184+ nhash->nh_head = head;
29185+ for (u = 0; u < num_hash; u++)
1facf9fc 29186+ INIT_HLIST_HEAD(head++);
dece6358 29187+ return 0; /* success */
1facf9fc 29188+ }
1facf9fc 29189+
dece6358 29190+ return -ENOMEM;
1facf9fc 29191+}
29192+
dece6358
AM
29193+static void nhash_count(struct hlist_head *head)
29194+{
29195+#if 0
29196+ unsigned long n;
29197+ struct hlist_node *pos;
29198+
29199+ n = 0;
29200+ hlist_for_each(pos, head)
29201+ n++;
4a4d8108 29202+ pr_info("%lu\n", n);
dece6358
AM
29203+#endif
29204+}
29205+
29206+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 29207+{
c06a8ce3
AM
29208+ struct au_vdir_wh *pos;
29209+ struct hlist_node *node;
1facf9fc 29210+
c06a8ce3
AM
29211+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
29212+ kfree(pos);
1facf9fc 29213+}
29214+
dece6358 29215+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 29216+{
c06a8ce3
AM
29217+ struct au_vdir_dehstr *pos;
29218+ struct hlist_node *node;
1facf9fc 29219+
c06a8ce3
AM
29220+ hlist_for_each_entry_safe(pos, node, head, hash)
29221+ au_cache_free_vdir_dehstr(pos);
1facf9fc 29222+}
29223+
dece6358
AM
29224+static void au_nhash_do_free(struct au_nhash *nhash,
29225+ void (*free)(struct hlist_head *head))
1facf9fc 29226+{
1308ab2a 29227+ unsigned int n;
1facf9fc 29228+ struct hlist_head *head;
1facf9fc 29229+
dece6358 29230+ n = nhash->nh_num;
1308ab2a 29231+ if (!n)
29232+ return;
29233+
dece6358 29234+ head = nhash->nh_head;
1308ab2a 29235+ while (n-- > 0) {
dece6358
AM
29236+ nhash_count(head);
29237+ free(head++);
1facf9fc 29238+ }
dece6358 29239+ kfree(nhash->nh_head);
1facf9fc 29240+}
29241+
dece6358 29242+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 29243+{
dece6358
AM
29244+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
29245+}
1facf9fc 29246+
dece6358
AM
29247+static void au_nhash_de_free(struct au_nhash *delist)
29248+{
29249+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 29250+}
29251+
29252+/* ---------------------------------------------------------------------- */
29253+
29254+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
29255+ int limit)
29256+{
29257+ int num;
29258+ unsigned int u, n;
29259+ struct hlist_head *head;
c06a8ce3 29260+ struct au_vdir_wh *pos;
1facf9fc 29261+
29262+ num = 0;
29263+ n = whlist->nh_num;
29264+ head = whlist->nh_head;
1308ab2a 29265+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
29266+ hlist_for_each_entry(pos, head, wh_hash)
29267+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 29268+ return 1;
1facf9fc 29269+ return 0;
29270+}
29271+
29272+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 29273+ unsigned char *name,
1facf9fc 29274+ unsigned int len)
29275+{
dece6358
AM
29276+ unsigned int v;
29277+ /* const unsigned int magic_bit = 12; */
29278+
1308ab2a 29279+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
29280+
dece6358
AM
29281+ v = 0;
29282+ while (len--)
29283+ v += *name++;
29284+ /* v = hash_long(v, magic_bit); */
29285+ v %= nhash->nh_num;
29286+ return nhash->nh_head + v;
29287+}
29288+
29289+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
29290+ int nlen)
29291+{
29292+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 29293+}
29294+
29295+/* returns found or not */
dece6358 29296+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 29297+{
29298+ struct hlist_head *head;
c06a8ce3 29299+ struct au_vdir_wh *pos;
1facf9fc 29300+ struct au_vdir_destr *str;
29301+
dece6358 29302+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
29303+ hlist_for_each_entry(pos, head, wh_hash) {
29304+ str = &pos->wh_str;
1facf9fc 29305+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
29306+ if (au_nhash_test_name(str, name, nlen))
29307+ return 1;
29308+ }
29309+ return 0;
29310+}
29311+
29312+/* returns found(true) or not */
29313+static int test_known(struct au_nhash *delist, char *name, int nlen)
29314+{
29315+ struct hlist_head *head;
c06a8ce3 29316+ struct au_vdir_dehstr *pos;
dece6358
AM
29317+ struct au_vdir_destr *str;
29318+
29319+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
29320+ hlist_for_each_entry(pos, head, hash) {
29321+ str = pos->str;
dece6358
AM
29322+ AuDbg("%.*s\n", str->len, str->name);
29323+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 29324+ return 1;
29325+ }
29326+ return 0;
29327+}
29328+
dece6358
AM
29329+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
29330+ unsigned char d_type)
29331+{
29332+#ifdef CONFIG_AUFS_SHWH
29333+ wh->wh_ino = ino;
29334+ wh->wh_type = d_type;
29335+#endif
29336+}
29337+
29338+/* ---------------------------------------------------------------------- */
29339+
29340+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
29341+ unsigned int d_type, aufs_bindex_t bindex,
29342+ unsigned char shwh)
1facf9fc 29343+{
29344+ int err;
29345+ struct au_vdir_destr *str;
29346+ struct au_vdir_wh *wh;
29347+
dece6358 29348+ AuDbg("%.*s\n", nlen, name);
1308ab2a 29349+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
29350+
1facf9fc 29351+ err = -ENOMEM;
dece6358 29352+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 29353+ if (unlikely(!wh))
29354+ goto out;
29355+
29356+ err = 0;
29357+ wh->wh_bindex = bindex;
dece6358
AM
29358+ if (shwh)
29359+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 29360+ str = &wh->wh_str;
dece6358
AM
29361+ str->len = nlen;
29362+ memcpy(str->name, name, nlen);
29363+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 29364+ /* smp_mb(); */
29365+
4f0767ce 29366+out:
1facf9fc 29367+ return err;
29368+}
29369+
1facf9fc 29370+static int append_deblk(struct au_vdir *vdir)
29371+{
29372+ int err;
dece6358 29373+ unsigned long ul;
1facf9fc 29374+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
29375+ union au_vdir_deblk_p p, deblk_end;
29376+ unsigned char **o;
29377+
29378+ err = -ENOMEM;
dece6358
AM
29379+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
29380+ GFP_NOFS);
1facf9fc 29381+ if (unlikely(!o))
29382+ goto out;
29383+
29384+ vdir->vd_deblk = o;
29385+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
29386+ if (p.deblk) {
29387+ ul = vdir->vd_nblk++;
29388+ vdir->vd_deblk[ul] = p.deblk;
29389+ vdir->vd_last.ul = ul;
29390+ vdir->vd_last.p.deblk = p.deblk;
29391+ deblk_end.deblk = p.deblk + deblk_sz;
29392+ err = set_deblk_end(&p, &deblk_end);
29393+ }
29394+
4f0767ce 29395+out:
1facf9fc 29396+ return err;
29397+}
29398+
dece6358
AM
29399+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
29400+ unsigned int d_type, struct au_nhash *delist)
29401+{
29402+ int err;
29403+ unsigned int sz;
29404+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
29405+ union au_vdir_deblk_p p, *room, deblk_end;
29406+ struct au_vdir_dehstr *dehstr;
29407+
29408+ p.deblk = last_deblk(vdir);
29409+ deblk_end.deblk = p.deblk + deblk_sz;
29410+ room = &vdir->vd_last.p;
29411+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
29412+ || !is_deblk_end(room, &deblk_end));
29413+
29414+ sz = calc_size(nlen);
29415+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
29416+ err = append_deblk(vdir);
29417+ if (unlikely(err))
29418+ goto out;
29419+
29420+ p.deblk = last_deblk(vdir);
29421+ deblk_end.deblk = p.deblk + deblk_sz;
29422+ /* smp_mb(); */
29423+ AuDebugOn(room->deblk != p.deblk);
29424+ }
29425+
29426+ err = -ENOMEM;
4a4d8108 29427+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
29428+ if (unlikely(!dehstr))
29429+ goto out;
29430+
29431+ dehstr->str = &room->de->de_str;
29432+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
29433+ room->de->de_ino = ino;
29434+ room->de->de_type = d_type;
29435+ room->de->de_str.len = nlen;
29436+ memcpy(room->de->de_str.name, name, nlen);
29437+
29438+ err = 0;
29439+ room->deblk += sz;
29440+ if (unlikely(set_deblk_end(room, &deblk_end)))
29441+ err = append_deblk(vdir);
29442+ /* smp_mb(); */
29443+
4f0767ce 29444+out:
dece6358
AM
29445+ return err;
29446+}
29447+
29448+/* ---------------------------------------------------------------------- */
29449+
29450+void au_vdir_free(struct au_vdir *vdir)
29451+{
29452+ unsigned char **deblk;
29453+
29454+ deblk = vdir->vd_deblk;
29455+ while (vdir->vd_nblk--)
29456+ kfree(*deblk++);
29457+ kfree(vdir->vd_deblk);
29458+ au_cache_free_vdir(vdir);
29459+}
29460+
1308ab2a 29461+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 29462+{
29463+ struct au_vdir *vdir;
1308ab2a 29464+ struct super_block *sb;
1facf9fc 29465+ int err;
29466+
2000de60 29467+ sb = file->f_path.dentry->d_sb;
dece6358
AM
29468+ SiMustAnyLock(sb);
29469+
1facf9fc 29470+ err = -ENOMEM;
29471+ vdir = au_cache_alloc_vdir();
29472+ if (unlikely(!vdir))
29473+ goto out;
29474+
29475+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
29476+ if (unlikely(!vdir->vd_deblk))
29477+ goto out_free;
29478+
29479+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 29480+ if (!vdir->vd_deblk_sz) {
79b8bda9 29481+ /* estimate the appropriate size for deblk */
1308ab2a 29482+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 29483+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 29484+ }
1facf9fc 29485+ vdir->vd_nblk = 0;
29486+ vdir->vd_version = 0;
29487+ vdir->vd_jiffy = 0;
29488+ err = append_deblk(vdir);
29489+ if (!err)
29490+ return vdir; /* success */
29491+
29492+ kfree(vdir->vd_deblk);
29493+
4f0767ce 29494+out_free:
1facf9fc 29495+ au_cache_free_vdir(vdir);
4f0767ce 29496+out:
1facf9fc 29497+ vdir = ERR_PTR(err);
29498+ return vdir;
29499+}
29500+
29501+static int reinit_vdir(struct au_vdir *vdir)
29502+{
29503+ int err;
29504+ union au_vdir_deblk_p p, deblk_end;
29505+
29506+ while (vdir->vd_nblk > 1) {
29507+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
29508+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
29509+ vdir->vd_nblk--;
29510+ }
29511+ p.deblk = vdir->vd_deblk[0];
29512+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
29513+ err = set_deblk_end(&p, &deblk_end);
29514+ /* keep vd_dblk_sz */
29515+ vdir->vd_last.ul = 0;
29516+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
29517+ vdir->vd_version = 0;
29518+ vdir->vd_jiffy = 0;
29519+ /* smp_mb(); */
29520+ return err;
29521+}
29522+
29523+/* ---------------------------------------------------------------------- */
29524+
1facf9fc 29525+#define AuFillVdir_CALLED 1
29526+#define AuFillVdir_WHABLE (1 << 1)
dece6358 29527+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 29528+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
29529+#define au_fset_fillvdir(flags, name) \
29530+ do { (flags) |= AuFillVdir_##name; } while (0)
29531+#define au_fclr_fillvdir(flags, name) \
29532+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 29533+
dece6358
AM
29534+#ifndef CONFIG_AUFS_SHWH
29535+#undef AuFillVdir_SHWH
29536+#define AuFillVdir_SHWH 0
29537+#endif
29538+
1facf9fc 29539+struct fillvdir_arg {
392086de 29540+ struct dir_context ctx;
1facf9fc 29541+ struct file *file;
29542+ struct au_vdir *vdir;
dece6358
AM
29543+ struct au_nhash delist;
29544+ struct au_nhash whlist;
1facf9fc 29545+ aufs_bindex_t bindex;
29546+ unsigned int flags;
29547+ int err;
29548+};
29549+
392086de 29550+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 29551+ loff_t offset __maybe_unused, u64 h_ino,
29552+ unsigned int d_type)
29553+{
392086de 29554+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 29555+ char *name = (void *)__name;
29556+ struct super_block *sb;
1facf9fc 29557+ ino_t ino;
dece6358 29558+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 29559+
1facf9fc 29560+ arg->err = 0;
2000de60 29561+ sb = arg->file->f_path.dentry->d_sb;
1facf9fc 29562+ au_fset_fillvdir(arg->flags, CALLED);
29563+ /* smp_mb(); */
dece6358 29564+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 29565+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
29566+ if (test_known(&arg->delist, name, nlen)
29567+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
29568+ goto out; /* already exists or whiteouted */
1facf9fc 29569+
dece6358 29570+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
29571+ if (!arg->err) {
29572+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
29573+ d_type = DT_UNKNOWN;
dece6358
AM
29574+ arg->err = append_de(arg->vdir, name, nlen, ino,
29575+ d_type, &arg->delist);
4a4d8108 29576+ }
1facf9fc 29577+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
29578+ name += AUFS_WH_PFX_LEN;
dece6358
AM
29579+ nlen -= AUFS_WH_PFX_LEN;
29580+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
29581+ goto out; /* already whiteouted */
1facf9fc 29582+
dece6358
AM
29583+ if (shwh)
29584+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
29585+ &ino);
4a4d8108
AM
29586+ if (!arg->err) {
29587+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
29588+ d_type = DT_UNKNOWN;
1facf9fc 29589+ arg->err = au_nhash_append_wh
dece6358
AM
29590+ (&arg->whlist, name, nlen, ino, d_type,
29591+ arg->bindex, shwh);
4a4d8108 29592+ }
1facf9fc 29593+ }
29594+
4f0767ce 29595+out:
1facf9fc 29596+ if (!arg->err)
29597+ arg->vdir->vd_jiffy = jiffies;
29598+ /* smp_mb(); */
29599+ AuTraceErr(arg->err);
29600+ return arg->err;
29601+}
29602+
dece6358
AM
29603+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
29604+ struct au_nhash *whlist, struct au_nhash *delist)
29605+{
29606+#ifdef CONFIG_AUFS_SHWH
29607+ int err;
29608+ unsigned int nh, u;
29609+ struct hlist_head *head;
c06a8ce3
AM
29610+ struct au_vdir_wh *pos;
29611+ struct hlist_node *n;
dece6358
AM
29612+ char *p, *o;
29613+ struct au_vdir_destr *destr;
29614+
29615+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
29616+
29617+ err = -ENOMEM;
537831f9 29618+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
29619+ if (unlikely(!p))
29620+ goto out;
29621+
29622+ err = 0;
29623+ nh = whlist->nh_num;
29624+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
29625+ p += AUFS_WH_PFX_LEN;
29626+ for (u = 0; u < nh; u++) {
29627+ head = whlist->nh_head + u;
c06a8ce3
AM
29628+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
29629+ destr = &pos->wh_str;
dece6358
AM
29630+ memcpy(p, destr->name, destr->len);
29631+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 29632+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
29633+ if (unlikely(err))
29634+ break;
29635+ }
29636+ }
29637+
537831f9 29638+ free_page((unsigned long)o);
dece6358 29639+
4f0767ce 29640+out:
dece6358
AM
29641+ AuTraceErr(err);
29642+ return err;
29643+#else
29644+ return 0;
29645+#endif
29646+}
29647+
1facf9fc 29648+static int au_do_read_vdir(struct fillvdir_arg *arg)
29649+{
29650+ int err;
dece6358 29651+ unsigned int rdhash;
1facf9fc 29652+ loff_t offset;
dece6358
AM
29653+ aufs_bindex_t bend, bindex, bstart;
29654+ unsigned char shwh;
1facf9fc 29655+ struct file *hf, *file;
29656+ struct super_block *sb;
29657+
1facf9fc 29658+ file = arg->file;
2000de60 29659+ sb = file->f_path.dentry->d_sb;
dece6358
AM
29660+ SiMustAnyLock(sb);
29661+
29662+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 29663+ if (!rdhash)
29664+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
29665+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
29666+ if (unlikely(err))
1facf9fc 29667+ goto out;
dece6358
AM
29668+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
29669+ if (unlikely(err))
1facf9fc 29670+ goto out_delist;
29671+
29672+ err = 0;
29673+ arg->flags = 0;
dece6358
AM
29674+ shwh = 0;
29675+ if (au_opt_test(au_mntflags(sb), SHWH)) {
29676+ shwh = 1;
29677+ au_fset_fillvdir(arg->flags, SHWH);
29678+ }
29679+ bstart = au_fbstart(file);
4a4d8108 29680+ bend = au_fbend_dir(file);
dece6358 29681+ for (bindex = bstart; !err && bindex <= bend; bindex++) {
4a4d8108 29682+ hf = au_hf_dir(file, bindex);
1facf9fc 29683+ if (!hf)
29684+ continue;
29685+
29686+ offset = vfsub_llseek(hf, 0, SEEK_SET);
29687+ err = offset;
29688+ if (unlikely(offset))
29689+ break;
29690+
29691+ arg->bindex = bindex;
29692+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358
AM
29693+ if (shwh
29694+ || (bindex != bend
29695+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 29696+ au_fset_fillvdir(arg->flags, WHABLE);
29697+ do {
29698+ arg->err = 0;
29699+ au_fclr_fillvdir(arg->flags, CALLED);
29700+ /* smp_mb(); */
392086de 29701+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 29702+ if (err >= 0)
29703+ err = arg->err;
29704+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
29705+
29706+ /*
29707+ * dir_relax() may be good for concurrency, but aufs should not
29708+ * use it since it will cause a lockdep problem.
29709+ */
1facf9fc 29710+ }
dece6358
AM
29711+
29712+ if (!err && shwh)
29713+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
29714+
29715+ au_nhash_wh_free(&arg->whlist);
1facf9fc 29716+
4f0767ce 29717+out_delist:
dece6358 29718+ au_nhash_de_free(&arg->delist);
4f0767ce 29719+out:
1facf9fc 29720+ return err;
29721+}
29722+
29723+static int read_vdir(struct file *file, int may_read)
29724+{
29725+ int err;
29726+ unsigned long expire;
29727+ unsigned char do_read;
392086de
AM
29728+ struct fillvdir_arg arg = {
29729+ .ctx = {
2000de60 29730+ .actor = fillvdir
392086de
AM
29731+ }
29732+ };
1facf9fc 29733+ struct inode *inode;
29734+ struct au_vdir *vdir, *allocated;
29735+
29736+ err = 0;
c06a8ce3 29737+ inode = file_inode(file);
1facf9fc 29738+ IMustLock(inode);
dece6358
AM
29739+ SiMustAnyLock(inode->i_sb);
29740+
1facf9fc 29741+ allocated = NULL;
29742+ do_read = 0;
29743+ expire = au_sbi(inode->i_sb)->si_rdcache;
29744+ vdir = au_ivdir(inode);
29745+ if (!vdir) {
29746+ do_read = 1;
1308ab2a 29747+ vdir = alloc_vdir(file);
1facf9fc 29748+ err = PTR_ERR(vdir);
29749+ if (IS_ERR(vdir))
29750+ goto out;
29751+ err = 0;
29752+ allocated = vdir;
29753+ } else if (may_read
29754+ && (inode->i_version != vdir->vd_version
29755+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
29756+ do_read = 1;
29757+ err = reinit_vdir(vdir);
29758+ if (unlikely(err))
29759+ goto out;
29760+ }
29761+
29762+ if (!do_read)
29763+ return 0; /* success */
29764+
29765+ arg.file = file;
29766+ arg.vdir = vdir;
29767+ err = au_do_read_vdir(&arg);
29768+ if (!err) {
392086de 29769+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
1facf9fc 29770+ vdir->vd_version = inode->i_version;
29771+ vdir->vd_last.ul = 0;
29772+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
29773+ if (allocated)
29774+ au_set_ivdir(inode, allocated);
29775+ } else if (allocated)
29776+ au_vdir_free(allocated);
29777+
4f0767ce 29778+out:
1facf9fc 29779+ return err;
29780+}
29781+
29782+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
29783+{
29784+ int err, rerr;
29785+ unsigned long ul, n;
29786+ const unsigned int deblk_sz = src->vd_deblk_sz;
29787+
29788+ AuDebugOn(tgt->vd_nblk != 1);
29789+
29790+ err = -ENOMEM;
29791+ if (tgt->vd_nblk < src->vd_nblk) {
29792+ unsigned char **p;
29793+
dece6358
AM
29794+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
29795+ GFP_NOFS);
1facf9fc 29796+ if (unlikely(!p))
29797+ goto out;
29798+ tgt->vd_deblk = p;
29799+ }
29800+
1308ab2a 29801+ if (tgt->vd_deblk_sz != deblk_sz) {
29802+ unsigned char *p;
29803+
29804+ tgt->vd_deblk_sz = deblk_sz;
29805+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
29806+ if (unlikely(!p))
29807+ goto out;
29808+ tgt->vd_deblk[0] = p;
29809+ }
1facf9fc 29810+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 29811+ tgt->vd_version = src->vd_version;
29812+ tgt->vd_jiffy = src->vd_jiffy;
29813+
29814+ n = src->vd_nblk;
29815+ for (ul = 1; ul < n; ul++) {
dece6358
AM
29816+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
29817+ GFP_NOFS);
29818+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 29819+ goto out;
1308ab2a 29820+ tgt->vd_nblk++;
1facf9fc 29821+ }
1308ab2a 29822+ tgt->vd_nblk = n;
29823+ tgt->vd_last.ul = tgt->vd_last.ul;
29824+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
29825+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
29826+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 29827+ /* smp_mb(); */
29828+ return 0; /* success */
29829+
4f0767ce 29830+out:
1facf9fc 29831+ rerr = reinit_vdir(tgt);
29832+ BUG_ON(rerr);
29833+ return err;
29834+}
29835+
29836+int au_vdir_init(struct file *file)
29837+{
29838+ int err;
29839+ struct inode *inode;
29840+ struct au_vdir *vdir_cache, *allocated;
29841+
392086de 29842+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 29843+ err = read_vdir(file, !file->f_pos);
29844+ if (unlikely(err))
29845+ goto out;
29846+
29847+ allocated = NULL;
29848+ vdir_cache = au_fvdir_cache(file);
29849+ if (!vdir_cache) {
1308ab2a 29850+ vdir_cache = alloc_vdir(file);
1facf9fc 29851+ err = PTR_ERR(vdir_cache);
29852+ if (IS_ERR(vdir_cache))
29853+ goto out;
29854+ allocated = vdir_cache;
29855+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 29856+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 29857+ err = reinit_vdir(vdir_cache);
29858+ if (unlikely(err))
29859+ goto out;
29860+ } else
29861+ return 0; /* success */
29862+
c06a8ce3 29863+ inode = file_inode(file);
1facf9fc 29864+ err = copy_vdir(vdir_cache, au_ivdir(inode));
29865+ if (!err) {
29866+ file->f_version = inode->i_version;
29867+ if (allocated)
29868+ au_set_fvdir_cache(file, allocated);
29869+ } else if (allocated)
29870+ au_vdir_free(allocated);
29871+
4f0767ce 29872+out:
1facf9fc 29873+ return err;
29874+}
29875+
29876+static loff_t calc_offset(struct au_vdir *vdir)
29877+{
29878+ loff_t offset;
29879+ union au_vdir_deblk_p p;
29880+
29881+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
29882+ offset = vdir->vd_last.p.deblk - p.deblk;
29883+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
29884+ return offset;
29885+}
29886+
29887+/* returns true or false */
392086de 29888+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 29889+{
29890+ int valid;
29891+ unsigned int deblk_sz;
29892+ unsigned long ul, n;
29893+ loff_t offset;
29894+ union au_vdir_deblk_p p, deblk_end;
29895+ struct au_vdir *vdir_cache;
29896+
29897+ valid = 1;
29898+ vdir_cache = au_fvdir_cache(file);
29899+ offset = calc_offset(vdir_cache);
29900+ AuDbg("offset %lld\n", offset);
392086de 29901+ if (ctx->pos == offset)
1facf9fc 29902+ goto out;
29903+
29904+ vdir_cache->vd_last.ul = 0;
29905+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 29906+ if (!ctx->pos)
1facf9fc 29907+ goto out;
29908+
29909+ valid = 0;
29910+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 29911+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 29912+ AuDbg("ul %lu\n", ul);
29913+ if (ul >= vdir_cache->vd_nblk)
29914+ goto out;
29915+
29916+ n = vdir_cache->vd_nblk;
29917+ for (; ul < n; ul++) {
29918+ p.deblk = vdir_cache->vd_deblk[ul];
29919+ deblk_end.deblk = p.deblk + deblk_sz;
29920+ offset = ul;
29921+ offset *= deblk_sz;
392086de 29922+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 29923+ unsigned int l;
29924+
29925+ l = calc_size(p.de->de_str.len);
29926+ offset += l;
29927+ p.deblk += l;
29928+ }
29929+ if (!is_deblk_end(&p, &deblk_end)) {
29930+ valid = 1;
29931+ vdir_cache->vd_last.ul = ul;
29932+ vdir_cache->vd_last.p = p;
29933+ break;
29934+ }
29935+ }
29936+
4f0767ce 29937+out:
1facf9fc 29938+ /* smp_mb(); */
29939+ AuTraceErr(!valid);
29940+ return valid;
29941+}
29942+
392086de 29943+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 29944+{
1facf9fc 29945+ unsigned int l, deblk_sz;
29946+ union au_vdir_deblk_p deblk_end;
29947+ struct au_vdir *vdir_cache;
29948+ struct au_vdir_de *de;
29949+
29950+ vdir_cache = au_fvdir_cache(file);
392086de 29951+ if (!seek_vdir(file, ctx))
1facf9fc 29952+ return 0;
29953+
29954+ deblk_sz = vdir_cache->vd_deblk_sz;
29955+ while (1) {
29956+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
29957+ deblk_end.deblk += deblk_sz;
29958+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
29959+ de = vdir_cache->vd_last.p.de;
29960+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 29961+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 29962+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
29963+ if (unlikely(!dir_emit(ctx, de->de_str.name,
29964+ de->de_str.len, de->de_ino,
29965+ de->de_type))) {
1facf9fc 29966+ /* todo: ignore the error caused by udba? */
29967+ /* return err; */
29968+ return 0;
29969+ }
29970+
29971+ l = calc_size(de->de_str.len);
29972+ vdir_cache->vd_last.p.deblk += l;
392086de 29973+ ctx->pos += l;
1facf9fc 29974+ }
29975+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
29976+ vdir_cache->vd_last.ul++;
29977+ vdir_cache->vd_last.p.deblk
29978+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 29979+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 29980+ continue;
29981+ }
29982+ break;
29983+ }
29984+
29985+ /* smp_mb(); */
29986+ return 0;
29987+}
7f207e10
AM
29988diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
29989--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 29990+++ linux/fs/aufs/vfsub.c 2015-09-24 10:47:58.258053165 +0200
5527c038 29991@@ -0,0 +1,848 @@
1facf9fc 29992+/*
2000de60 29993+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 29994+ *
29995+ * This program, aufs is free software; you can redistribute it and/or modify
29996+ * it under the terms of the GNU General Public License as published by
29997+ * the Free Software Foundation; either version 2 of the License, or
29998+ * (at your option) any later version.
dece6358
AM
29999+ *
30000+ * This program is distributed in the hope that it will be useful,
30001+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30002+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30003+ * GNU General Public License for more details.
30004+ *
30005+ * You should have received a copy of the GNU General Public License
523b37e3 30006+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30007+ */
30008+
30009+/*
30010+ * sub-routines for VFS
30011+ */
30012+
dece6358
AM
30013+#include <linux/namei.h>
30014+#include <linux/security.h>
30015+#include <linux/splice.h>
1facf9fc 30016+#include "aufs.h"
30017+
30018+int vfsub_update_h_iattr(struct path *h_path, int *did)
30019+{
30020+ int err;
30021+ struct kstat st;
30022+ struct super_block *h_sb;
30023+
30024+ /* for remote fs, leave work for its getattr or d_revalidate */
30025+ /* for bad i_attr fs, handle them in aufs_getattr() */
30026+ /* still some fs may acquire i_mutex. we need to skip them */
30027+ err = 0;
30028+ if (!did)
30029+ did = &err;
30030+ h_sb = h_path->dentry->d_sb;
30031+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
30032+ if (*did)
c06a8ce3 30033+ err = vfs_getattr(h_path, &st);
1facf9fc 30034+
30035+ return err;
30036+}
30037+
30038+/* ---------------------------------------------------------------------- */
30039+
4a4d8108 30040+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 30041+{
30042+ struct file *file;
30043+
b4510431 30044+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 30045+ current_cred());
2cbb1c4b
JR
30046+ if (!IS_ERR_OR_NULL(file)
30047+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
5527c038 30048+ i_readcount_inc(d_inode(path->dentry));
4a4d8108 30049+
1308ab2a 30050+ return file;
30051+}
30052+
1facf9fc 30053+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
30054+{
30055+ struct file *file;
30056+
2cbb1c4b 30057+ lockdep_off();
7f207e10 30058+ file = filp_open(path,
2cbb1c4b 30059+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 30060+ mode);
2cbb1c4b 30061+ lockdep_on();
1facf9fc 30062+ if (IS_ERR(file))
30063+ goto out;
30064+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30065+
4f0767ce 30066+out:
1facf9fc 30067+ return file;
30068+}
30069+
b912730e
AM
30070+/*
30071+ * Ideally this function should call VFS:do_last() in order to keep all its
30072+ * checkings. But it is very hard for aufs to regenerate several VFS internal
30073+ * structure such as nameidata. This is a second (or third) best approach.
30074+ * cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open().
30075+ */
30076+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
30077+ struct vfsub_aopen_args *args, struct au_branch *br)
30078+{
30079+ int err;
30080+ struct file *file = args->file;
30081+ /* copied from linux/fs/namei.c:atomic_open() */
30082+ struct dentry *const DENTRY_NOT_SET = (void *)-1UL;
30083+
30084+ IMustLock(dir);
30085+ AuDebugOn(!dir->i_op->atomic_open);
30086+
30087+ err = au_br_test_oflag(args->open_flag, br);
30088+ if (unlikely(err))
30089+ goto out;
30090+
30091+ args->file->f_path.dentry = DENTRY_NOT_SET;
30092+ args->file->f_path.mnt = au_br_mnt(br);
30093+ err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag,
30094+ args->create_mode, args->opened);
30095+ if (err >= 0) {
30096+ /* some filesystems don't set FILE_CREATED while succeeded? */
30097+ if (*args->opened & FILE_CREATED)
30098+ fsnotify_create(dir, dentry);
30099+ } else
30100+ goto out;
30101+
30102+
30103+ if (!err) {
30104+ /* todo: call VFS:may_open() here */
30105+ err = open_check_o_direct(file);
30106+ /* todo: ima_file_check() too? */
30107+ if (!err && (args->open_flag & __FMODE_EXEC))
30108+ err = deny_write_access(file);
30109+ if (unlikely(err))
30110+ /* note that the file is created and still opened */
30111+ goto out;
30112+ }
30113+
30114+ atomic_inc(&br->br_count);
30115+ fsnotify_open(file);
30116+
30117+out:
30118+ return err;
30119+}
30120+
1facf9fc 30121+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
30122+{
30123+ int err;
30124+
1facf9fc 30125+ err = kern_path(name, flags, path);
5527c038 30126+ if (!err && d_is_positive(path->dentry))
1facf9fc 30127+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
30128+ return err;
30129+}
30130+
30131+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
30132+ int len)
30133+{
30134+ struct path path = {
30135+ .mnt = NULL
30136+ };
30137+
1308ab2a 30138+ /* VFS checks it too, but by WARN_ON_ONCE() */
5527c038 30139+ IMustLock(d_inode(parent));
1facf9fc 30140+
30141+ path.dentry = lookup_one_len(name, parent, len);
30142+ if (IS_ERR(path.dentry))
30143+ goto out;
5527c038 30144+ if (d_is_positive(path.dentry))
1facf9fc 30145+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
30146+
4f0767ce 30147+out:
4a4d8108 30148+ AuTraceErrPtr(path.dentry);
1facf9fc 30149+ return path.dentry;
30150+}
30151+
b4510431 30152+void vfsub_call_lkup_one(void *args)
2cbb1c4b 30153+{
b4510431
AM
30154+ struct vfsub_lkup_one_args *a = args;
30155+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
30156+}
30157+
1facf9fc 30158+/* ---------------------------------------------------------------------- */
30159+
30160+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
30161+ struct dentry *d2, struct au_hinode *hdir2)
30162+{
30163+ struct dentry *d;
30164+
2cbb1c4b 30165+ lockdep_off();
1facf9fc 30166+ d = lock_rename(d1, d2);
2cbb1c4b 30167+ lockdep_on();
4a4d8108 30168+ au_hn_suspend(hdir1);
1facf9fc 30169+ if (hdir1 != hdir2)
4a4d8108 30170+ au_hn_suspend(hdir2);
1facf9fc 30171+
30172+ return d;
30173+}
30174+
30175+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
30176+ struct dentry *d2, struct au_hinode *hdir2)
30177+{
4a4d8108 30178+ au_hn_resume(hdir1);
1facf9fc 30179+ if (hdir1 != hdir2)
4a4d8108 30180+ au_hn_resume(hdir2);
2cbb1c4b 30181+ lockdep_off();
1facf9fc 30182+ unlock_rename(d1, d2);
2cbb1c4b 30183+ lockdep_on();
1facf9fc 30184+}
30185+
30186+/* ---------------------------------------------------------------------- */
30187+
b4510431 30188+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 30189+{
30190+ int err;
30191+ struct dentry *d;
30192+
30193+ IMustLock(dir);
30194+
30195+ d = path->dentry;
30196+ path->dentry = d->d_parent;
b752ccd1 30197+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 30198+ path->dentry = d;
30199+ if (unlikely(err))
30200+ goto out;
30201+
c1595e42 30202+ lockdep_off();
b4510431 30203+ err = vfs_create(dir, path->dentry, mode, want_excl);
c1595e42 30204+ lockdep_on();
1facf9fc 30205+ if (!err) {
30206+ struct path tmp = *path;
30207+ int did;
30208+
30209+ vfsub_update_h_iattr(&tmp, &did);
30210+ if (did) {
30211+ tmp.dentry = path->dentry->d_parent;
30212+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30213+ }
30214+ /*ignore*/
30215+ }
30216+
4f0767ce 30217+out:
1facf9fc 30218+ return err;
30219+}
30220+
30221+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
30222+{
30223+ int err;
30224+ struct dentry *d;
30225+
30226+ IMustLock(dir);
30227+
30228+ d = path->dentry;
30229+ path->dentry = d->d_parent;
b752ccd1 30230+ err = security_path_symlink(path, d, symname);
1facf9fc 30231+ path->dentry = d;
30232+ if (unlikely(err))
30233+ goto out;
30234+
c1595e42 30235+ lockdep_off();
1facf9fc 30236+ err = vfs_symlink(dir, path->dentry, symname);
c1595e42 30237+ lockdep_on();
1facf9fc 30238+ if (!err) {
30239+ struct path tmp = *path;
30240+ int did;
30241+
30242+ vfsub_update_h_iattr(&tmp, &did);
30243+ if (did) {
30244+ tmp.dentry = path->dentry->d_parent;
30245+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30246+ }
30247+ /*ignore*/
30248+ }
30249+
4f0767ce 30250+out:
1facf9fc 30251+ return err;
30252+}
30253+
30254+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
30255+{
30256+ int err;
30257+ struct dentry *d;
30258+
30259+ IMustLock(dir);
30260+
30261+ d = path->dentry;
30262+ path->dentry = d->d_parent;
027c5e7a 30263+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 30264+ path->dentry = d;
30265+ if (unlikely(err))
30266+ goto out;
30267+
c1595e42 30268+ lockdep_off();
1facf9fc 30269+ err = vfs_mknod(dir, path->dentry, mode, dev);
c1595e42 30270+ lockdep_on();
1facf9fc 30271+ if (!err) {
30272+ struct path tmp = *path;
30273+ int did;
30274+
30275+ vfsub_update_h_iattr(&tmp, &did);
30276+ if (did) {
30277+ tmp.dentry = path->dentry->d_parent;
30278+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30279+ }
30280+ /*ignore*/
30281+ }
30282+
4f0767ce 30283+out:
1facf9fc 30284+ return err;
30285+}
30286+
30287+static int au_test_nlink(struct inode *inode)
30288+{
30289+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
30290+
30291+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
30292+ || inode->i_nlink < link_max)
30293+ return 0;
30294+ return -EMLINK;
30295+}
30296+
523b37e3
AM
30297+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
30298+ struct inode **delegated_inode)
1facf9fc 30299+{
30300+ int err;
30301+ struct dentry *d;
30302+
30303+ IMustLock(dir);
30304+
5527c038 30305+ err = au_test_nlink(d_inode(src_dentry));
1facf9fc 30306+ if (unlikely(err))
30307+ return err;
30308+
b4510431 30309+ /* we don't call may_linkat() */
1facf9fc 30310+ d = path->dentry;
30311+ path->dentry = d->d_parent;
b752ccd1 30312+ err = security_path_link(src_dentry, path, d);
1facf9fc 30313+ path->dentry = d;
30314+ if (unlikely(err))
30315+ goto out;
30316+
2cbb1c4b 30317+ lockdep_off();
523b37e3 30318+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 30319+ lockdep_on();
1facf9fc 30320+ if (!err) {
30321+ struct path tmp = *path;
30322+ int did;
30323+
30324+ /* fuse has different memory inode for the same inumber */
30325+ vfsub_update_h_iattr(&tmp, &did);
30326+ if (did) {
30327+ tmp.dentry = path->dentry->d_parent;
30328+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30329+ tmp.dentry = src_dentry;
30330+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30331+ }
30332+ /*ignore*/
30333+ }
30334+
4f0767ce 30335+out:
1facf9fc 30336+ return err;
30337+}
30338+
30339+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3
AM
30340+ struct inode *dir, struct path *path,
30341+ struct inode **delegated_inode)
1facf9fc 30342+{
30343+ int err;
30344+ struct path tmp = {
30345+ .mnt = path->mnt
30346+ };
30347+ struct dentry *d;
30348+
30349+ IMustLock(dir);
30350+ IMustLock(src_dir);
30351+
30352+ d = path->dentry;
30353+ path->dentry = d->d_parent;
30354+ tmp.dentry = src_dentry->d_parent;
38d290e6 30355+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
1facf9fc 30356+ path->dentry = d;
30357+ if (unlikely(err))
30358+ goto out;
30359+
2cbb1c4b 30360+ lockdep_off();
523b37e3 30361+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
38d290e6 30362+ delegated_inode, /*flags*/0);
2cbb1c4b 30363+ lockdep_on();
1facf9fc 30364+ if (!err) {
30365+ int did;
30366+
30367+ tmp.dentry = d->d_parent;
30368+ vfsub_update_h_iattr(&tmp, &did);
30369+ if (did) {
30370+ tmp.dentry = src_dentry;
30371+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30372+ tmp.dentry = src_dentry->d_parent;
30373+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30374+ }
30375+ /*ignore*/
30376+ }
30377+
4f0767ce 30378+out:
1facf9fc 30379+ return err;
30380+}
30381+
30382+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
30383+{
30384+ int err;
30385+ struct dentry *d;
30386+
30387+ IMustLock(dir);
30388+
30389+ d = path->dentry;
30390+ path->dentry = d->d_parent;
b752ccd1 30391+ err = security_path_mkdir(path, d, mode);
1facf9fc 30392+ path->dentry = d;
30393+ if (unlikely(err))
30394+ goto out;
30395+
c1595e42 30396+ lockdep_off();
1facf9fc 30397+ err = vfs_mkdir(dir, path->dentry, mode);
c1595e42 30398+ lockdep_on();
1facf9fc 30399+ if (!err) {
30400+ struct path tmp = *path;
30401+ int did;
30402+
30403+ vfsub_update_h_iattr(&tmp, &did);
30404+ if (did) {
30405+ tmp.dentry = path->dentry->d_parent;
30406+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30407+ }
30408+ /*ignore*/
30409+ }
30410+
4f0767ce 30411+out:
1facf9fc 30412+ return err;
30413+}
30414+
30415+int vfsub_rmdir(struct inode *dir, struct path *path)
30416+{
30417+ int err;
30418+ struct dentry *d;
30419+
30420+ IMustLock(dir);
30421+
30422+ d = path->dentry;
30423+ path->dentry = d->d_parent;
b752ccd1 30424+ err = security_path_rmdir(path, d);
1facf9fc 30425+ path->dentry = d;
30426+ if (unlikely(err))
30427+ goto out;
30428+
2cbb1c4b 30429+ lockdep_off();
1facf9fc 30430+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 30431+ lockdep_on();
1facf9fc 30432+ if (!err) {
30433+ struct path tmp = {
30434+ .dentry = path->dentry->d_parent,
30435+ .mnt = path->mnt
30436+ };
30437+
30438+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
30439+ }
30440+
4f0767ce 30441+out:
1facf9fc 30442+ return err;
30443+}
30444+
30445+/* ---------------------------------------------------------------------- */
30446+
9dbd164d 30447+/* todo: support mmap_sem? */
1facf9fc 30448+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
30449+ loff_t *ppos)
30450+{
30451+ ssize_t err;
30452+
2cbb1c4b 30453+ lockdep_off();
1facf9fc 30454+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 30455+ lockdep_on();
1facf9fc 30456+ if (err >= 0)
30457+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30458+ return err;
30459+}
30460+
30461+/* todo: kernel_read()? */
30462+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
30463+ loff_t *ppos)
30464+{
30465+ ssize_t err;
30466+ mm_segment_t oldfs;
b752ccd1
AM
30467+ union {
30468+ void *k;
30469+ char __user *u;
30470+ } buf;
1facf9fc 30471+
b752ccd1 30472+ buf.k = kbuf;
1facf9fc 30473+ oldfs = get_fs();
30474+ set_fs(KERNEL_DS);
b752ccd1 30475+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 30476+ set_fs(oldfs);
30477+ return err;
30478+}
30479+
30480+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
30481+ loff_t *ppos)
30482+{
30483+ ssize_t err;
30484+
2cbb1c4b 30485+ lockdep_off();
1facf9fc 30486+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 30487+ lockdep_on();
1facf9fc 30488+ if (err >= 0)
30489+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30490+ return err;
30491+}
30492+
30493+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
30494+{
30495+ ssize_t err;
30496+ mm_segment_t oldfs;
b752ccd1
AM
30497+ union {
30498+ void *k;
30499+ const char __user *u;
30500+ } buf;
1facf9fc 30501+
b752ccd1 30502+ buf.k = kbuf;
1facf9fc 30503+ oldfs = get_fs();
30504+ set_fs(KERNEL_DS);
b752ccd1 30505+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 30506+ set_fs(oldfs);
30507+ return err;
30508+}
30509+
4a4d8108
AM
30510+int vfsub_flush(struct file *file, fl_owner_t id)
30511+{
30512+ int err;
30513+
30514+ err = 0;
523b37e3 30515+ if (file->f_op->flush) {
2000de60 30516+ if (!au_test_nfs(file->f_path.dentry->d_sb))
2cbb1c4b
JR
30517+ err = file->f_op->flush(file, id);
30518+ else {
30519+ lockdep_off();
30520+ err = file->f_op->flush(file, id);
30521+ lockdep_on();
30522+ }
4a4d8108
AM
30523+ if (!err)
30524+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
30525+ /*ignore*/
30526+ }
30527+ return err;
30528+}
30529+
392086de 30530+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 30531+{
30532+ int err;
30533+
523b37e3 30534+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 30535+
2cbb1c4b 30536+ lockdep_off();
392086de 30537+ err = iterate_dir(file, ctx);
2cbb1c4b 30538+ lockdep_on();
1facf9fc 30539+ if (err >= 0)
30540+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30541+ return err;
30542+}
30543+
30544+long vfsub_splice_to(struct file *in, loff_t *ppos,
30545+ struct pipe_inode_info *pipe, size_t len,
30546+ unsigned int flags)
30547+{
30548+ long err;
30549+
2cbb1c4b 30550+ lockdep_off();
0fc653ad 30551+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 30552+ lockdep_on();
4a4d8108 30553+ file_accessed(in);
1facf9fc 30554+ if (err >= 0)
30555+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
30556+ return err;
30557+}
30558+
30559+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
30560+ loff_t *ppos, size_t len, unsigned int flags)
30561+{
30562+ long err;
30563+
2cbb1c4b 30564+ lockdep_off();
0fc653ad 30565+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 30566+ lockdep_on();
1facf9fc 30567+ if (err >= 0)
30568+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
30569+ return err;
30570+}
30571+
53392da6
AM
30572+int vfsub_fsync(struct file *file, struct path *path, int datasync)
30573+{
30574+ int err;
30575+
30576+ /* file can be NULL */
30577+ lockdep_off();
30578+ err = vfs_fsync(file, datasync);
30579+ lockdep_on();
30580+ if (!err) {
30581+ if (!path) {
30582+ AuDebugOn(!file);
30583+ path = &file->f_path;
30584+ }
30585+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
30586+ }
30587+ return err;
30588+}
30589+
1facf9fc 30590+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
30591+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
30592+ struct file *h_file)
30593+{
30594+ int err;
30595+ struct inode *h_inode;
c06a8ce3 30596+ struct super_block *h_sb;
1facf9fc 30597+
1facf9fc 30598+ if (!h_file) {
c06a8ce3
AM
30599+ err = vfsub_truncate(h_path, length);
30600+ goto out;
1facf9fc 30601+ }
30602+
5527c038 30603+ h_inode = d_inode(h_path->dentry);
c06a8ce3
AM
30604+ h_sb = h_inode->i_sb;
30605+ lockdep_off();
30606+ sb_start_write(h_sb);
30607+ lockdep_on();
1facf9fc 30608+ err = locks_verify_truncate(h_inode, h_file, length);
30609+ if (!err)
953406b4 30610+ err = security_path_truncate(h_path);
2cbb1c4b
JR
30611+ if (!err) {
30612+ lockdep_off();
1facf9fc 30613+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
30614+ lockdep_on();
30615+ }
c06a8ce3
AM
30616+ lockdep_off();
30617+ sb_end_write(h_sb);
30618+ lockdep_on();
1facf9fc 30619+
4f0767ce 30620+out:
1facf9fc 30621+ return err;
30622+}
30623+
30624+/* ---------------------------------------------------------------------- */
30625+
30626+struct au_vfsub_mkdir_args {
30627+ int *errp;
30628+ struct inode *dir;
30629+ struct path *path;
30630+ int mode;
30631+};
30632+
30633+static void au_call_vfsub_mkdir(void *args)
30634+{
30635+ struct au_vfsub_mkdir_args *a = args;
30636+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
30637+}
30638+
30639+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
30640+{
30641+ int err, do_sio, wkq_err;
30642+
30643+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
30644+ if (!do_sio) {
30645+ lockdep_off();
1facf9fc 30646+ err = vfsub_mkdir(dir, path, mode);
c1595e42
JR
30647+ lockdep_on();
30648+ } else {
1facf9fc 30649+ struct au_vfsub_mkdir_args args = {
30650+ .errp = &err,
30651+ .dir = dir,
30652+ .path = path,
30653+ .mode = mode
30654+ };
30655+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
30656+ if (unlikely(wkq_err))
30657+ err = wkq_err;
30658+ }
30659+
30660+ return err;
30661+}
30662+
30663+struct au_vfsub_rmdir_args {
30664+ int *errp;
30665+ struct inode *dir;
30666+ struct path *path;
30667+};
30668+
30669+static void au_call_vfsub_rmdir(void *args)
30670+{
30671+ struct au_vfsub_rmdir_args *a = args;
30672+ *a->errp = vfsub_rmdir(a->dir, a->path);
30673+}
30674+
30675+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
30676+{
30677+ int err, do_sio, wkq_err;
30678+
30679+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
30680+ if (!do_sio) {
30681+ lockdep_off();
1facf9fc 30682+ err = vfsub_rmdir(dir, path);
c1595e42
JR
30683+ lockdep_on();
30684+ } else {
1facf9fc 30685+ struct au_vfsub_rmdir_args args = {
30686+ .errp = &err,
30687+ .dir = dir,
30688+ .path = path
30689+ };
30690+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
30691+ if (unlikely(wkq_err))
30692+ err = wkq_err;
30693+ }
30694+
30695+ return err;
30696+}
30697+
30698+/* ---------------------------------------------------------------------- */
30699+
30700+struct notify_change_args {
30701+ int *errp;
30702+ struct path *path;
30703+ struct iattr *ia;
523b37e3 30704+ struct inode **delegated_inode;
1facf9fc 30705+};
30706+
30707+static void call_notify_change(void *args)
30708+{
30709+ struct notify_change_args *a = args;
30710+ struct inode *h_inode;
30711+
5527c038 30712+ h_inode = d_inode(a->path->dentry);
1facf9fc 30713+ IMustLock(h_inode);
30714+
30715+ *a->errp = -EPERM;
30716+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
c1595e42 30717+ lockdep_off();
523b37e3
AM
30718+ *a->errp = notify_change(a->path->dentry, a->ia,
30719+ a->delegated_inode);
c1595e42 30720+ lockdep_on();
1facf9fc 30721+ if (!*a->errp)
30722+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
30723+ }
30724+ AuTraceErr(*a->errp);
30725+}
30726+
523b37e3
AM
30727+int vfsub_notify_change(struct path *path, struct iattr *ia,
30728+ struct inode **delegated_inode)
1facf9fc 30729+{
30730+ int err;
30731+ struct notify_change_args args = {
523b37e3
AM
30732+ .errp = &err,
30733+ .path = path,
30734+ .ia = ia,
30735+ .delegated_inode = delegated_inode
1facf9fc 30736+ };
30737+
30738+ call_notify_change(&args);
30739+
30740+ return err;
30741+}
30742+
523b37e3
AM
30743+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
30744+ struct inode **delegated_inode)
1facf9fc 30745+{
30746+ int err, wkq_err;
30747+ struct notify_change_args args = {
523b37e3
AM
30748+ .errp = &err,
30749+ .path = path,
30750+ .ia = ia,
30751+ .delegated_inode = delegated_inode
1facf9fc 30752+ };
30753+
30754+ wkq_err = au_wkq_wait(call_notify_change, &args);
30755+ if (unlikely(wkq_err))
30756+ err = wkq_err;
30757+
30758+ return err;
30759+}
30760+
30761+/* ---------------------------------------------------------------------- */
30762+
30763+struct unlink_args {
30764+ int *errp;
30765+ struct inode *dir;
30766+ struct path *path;
523b37e3 30767+ struct inode **delegated_inode;
1facf9fc 30768+};
30769+
30770+static void call_unlink(void *args)
30771+{
30772+ struct unlink_args *a = args;
30773+ struct dentry *d = a->path->dentry;
30774+ struct inode *h_inode;
30775+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
c1595e42 30776+ && au_dcount(d) == 1);
1facf9fc 30777+
30778+ IMustLock(a->dir);
30779+
30780+ a->path->dentry = d->d_parent;
30781+ *a->errp = security_path_unlink(a->path, d);
30782+ a->path->dentry = d;
30783+ if (unlikely(*a->errp))
30784+ return;
30785+
30786+ if (!stop_sillyrename)
30787+ dget(d);
5527c038
JR
30788+ h_inode = NULL;
30789+ if (d_is_positive(d)) {
30790+ h_inode = d_inode(d);
027c5e7a 30791+ ihold(h_inode);
5527c038 30792+ }
1facf9fc 30793+
2cbb1c4b 30794+ lockdep_off();
523b37e3 30795+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 30796+ lockdep_on();
1facf9fc 30797+ if (!*a->errp) {
30798+ struct path tmp = {
30799+ .dentry = d->d_parent,
30800+ .mnt = a->path->mnt
30801+ };
30802+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
30803+ }
30804+
30805+ if (!stop_sillyrename)
30806+ dput(d);
30807+ if (h_inode)
30808+ iput(h_inode);
30809+
30810+ AuTraceErr(*a->errp);
30811+}
30812+
30813+/*
30814+ * @dir: must be locked.
30815+ * @dentry: target dentry.
30816+ */
523b37e3
AM
30817+int vfsub_unlink(struct inode *dir, struct path *path,
30818+ struct inode **delegated_inode, int force)
1facf9fc 30819+{
30820+ int err;
30821+ struct unlink_args args = {
523b37e3
AM
30822+ .errp = &err,
30823+ .dir = dir,
30824+ .path = path,
30825+ .delegated_inode = delegated_inode
1facf9fc 30826+ };
30827+
30828+ if (!force)
30829+ call_unlink(&args);
30830+ else {
30831+ int wkq_err;
30832+
30833+ wkq_err = au_wkq_wait(call_unlink, &args);
30834+ if (unlikely(wkq_err))
30835+ err = wkq_err;
30836+ }
30837+
30838+ return err;
30839+}
7f207e10
AM
30840diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
30841--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
30842+++ linux/fs/aufs/vfsub.h 2015-11-11 17:21:46.922197217 +0100
30843@@ -0,0 +1,287 @@
1facf9fc 30844+/*
2000de60 30845+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 30846+ *
30847+ * This program, aufs is free software; you can redistribute it and/or modify
30848+ * it under the terms of the GNU General Public License as published by
30849+ * the Free Software Foundation; either version 2 of the License, or
30850+ * (at your option) any later version.
dece6358
AM
30851+ *
30852+ * This program is distributed in the hope that it will be useful,
30853+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30854+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30855+ * GNU General Public License for more details.
30856+ *
30857+ * You should have received a copy of the GNU General Public License
523b37e3 30858+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30859+ */
30860+
30861+/*
30862+ * sub-routines for VFS
30863+ */
30864+
30865+#ifndef __AUFS_VFSUB_H__
30866+#define __AUFS_VFSUB_H__
30867+
30868+#ifdef __KERNEL__
30869+
30870+#include <linux/fs.h>
b4510431 30871+#include <linux/mount.h>
c1595e42 30872+#include <linux/xattr.h>
7f207e10 30873+#include "debug.h"
1facf9fc 30874+
7f207e10 30875+/* copied from linux/fs/internal.h */
2cbb1c4b 30876+/* todo: BAD approach!! */
c06a8ce3 30877+extern void __mnt_drop_write(struct vfsmount *);
b912730e 30878+extern int open_check_o_direct(struct file *f);
7f207e10
AM
30879+
30880+/* ---------------------------------------------------------------------- */
1facf9fc 30881+
30882+/* lock subclass for lower inode */
30883+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
30884+/* reduce? gave up. */
30885+enum {
c1595e42 30886+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
1facf9fc 30887+ AuLsc_I_PARENT, /* lower inode, parent first */
30888+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 30889+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 30890+ AuLsc_I_CHILD,
30891+ AuLsc_I_CHILD2,
30892+ AuLsc_I_End
30893+};
30894+
30895+/* to debug easier, do not make them inlined functions */
30896+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
30897+#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
30898+
30899+/* ---------------------------------------------------------------------- */
30900+
7f207e10
AM
30901+static inline void vfsub_drop_nlink(struct inode *inode)
30902+{
30903+ AuDebugOn(!inode->i_nlink);
30904+ drop_nlink(inode);
30905+}
30906+
027c5e7a
AM
30907+static inline void vfsub_dead_dir(struct inode *inode)
30908+{
30909+ AuDebugOn(!S_ISDIR(inode->i_mode));
30910+ inode->i_flags |= S_DEAD;
30911+ clear_nlink(inode);
30912+}
30913+
392086de
AM
30914+static inline int vfsub_native_ro(struct inode *inode)
30915+{
30916+ return (inode->i_sb->s_flags & MS_RDONLY)
30917+ || IS_RDONLY(inode)
30918+ /* || IS_APPEND(inode) */
30919+ || IS_IMMUTABLE(inode);
30920+}
30921+
7f207e10
AM
30922+/* ---------------------------------------------------------------------- */
30923+
30924+int vfsub_update_h_iattr(struct path *h_path, int *did);
30925+struct file *vfsub_dentry_open(struct path *path, int flags);
30926+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
b912730e
AM
30927+struct vfsub_aopen_args {
30928+ struct file *file;
30929+ unsigned int open_flag;
30930+ umode_t create_mode;
30931+ int *opened;
30932+};
30933+struct au_branch;
30934+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
30935+ struct vfsub_aopen_args *args, struct au_branch *br);
1facf9fc 30936+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 30937+
1facf9fc 30938+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
30939+ int len);
b4510431
AM
30940+
30941+struct vfsub_lkup_one_args {
30942+ struct dentry **errp;
30943+ struct qstr *name;
30944+ struct dentry *parent;
30945+};
30946+
30947+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
30948+ struct dentry *parent)
30949+{
30950+ return vfsub_lookup_one_len(name->name, parent, name->len);
30951+}
30952+
30953+void vfsub_call_lkup_one(void *args);
30954+
30955+/* ---------------------------------------------------------------------- */
30956+
30957+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
30958+{
30959+ int err;
076b876e 30960+
b4510431
AM
30961+ lockdep_off();
30962+ err = mnt_want_write(mnt);
30963+ lockdep_on();
30964+ return err;
30965+}
30966+
30967+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
30968+{
30969+ lockdep_off();
30970+ mnt_drop_write(mnt);
30971+ lockdep_on();
30972+}
1facf9fc 30973+
7e9cd9fe 30974+#if 0 /* reserved */
c06a8ce3
AM
30975+static inline void vfsub_mnt_drop_write_file(struct file *file)
30976+{
30977+ lockdep_off();
30978+ mnt_drop_write_file(file);
30979+ lockdep_on();
30980+}
7e9cd9fe 30981+#endif
c06a8ce3 30982+
1facf9fc 30983+/* ---------------------------------------------------------------------- */
30984+
30985+struct au_hinode;
30986+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
30987+ struct dentry *d2, struct au_hinode *hdir2);
30988+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
30989+ struct dentry *d2, struct au_hinode *hdir2);
30990+
537831f9
AM
30991+int vfsub_create(struct inode *dir, struct path *path, int mode,
30992+ bool want_excl);
1facf9fc 30993+int vfsub_symlink(struct inode *dir, struct path *path,
30994+ const char *symname);
30995+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
30996+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 30997+ struct path *path, struct inode **delegated_inode);
1facf9fc 30998+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3
AM
30999+ struct inode *hdir, struct path *path,
31000+ struct inode **delegated_inode);
1facf9fc 31001+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
31002+int vfsub_rmdir(struct inode *dir, struct path *path);
31003+
31004+/* ---------------------------------------------------------------------- */
31005+
31006+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
31007+ loff_t *ppos);
31008+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
31009+ loff_t *ppos);
31010+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
31011+ loff_t *ppos);
31012+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
31013+ loff_t *ppos);
4a4d8108 31014+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
31015+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
31016+
c06a8ce3
AM
31017+static inline loff_t vfsub_f_size_read(struct file *file)
31018+{
31019+ return i_size_read(file_inode(file));
31020+}
31021+
4a4d8108
AM
31022+static inline unsigned int vfsub_file_flags(struct file *file)
31023+{
31024+ unsigned int flags;
31025+
31026+ spin_lock(&file->f_lock);
31027+ flags = file->f_flags;
31028+ spin_unlock(&file->f_lock);
31029+
31030+ return flags;
31031+}
1308ab2a 31032+
7e9cd9fe 31033+#if 0 /* reserved */
1facf9fc 31034+static inline void vfsub_file_accessed(struct file *h_file)
31035+{
31036+ file_accessed(h_file);
31037+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
31038+}
7e9cd9fe 31039+#endif
1facf9fc 31040+
79b8bda9 31041+#if 0 /* reserved */
1facf9fc 31042+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
31043+ struct dentry *h_dentry)
31044+{
31045+ struct path h_path = {
31046+ .dentry = h_dentry,
31047+ .mnt = h_mnt
31048+ };
92d182d2 31049+ touch_atime(&h_path);
1facf9fc 31050+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
31051+}
79b8bda9 31052+#endif
1facf9fc 31053+
0c3ec466
AM
31054+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
31055+ int flags)
31056+{
7e9cd9fe 31057+ return generic_update_time(h_inode, ts, flags);
0c3ec466
AM
31058+ /* no vfsub_update_h_iattr() since we don't have struct path */
31059+}
31060+
4a4d8108
AM
31061+long vfsub_splice_to(struct file *in, loff_t *ppos,
31062+ struct pipe_inode_info *pipe, size_t len,
31063+ unsigned int flags);
31064+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
31065+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
31066+
31067+static inline long vfsub_truncate(struct path *path, loff_t length)
31068+{
31069+ long err;
076b876e 31070+
c06a8ce3
AM
31071+ lockdep_off();
31072+ err = vfs_truncate(path, length);
31073+ lockdep_on();
31074+ return err;
31075+}
31076+
4a4d8108
AM
31077+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
31078+ struct file *h_file);
53392da6 31079+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 31080+
1facf9fc 31081+/* ---------------------------------------------------------------------- */
31082+
31083+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
31084+{
31085+ loff_t err;
31086+
2cbb1c4b 31087+ lockdep_off();
1facf9fc 31088+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 31089+ lockdep_on();
1facf9fc 31090+ return err;
31091+}
31092+
31093+/* ---------------------------------------------------------------------- */
31094+
4a4d8108
AM
31095+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
31096+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
31097+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
31098+ struct inode **delegated_inode);
31099+int vfsub_notify_change(struct path *path, struct iattr *ia,
31100+ struct inode **delegated_inode);
31101+int vfsub_unlink(struct inode *dir, struct path *path,
31102+ struct inode **delegated_inode, int force);
4a4d8108 31103+
c1595e42
JR
31104+/* ---------------------------------------------------------------------- */
31105+
31106+static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
31107+ const void *value, size_t size, int flags)
31108+{
31109+ int err;
31110+
31111+ lockdep_off();
31112+ err = vfs_setxattr(dentry, name, value, size, flags);
31113+ lockdep_on();
31114+
31115+ return err;
31116+}
31117+
31118+static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
31119+{
31120+ int err;
31121+
31122+ lockdep_off();
31123+ err = vfs_removexattr(dentry, name);
31124+ lockdep_on();
31125+
31126+ return err;
31127+}
31128+
1facf9fc 31129+#endif /* __KERNEL__ */
31130+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
31131diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
31132--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 31133+++ linux/fs/aufs/wbr_policy.c 2015-09-24 10:47:58.258053165 +0200
076b876e 31134@@ -0,0 +1,765 @@
1facf9fc 31135+/*
2000de60 31136+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 31137+ *
31138+ * This program, aufs is free software; you can redistribute it and/or modify
31139+ * it under the terms of the GNU General Public License as published by
31140+ * the Free Software Foundation; either version 2 of the License, or
31141+ * (at your option) any later version.
dece6358
AM
31142+ *
31143+ * This program is distributed in the hope that it will be useful,
31144+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31145+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31146+ * GNU General Public License for more details.
31147+ *
31148+ * You should have received a copy of the GNU General Public License
523b37e3 31149+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31150+ */
31151+
31152+/*
31153+ * policies for selecting one among multiple writable branches
31154+ */
31155+
31156+#include <linux/statfs.h>
31157+#include "aufs.h"
31158+
31159+/* subset of cpup_attr() */
31160+static noinline_for_stack
31161+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
31162+{
31163+ int err, sbits;
31164+ struct iattr ia;
31165+ struct inode *h_isrc;
31166+
5527c038 31167+ h_isrc = d_inode(h_src);
1facf9fc 31168+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
31169+ ia.ia_mode = h_isrc->i_mode;
31170+ ia.ia_uid = h_isrc->i_uid;
31171+ ia.ia_gid = h_isrc->i_gid;
31172+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
5527c038 31173+ au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags);
523b37e3
AM
31174+ /* no delegation since it is just created */
31175+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 31176+
31177+ /* is this nfs only? */
31178+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
31179+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
31180+ ia.ia_mode = h_isrc->i_mode;
523b37e3 31181+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 31182+ }
31183+
31184+ return err;
31185+}
31186+
31187+#define AuCpdown_PARENT_OPQ 1
31188+#define AuCpdown_WHED (1 << 1)
31189+#define AuCpdown_MADE_DIR (1 << 2)
31190+#define AuCpdown_DIROPQ (1 << 3)
31191+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
31192+#define au_fset_cpdown(flags, name) \
31193+ do { (flags) |= AuCpdown_##name; } while (0)
31194+#define au_fclr_cpdown(flags, name) \
31195+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 31196+
1facf9fc 31197+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 31198+ unsigned int *flags)
1facf9fc 31199+{
31200+ int err;
31201+ struct dentry *opq_dentry;
31202+
31203+ opq_dentry = au_diropq_create(dentry, bdst);
31204+ err = PTR_ERR(opq_dentry);
31205+ if (IS_ERR(opq_dentry))
31206+ goto out;
31207+ dput(opq_dentry);
c2b27bf2 31208+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 31209+
4f0767ce 31210+out:
1facf9fc 31211+ return err;
31212+}
31213+
31214+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
31215+ struct inode *dir, aufs_bindex_t bdst)
31216+{
31217+ int err;
31218+ struct path h_path;
31219+ struct au_branch *br;
31220+
31221+ br = au_sbr(dentry->d_sb, bdst);
31222+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
31223+ err = PTR_ERR(h_path.dentry);
31224+ if (IS_ERR(h_path.dentry))
31225+ goto out;
31226+
31227+ err = 0;
5527c038 31228+ if (d_is_positive(h_path.dentry)) {
86dc4139 31229+ h_path.mnt = au_br_mnt(br);
1facf9fc 31230+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
31231+ dentry);
31232+ }
31233+ dput(h_path.dentry);
31234+
4f0767ce 31235+out:
1facf9fc 31236+ return err;
31237+}
31238+
31239+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 31240+ struct au_pin *pin,
1facf9fc 31241+ struct dentry *h_parent, void *arg)
31242+{
31243+ int err, rerr;
4a4d8108 31244+ aufs_bindex_t bopq, bstart;
1facf9fc 31245+ struct path h_path;
31246+ struct dentry *parent;
31247+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 31248+ unsigned int *flags = arg;
1facf9fc 31249+
31250+ bstart = au_dbstart(dentry);
31251+ /* dentry is di-locked */
31252+ parent = dget_parent(dentry);
5527c038
JR
31253+ dir = d_inode(parent);
31254+ h_dir = d_inode(h_parent);
1facf9fc 31255+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
31256+ IMustLock(h_dir);
31257+
86dc4139 31258+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 31259+ if (unlikely(err < 0))
31260+ goto out;
31261+ h_path.dentry = au_h_dptr(dentry, bdst);
31262+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
31263+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
31264+ S_IRWXU | S_IRUGO | S_IXUGO);
31265+ if (unlikely(err))
31266+ goto out_put;
c2b27bf2 31267+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 31268+
1facf9fc 31269+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
31270+ au_fclr_cpdown(*flags, WHED);
31271+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 31272+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
31273+ au_fset_cpdown(*flags, WHED);
31274+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
31275+ au_fset_cpdown(*flags, PARENT_OPQ);
5527c038 31276+ h_inode = d_inode(h_path.dentry);
1facf9fc 31277+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2
AM
31278+ if (au_ftest_cpdown(*flags, WHED)) {
31279+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 31280+ if (unlikely(err)) {
31281+ mutex_unlock(&h_inode->i_mutex);
31282+ goto out_dir;
31283+ }
31284+ }
31285+
31286+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
31287+ mutex_unlock(&h_inode->i_mutex);
31288+ if (unlikely(err))
31289+ goto out_opq;
31290+
c2b27bf2 31291+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 31292+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
31293+ if (unlikely(err))
31294+ goto out_opq;
31295+ }
31296+
5527c038 31297+ inode = d_inode(dentry);
1facf9fc 31298+ if (au_ibend(inode) < bdst)
31299+ au_set_ibend(inode, bdst);
31300+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
31301+ au_hi_flags(inode, /*isdir*/1));
076b876e 31302+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
1facf9fc 31303+ goto out; /* success */
31304+
31305+ /* revert */
4f0767ce 31306+out_opq:
c2b27bf2 31307+ if (au_ftest_cpdown(*flags, DIROPQ)) {
1facf9fc 31308+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
31309+ rerr = au_diropq_remove(dentry, bdst);
31310+ mutex_unlock(&h_inode->i_mutex);
31311+ if (unlikely(rerr)) {
523b37e3
AM
31312+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
31313+ dentry, bdst, rerr);
1facf9fc 31314+ err = -EIO;
31315+ goto out;
31316+ }
31317+ }
4f0767ce 31318+out_dir:
c2b27bf2 31319+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 31320+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
31321+ if (unlikely(rerr)) {
523b37e3
AM
31322+ AuIOErr("failed removing %pd b%d (%d)\n",
31323+ dentry, bdst, rerr);
1facf9fc 31324+ err = -EIO;
31325+ }
31326+ }
4f0767ce 31327+out_put:
1facf9fc 31328+ au_set_h_dptr(dentry, bdst, NULL);
31329+ if (au_dbend(dentry) == bdst)
31330+ au_update_dbend(dentry);
4f0767ce 31331+out:
1facf9fc 31332+ dput(parent);
31333+ return err;
31334+}
31335+
31336+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
31337+{
31338+ int err;
c2b27bf2 31339+ unsigned int flags;
1facf9fc 31340+
c2b27bf2
AM
31341+ flags = 0;
31342+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 31343+
31344+ return err;
31345+}
31346+
31347+/* ---------------------------------------------------------------------- */
31348+
31349+/* policies for create */
31350+
c2b27bf2 31351+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
31352+{
31353+ int err, i, j, ndentry;
31354+ aufs_bindex_t bopq;
31355+ struct au_dcsub_pages dpages;
31356+ struct au_dpage *dpage;
31357+ struct dentry **dentries, *parent, *d;
31358+
31359+ err = au_dpages_init(&dpages, GFP_NOFS);
31360+ if (unlikely(err))
31361+ goto out;
31362+ parent = dget_parent(dentry);
027c5e7a 31363+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
31364+ if (unlikely(err))
31365+ goto out_free;
31366+
31367+ err = bindex;
31368+ for (i = 0; i < dpages.ndpage; i++) {
31369+ dpage = dpages.dpages + i;
31370+ dentries = dpage->dentries;
31371+ ndentry = dpage->ndentry;
31372+ for (j = 0; j < ndentry; j++) {
31373+ d = dentries[j];
31374+ di_read_lock_parent2(d, !AuLock_IR);
31375+ bopq = au_dbdiropq(d);
31376+ di_read_unlock(d, !AuLock_IR);
31377+ if (bopq >= 0 && bopq < err)
31378+ err = bopq;
31379+ }
31380+ }
31381+
31382+out_free:
31383+ dput(parent);
31384+ au_dpages_free(&dpages);
31385+out:
31386+ return err;
31387+}
31388+
1facf9fc 31389+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
31390+{
31391+ for (; bindex >= 0; bindex--)
31392+ if (!au_br_rdonly(au_sbr(sb, bindex)))
31393+ return bindex;
31394+ return -EROFS;
31395+}
31396+
31397+/* top down parent */
392086de
AM
31398+static int au_wbr_create_tdp(struct dentry *dentry,
31399+ unsigned int flags __maybe_unused)
1facf9fc 31400+{
31401+ int err;
31402+ aufs_bindex_t bstart, bindex;
31403+ struct super_block *sb;
31404+ struct dentry *parent, *h_parent;
31405+
31406+ sb = dentry->d_sb;
31407+ bstart = au_dbstart(dentry);
31408+ err = bstart;
31409+ if (!au_br_rdonly(au_sbr(sb, bstart)))
31410+ goto out;
31411+
31412+ err = -EROFS;
31413+ parent = dget_parent(dentry);
31414+ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
31415+ h_parent = au_h_dptr(parent, bindex);
5527c038 31416+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 31417+ continue;
31418+
31419+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
31420+ err = bindex;
31421+ break;
31422+ }
31423+ }
31424+ dput(parent);
31425+
31426+ /* bottom up here */
4a4d8108 31427+ if (unlikely(err < 0)) {
1facf9fc 31428+ err = au_wbr_bu(sb, bstart - 1);
4a4d8108
AM
31429+ if (err >= 0)
31430+ err = au_wbr_nonopq(dentry, err);
31431+ }
1facf9fc 31432+
4f0767ce 31433+out:
1facf9fc 31434+ AuDbg("b%d\n", err);
31435+ return err;
31436+}
31437+
31438+/* ---------------------------------------------------------------------- */
31439+
31440+/* an exception for the policy other than tdp */
31441+static int au_wbr_create_exp(struct dentry *dentry)
31442+{
31443+ int err;
31444+ aufs_bindex_t bwh, bdiropq;
31445+ struct dentry *parent;
31446+
31447+ err = -1;
31448+ bwh = au_dbwh(dentry);
31449+ parent = dget_parent(dentry);
31450+ bdiropq = au_dbdiropq(parent);
31451+ if (bwh >= 0) {
31452+ if (bdiropq >= 0)
31453+ err = min(bdiropq, bwh);
31454+ else
31455+ err = bwh;
31456+ AuDbg("%d\n", err);
31457+ } else if (bdiropq >= 0) {
31458+ err = bdiropq;
31459+ AuDbg("%d\n", err);
31460+ }
31461+ dput(parent);
31462+
4a4d8108
AM
31463+ if (err >= 0)
31464+ err = au_wbr_nonopq(dentry, err);
31465+
1facf9fc 31466+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
31467+ err = -1;
31468+
31469+ AuDbg("%d\n", err);
31470+ return err;
31471+}
31472+
31473+/* ---------------------------------------------------------------------- */
31474+
31475+/* round robin */
31476+static int au_wbr_create_init_rr(struct super_block *sb)
31477+{
31478+ int err;
31479+
31480+ err = au_wbr_bu(sb, au_sbend(sb));
31481+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 31482+ /* smp_mb(); */
1facf9fc 31483+
31484+ AuDbg("b%d\n", err);
31485+ return err;
31486+}
31487+
392086de 31488+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 31489+{
31490+ int err, nbr;
31491+ unsigned int u;
31492+ aufs_bindex_t bindex, bend;
31493+ struct super_block *sb;
31494+ atomic_t *next;
31495+
31496+ err = au_wbr_create_exp(dentry);
31497+ if (err >= 0)
31498+ goto out;
31499+
31500+ sb = dentry->d_sb;
31501+ next = &au_sbi(sb)->si_wbr_rr_next;
31502+ bend = au_sbend(sb);
31503+ nbr = bend + 1;
31504+ for (bindex = 0; bindex <= bend; bindex++) {
392086de 31505+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 31506+ err = atomic_dec_return(next) + 1;
31507+ /* modulo for 0 is meaningless */
31508+ if (unlikely(!err))
31509+ err = atomic_dec_return(next) + 1;
31510+ } else
31511+ err = atomic_read(next);
31512+ AuDbg("%d\n", err);
31513+ u = err;
31514+ err = u % nbr;
31515+ AuDbg("%d\n", err);
31516+ if (!au_br_rdonly(au_sbr(sb, err)))
31517+ break;
31518+ err = -EROFS;
31519+ }
31520+
4a4d8108
AM
31521+ if (err >= 0)
31522+ err = au_wbr_nonopq(dentry, err);
31523+
4f0767ce 31524+out:
1facf9fc 31525+ AuDbg("%d\n", err);
31526+ return err;
31527+}
31528+
31529+/* ---------------------------------------------------------------------- */
31530+
31531+/* most free space */
392086de 31532+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 31533+{
31534+ struct super_block *sb;
31535+ struct au_branch *br;
31536+ struct au_wbr_mfs *mfs;
392086de 31537+ struct dentry *h_parent;
1facf9fc 31538+ aufs_bindex_t bindex, bend;
31539+ int err;
31540+ unsigned long long b, bavail;
7f207e10 31541+ struct path h_path;
1facf9fc 31542+ /* reduce the stack usage */
31543+ struct kstatfs *st;
31544+
31545+ st = kmalloc(sizeof(*st), GFP_NOFS);
31546+ if (unlikely(!st)) {
31547+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
31548+ return;
31549+ }
31550+
31551+ bavail = 0;
31552+ sb = dentry->d_sb;
31553+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 31554+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 31555+ mfs->mfs_bindex = -EROFS;
31556+ mfs->mfsrr_bytes = 0;
392086de
AM
31557+ if (!parent) {
31558+ bindex = 0;
31559+ bend = au_sbend(sb);
31560+ } else {
31561+ bindex = au_dbstart(parent);
31562+ bend = au_dbtaildir(parent);
31563+ }
31564+
31565+ for (; bindex <= bend; bindex++) {
31566+ if (parent) {
31567+ h_parent = au_h_dptr(parent, bindex);
5527c038 31568+ if (!h_parent || d_is_negative(h_parent))
392086de
AM
31569+ continue;
31570+ }
1facf9fc 31571+ br = au_sbr(sb, bindex);
31572+ if (au_br_rdonly(br))
31573+ continue;
31574+
31575+ /* sb->s_root for NFS is unreliable */
86dc4139 31576+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
31577+ h_path.dentry = h_path.mnt->mnt_root;
31578+ err = vfs_statfs(&h_path, st);
1facf9fc 31579+ if (unlikely(err)) {
31580+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
31581+ continue;
31582+ }
31583+
31584+ /* when the available size is equal, select the lower one */
31585+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
31586+ || sizeof(b) < sizeof(st->f_bsize));
31587+ b = st->f_bavail * st->f_bsize;
31588+ br->br_wbr->wbr_bytes = b;
31589+ if (b >= bavail) {
31590+ bavail = b;
31591+ mfs->mfs_bindex = bindex;
31592+ mfs->mfs_jiffy = jiffies;
31593+ }
31594+ }
31595+
31596+ mfs->mfsrr_bytes = bavail;
31597+ AuDbg("b%d\n", mfs->mfs_bindex);
31598+ kfree(st);
31599+}
31600+
392086de 31601+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 31602+{
31603+ int err;
392086de 31604+ struct dentry *parent;
1facf9fc 31605+ struct super_block *sb;
31606+ struct au_wbr_mfs *mfs;
31607+
31608+ err = au_wbr_create_exp(dentry);
31609+ if (err >= 0)
31610+ goto out;
31611+
31612+ sb = dentry->d_sb;
392086de
AM
31613+ parent = NULL;
31614+ if (au_ftest_wbr(flags, PARENT))
31615+ parent = dget_parent(dentry);
1facf9fc 31616+ mfs = &au_sbi(sb)->si_wbr_mfs;
31617+ mutex_lock(&mfs->mfs_lock);
31618+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
31619+ || mfs->mfs_bindex < 0
31620+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 31621+ au_mfs(dentry, parent);
1facf9fc 31622+ mutex_unlock(&mfs->mfs_lock);
31623+ err = mfs->mfs_bindex;
392086de 31624+ dput(parent);
1facf9fc 31625+
4a4d8108
AM
31626+ if (err >= 0)
31627+ err = au_wbr_nonopq(dentry, err);
31628+
4f0767ce 31629+out:
1facf9fc 31630+ AuDbg("b%d\n", err);
31631+ return err;
31632+}
31633+
31634+static int au_wbr_create_init_mfs(struct super_block *sb)
31635+{
31636+ struct au_wbr_mfs *mfs;
31637+
31638+ mfs = &au_sbi(sb)->si_wbr_mfs;
31639+ mutex_init(&mfs->mfs_lock);
31640+ mfs->mfs_jiffy = 0;
31641+ mfs->mfs_bindex = -EROFS;
31642+
31643+ return 0;
31644+}
31645+
31646+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
31647+{
31648+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
31649+ return 0;
31650+}
31651+
31652+/* ---------------------------------------------------------------------- */
31653+
31654+/* most free space and then round robin */
392086de 31655+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 31656+{
31657+ int err;
31658+ struct au_wbr_mfs *mfs;
31659+
392086de 31660+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 31661+ if (err >= 0) {
31662+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 31663+ mutex_lock(&mfs->mfs_lock);
1facf9fc 31664+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 31665+ err = au_wbr_create_rr(dentry, flags);
dece6358 31666+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 31667+ }
31668+
31669+ AuDbg("b%d\n", err);
31670+ return err;
31671+}
31672+
31673+static int au_wbr_create_init_mfsrr(struct super_block *sb)
31674+{
31675+ int err;
31676+
31677+ au_wbr_create_init_mfs(sb); /* ignore */
31678+ err = au_wbr_create_init_rr(sb);
31679+
31680+ return err;
31681+}
31682+
31683+/* ---------------------------------------------------------------------- */
31684+
31685+/* top down parent and most free space */
392086de 31686+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 31687+{
31688+ int err, e2;
31689+ unsigned long long b;
31690+ aufs_bindex_t bindex, bstart, bend;
31691+ struct super_block *sb;
31692+ struct dentry *parent, *h_parent;
31693+ struct au_branch *br;
31694+
392086de 31695+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 31696+ if (unlikely(err < 0))
31697+ goto out;
31698+ parent = dget_parent(dentry);
31699+ bstart = au_dbstart(parent);
31700+ bend = au_dbtaildir(parent);
31701+ if (bstart == bend)
31702+ goto out_parent; /* success */
31703+
392086de 31704+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 31705+ if (e2 < 0)
31706+ goto out_parent; /* success */
31707+
31708+ /* when the available size is equal, select upper one */
31709+ sb = dentry->d_sb;
31710+ br = au_sbr(sb, err);
31711+ b = br->br_wbr->wbr_bytes;
31712+ AuDbg("b%d, %llu\n", err, b);
31713+
31714+ for (bindex = bstart; bindex <= bend; bindex++) {
31715+ h_parent = au_h_dptr(parent, bindex);
5527c038 31716+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 31717+ continue;
31718+
31719+ br = au_sbr(sb, bindex);
31720+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
31721+ b = br->br_wbr->wbr_bytes;
31722+ err = bindex;
31723+ AuDbg("b%d, %llu\n", err, b);
31724+ }
31725+ }
31726+
4a4d8108
AM
31727+ if (err >= 0)
31728+ err = au_wbr_nonopq(dentry, err);
31729+
4f0767ce 31730+out_parent:
1facf9fc 31731+ dput(parent);
4f0767ce 31732+out:
1facf9fc 31733+ AuDbg("b%d\n", err);
31734+ return err;
31735+}
31736+
31737+/* ---------------------------------------------------------------------- */
31738+
392086de
AM
31739+/*
31740+ * - top down parent
31741+ * - most free space with parent
31742+ * - most free space round-robin regardless parent
31743+ */
31744+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
31745+{
31746+ int err;
31747+ unsigned long long watermark;
31748+ struct super_block *sb;
31749+ struct au_branch *br;
31750+ struct au_wbr_mfs *mfs;
31751+
31752+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
31753+ if (unlikely(err < 0))
31754+ goto out;
31755+
31756+ sb = dentry->d_sb;
31757+ br = au_sbr(sb, err);
31758+ mfs = &au_sbi(sb)->si_wbr_mfs;
31759+ mutex_lock(&mfs->mfs_lock);
31760+ watermark = mfs->mfsrr_watermark;
31761+ mutex_unlock(&mfs->mfs_lock);
31762+ if (br->br_wbr->wbr_bytes < watermark)
31763+ /* regardless the parent dir */
31764+ err = au_wbr_create_mfsrr(dentry, flags);
31765+
31766+out:
31767+ AuDbg("b%d\n", err);
31768+ return err;
31769+}
31770+
31771+/* ---------------------------------------------------------------------- */
31772+
1facf9fc 31773+/* policies for copyup */
31774+
31775+/* top down parent */
31776+static int au_wbr_copyup_tdp(struct dentry *dentry)
31777+{
392086de 31778+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 31779+}
31780+
31781+/* bottom up parent */
31782+static int au_wbr_copyup_bup(struct dentry *dentry)
31783+{
31784+ int err;
31785+ aufs_bindex_t bindex, bstart;
31786+ struct dentry *parent, *h_parent;
31787+ struct super_block *sb;
31788+
31789+ err = -EROFS;
31790+ sb = dentry->d_sb;
31791+ parent = dget_parent(dentry);
31792+ bstart = au_dbstart(parent);
31793+ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
31794+ h_parent = au_h_dptr(parent, bindex);
5527c038 31795+ if (!h_parent || d_is_negative(h_parent))
1facf9fc 31796+ continue;
31797+
31798+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
31799+ err = bindex;
31800+ break;
31801+ }
31802+ }
31803+ dput(parent);
31804+
31805+ /* bottom up here */
31806+ if (unlikely(err < 0))
31807+ err = au_wbr_bu(sb, bstart - 1);
31808+
31809+ AuDbg("b%d\n", err);
31810+ return err;
31811+}
31812+
31813+/* bottom up */
076b876e 31814+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart)
1facf9fc 31815+{
31816+ int err;
31817+
4a4d8108
AM
31818+ err = au_wbr_bu(dentry->d_sb, bstart);
31819+ AuDbg("b%d\n", err);
31820+ if (err > bstart)
31821+ err = au_wbr_nonopq(dentry, err);
1facf9fc 31822+
31823+ AuDbg("b%d\n", err);
31824+ return err;
31825+}
31826+
076b876e
AM
31827+static int au_wbr_copyup_bu(struct dentry *dentry)
31828+{
31829+ int err;
31830+ aufs_bindex_t bstart;
31831+
31832+ bstart = au_dbstart(dentry);
31833+ err = au_wbr_do_copyup_bu(dentry, bstart);
31834+ return err;
31835+}
31836+
1facf9fc 31837+/* ---------------------------------------------------------------------- */
31838+
31839+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
31840+ [AuWbrCopyup_TDP] = {
31841+ .copyup = au_wbr_copyup_tdp
31842+ },
31843+ [AuWbrCopyup_BUP] = {
31844+ .copyup = au_wbr_copyup_bup
31845+ },
31846+ [AuWbrCopyup_BU] = {
31847+ .copyup = au_wbr_copyup_bu
31848+ }
31849+};
31850+
31851+struct au_wbr_create_operations au_wbr_create_ops[] = {
31852+ [AuWbrCreate_TDP] = {
31853+ .create = au_wbr_create_tdp
31854+ },
31855+ [AuWbrCreate_RR] = {
31856+ .create = au_wbr_create_rr,
31857+ .init = au_wbr_create_init_rr
31858+ },
31859+ [AuWbrCreate_MFS] = {
31860+ .create = au_wbr_create_mfs,
31861+ .init = au_wbr_create_init_mfs,
31862+ .fin = au_wbr_create_fin_mfs
31863+ },
31864+ [AuWbrCreate_MFSV] = {
31865+ .create = au_wbr_create_mfs,
31866+ .init = au_wbr_create_init_mfs,
31867+ .fin = au_wbr_create_fin_mfs
31868+ },
31869+ [AuWbrCreate_MFSRR] = {
31870+ .create = au_wbr_create_mfsrr,
31871+ .init = au_wbr_create_init_mfsrr,
31872+ .fin = au_wbr_create_fin_mfs
31873+ },
31874+ [AuWbrCreate_MFSRRV] = {
31875+ .create = au_wbr_create_mfsrr,
31876+ .init = au_wbr_create_init_mfsrr,
31877+ .fin = au_wbr_create_fin_mfs
31878+ },
31879+ [AuWbrCreate_PMFS] = {
31880+ .create = au_wbr_create_pmfs,
31881+ .init = au_wbr_create_init_mfs,
31882+ .fin = au_wbr_create_fin_mfs
31883+ },
31884+ [AuWbrCreate_PMFSV] = {
31885+ .create = au_wbr_create_pmfs,
31886+ .init = au_wbr_create_init_mfs,
31887+ .fin = au_wbr_create_fin_mfs
392086de
AM
31888+ },
31889+ [AuWbrCreate_PMFSRR] = {
31890+ .create = au_wbr_create_pmfsrr,
31891+ .init = au_wbr_create_init_mfsrr,
31892+ .fin = au_wbr_create_fin_mfs
31893+ },
31894+ [AuWbrCreate_PMFSRRV] = {
31895+ .create = au_wbr_create_pmfsrr,
31896+ .init = au_wbr_create_init_mfsrr,
31897+ .fin = au_wbr_create_fin_mfs
1facf9fc 31898+ }
31899+};
7f207e10
AM
31900diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
31901--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 31902+++ linux/fs/aufs/whout.c 2015-09-24 10:47:58.258053165 +0200
5527c038 31903@@ -0,0 +1,1063 @@
1facf9fc 31904+/*
2000de60 31905+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 31906+ *
31907+ * This program, aufs is free software; you can redistribute it and/or modify
31908+ * it under the terms of the GNU General Public License as published by
31909+ * the Free Software Foundation; either version 2 of the License, or
31910+ * (at your option) any later version.
dece6358
AM
31911+ *
31912+ * This program is distributed in the hope that it will be useful,
31913+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31914+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31915+ * GNU General Public License for more details.
31916+ *
31917+ * You should have received a copy of the GNU General Public License
523b37e3 31918+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31919+ */
31920+
31921+/*
31922+ * whiteout for logical deletion and opaque directory
31923+ */
31924+
1facf9fc 31925+#include "aufs.h"
31926+
31927+#define WH_MASK S_IRUGO
31928+
31929+/*
31930+ * If a directory contains this file, then it is opaque. We start with the
31931+ * .wh. flag so that it is blocked by lookup.
31932+ */
0c3ec466
AM
31933+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
31934+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 31935+
31936+/*
31937+ * generate whiteout name, which is NOT terminated by NULL.
31938+ * @name: original d_name.name
31939+ * @len: original d_name.len
31940+ * @wh: whiteout qstr
31941+ * returns zero when succeeds, otherwise error.
31942+ * succeeded value as wh->name should be freed by kfree().
31943+ */
31944+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
31945+{
31946+ char *p;
31947+
31948+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
31949+ return -ENAMETOOLONG;
31950+
31951+ wh->len = name->len + AUFS_WH_PFX_LEN;
31952+ p = kmalloc(wh->len, GFP_NOFS);
31953+ wh->name = p;
31954+ if (p) {
31955+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
31956+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
31957+ /* smp_mb(); */
31958+ return 0;
31959+ }
31960+ return -ENOMEM;
31961+}
31962+
31963+/* ---------------------------------------------------------------------- */
31964+
31965+/*
31966+ * test if the @wh_name exists under @h_parent.
31967+ * @try_sio specifies the necessary of super-io.
31968+ */
076b876e 31969+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
1facf9fc 31970+{
31971+ int err;
31972+ struct dentry *wh_dentry;
1facf9fc 31973+
1facf9fc 31974+ if (!try_sio)
b4510431 31975+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 31976+ else
076b876e 31977+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
1facf9fc 31978+ err = PTR_ERR(wh_dentry);
2000de60
JR
31979+ if (IS_ERR(wh_dentry)) {
31980+ if (err == -ENAMETOOLONG)
31981+ err = 0;
1facf9fc 31982+ goto out;
2000de60 31983+ }
1facf9fc 31984+
31985+ err = 0;
5527c038 31986+ if (d_is_negative(wh_dentry))
1facf9fc 31987+ goto out_wh; /* success */
31988+
31989+ err = 1;
7e9cd9fe 31990+ if (d_is_reg(wh_dentry))
1facf9fc 31991+ goto out_wh; /* success */
31992+
31993+ err = -EIO;
523b37e3 31994+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
5527c038 31995+ wh_dentry, d_inode(wh_dentry)->i_mode);
1facf9fc 31996+
4f0767ce 31997+out_wh:
1facf9fc 31998+ dput(wh_dentry);
4f0767ce 31999+out:
1facf9fc 32000+ return err;
32001+}
32002+
32003+/*
32004+ * test if the @h_dentry sets opaque or not.
32005+ */
076b876e 32006+int au_diropq_test(struct dentry *h_dentry)
1facf9fc 32007+{
32008+ int err;
32009+ struct inode *h_dir;
32010+
5527c038 32011+ h_dir = d_inode(h_dentry);
076b876e 32012+ err = au_wh_test(h_dentry, &diropq_name,
1facf9fc 32013+ au_test_h_perm_sio(h_dir, MAY_EXEC));
32014+ return err;
32015+}
32016+
32017+/*
32018+ * returns a negative dentry whose name is unique and temporary.
32019+ */
32020+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
32021+ struct qstr *prefix)
32022+{
1facf9fc 32023+ struct dentry *dentry;
32024+ int i;
027c5e7a 32025+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 32026+ *name, *p;
027c5e7a 32027+ /* strict atomic_t is unnecessary here */
1facf9fc 32028+ static unsigned short cnt;
32029+ struct qstr qs;
32030+
4a4d8108
AM
32031+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
32032+
1facf9fc 32033+ name = defname;
027c5e7a
AM
32034+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
32035+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 32036+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 32037+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 32038+ goto out;
32039+ dentry = ERR_PTR(-ENOMEM);
32040+ name = kmalloc(qs.len + 1, GFP_NOFS);
32041+ if (unlikely(!name))
32042+ goto out;
32043+ }
32044+
32045+ /* doubly whiteout-ed */
32046+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
32047+ p = name + AUFS_WH_PFX_LEN * 2;
32048+ memcpy(p, prefix->name, prefix->len);
32049+ p += prefix->len;
32050+ *p++ = '.';
4a4d8108 32051+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 32052+
32053+ qs.name = name;
32054+ for (i = 0; i < 3; i++) {
b752ccd1 32055+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
076b876e 32056+ dentry = au_sio_lkup_one(&qs, h_parent);
5527c038 32057+ if (IS_ERR(dentry) || d_is_negative(dentry))
1facf9fc 32058+ goto out_name;
32059+ dput(dentry);
32060+ }
0c3ec466 32061+ /* pr_warn("could not get random name\n"); */
1facf9fc 32062+ dentry = ERR_PTR(-EEXIST);
32063+ AuDbg("%.*s\n", AuLNPair(&qs));
32064+ BUG();
32065+
4f0767ce 32066+out_name:
1facf9fc 32067+ if (name != defname)
32068+ kfree(name);
4f0767ce 32069+out:
4a4d8108 32070+ AuTraceErrPtr(dentry);
1facf9fc 32071+ return dentry;
1facf9fc 32072+}
32073+
32074+/*
32075+ * rename the @h_dentry on @br to the whiteouted temporary name.
32076+ */
32077+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
32078+{
32079+ int err;
32080+ struct path h_path = {
86dc4139 32081+ .mnt = au_br_mnt(br)
1facf9fc 32082+ };
523b37e3 32083+ struct inode *h_dir, *delegated;
1facf9fc 32084+ struct dentry *h_parent;
32085+
32086+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5527c038 32087+ h_dir = d_inode(h_parent);
1facf9fc 32088+ IMustLock(h_dir);
32089+
32090+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
32091+ err = PTR_ERR(h_path.dentry);
32092+ if (IS_ERR(h_path.dentry))
32093+ goto out;
32094+
32095+ /* under the same dir, no need to lock_rename() */
523b37e3
AM
32096+ delegated = NULL;
32097+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated);
1facf9fc 32098+ AuTraceErr(err);
523b37e3
AM
32099+ if (unlikely(err == -EWOULDBLOCK)) {
32100+ pr_warn("cannot retry for NFSv4 delegation"
32101+ " for an internal rename\n");
32102+ iput(delegated);
32103+ }
1facf9fc 32104+ dput(h_path.dentry);
32105+
4f0767ce 32106+out:
4a4d8108 32107+ AuTraceErr(err);
1facf9fc 32108+ return err;
32109+}
32110+
32111+/* ---------------------------------------------------------------------- */
32112+/*
32113+ * functions for removing a whiteout
32114+ */
32115+
32116+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
32117+{
523b37e3
AM
32118+ int err, force;
32119+ struct inode *delegated;
1facf9fc 32120+
32121+ /*
32122+ * forces superio when the dir has a sticky bit.
32123+ * this may be a violation of unix fs semantics.
32124+ */
32125+ force = (h_dir->i_mode & S_ISVTX)
5527c038 32126+ && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid);
523b37e3
AM
32127+ delegated = NULL;
32128+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
32129+ if (unlikely(err == -EWOULDBLOCK)) {
32130+ pr_warn("cannot retry for NFSv4 delegation"
32131+ " for an internal unlink\n");
32132+ iput(delegated);
32133+ }
32134+ return err;
1facf9fc 32135+}
32136+
32137+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
32138+ struct dentry *dentry)
32139+{
32140+ int err;
32141+
32142+ err = do_unlink_wh(h_dir, h_path);
32143+ if (!err && dentry)
32144+ au_set_dbwh(dentry, -1);
32145+
32146+ return err;
32147+}
32148+
32149+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
32150+ struct au_branch *br)
32151+{
32152+ int err;
32153+ struct path h_path = {
86dc4139 32154+ .mnt = au_br_mnt(br)
1facf9fc 32155+ };
32156+
32157+ err = 0;
b4510431 32158+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 32159+ if (IS_ERR(h_path.dentry))
32160+ err = PTR_ERR(h_path.dentry);
32161+ else {
5527c038
JR
32162+ if (d_is_reg(h_path.dentry))
32163+ err = do_unlink_wh(d_inode(h_parent), &h_path);
1facf9fc 32164+ dput(h_path.dentry);
32165+ }
32166+
32167+ return err;
32168+}
32169+
32170+/* ---------------------------------------------------------------------- */
32171+/*
32172+ * initialize/clean whiteout for a branch
32173+ */
32174+
32175+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
32176+ const int isdir)
32177+{
32178+ int err;
523b37e3 32179+ struct inode *delegated;
1facf9fc 32180+
5527c038 32181+ if (d_is_negative(whpath->dentry))
1facf9fc 32182+ return;
32183+
86dc4139
AM
32184+ if (isdir)
32185+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
32186+ else {
32187+ delegated = NULL;
32188+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
32189+ if (unlikely(err == -EWOULDBLOCK)) {
32190+ pr_warn("cannot retry for NFSv4 delegation"
32191+ " for an internal unlink\n");
32192+ iput(delegated);
32193+ }
32194+ }
1facf9fc 32195+ if (unlikely(err))
523b37e3
AM
32196+ pr_warn("failed removing %pd (%d), ignored.\n",
32197+ whpath->dentry, err);
1facf9fc 32198+}
32199+
32200+static int test_linkable(struct dentry *h_root)
32201+{
5527c038 32202+ struct inode *h_dir = d_inode(h_root);
1facf9fc 32203+
32204+ if (h_dir->i_op->link)
32205+ return 0;
32206+
523b37e3
AM
32207+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
32208+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 32209+ return -ENOSYS;
32210+}
32211+
32212+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
32213+static int au_whdir(struct inode *h_dir, struct path *path)
32214+{
32215+ int err;
32216+
32217+ err = -EEXIST;
5527c038 32218+ if (d_is_negative(path->dentry)) {
1facf9fc 32219+ int mode = S_IRWXU;
32220+
32221+ if (au_test_nfs(path->dentry->d_sb))
32222+ mode |= S_IXUGO;
86dc4139 32223+ err = vfsub_mkdir(h_dir, path, mode);
2000de60 32224+ } else if (d_is_dir(path->dentry))
1facf9fc 32225+ err = 0;
32226+ else
523b37e3 32227+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 32228+
32229+ return err;
32230+}
32231+
32232+struct au_wh_base {
32233+ const struct qstr *name;
32234+ struct dentry *dentry;
32235+};
32236+
32237+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
32238+ struct path *h_path)
32239+{
32240+ h_path->dentry = base[AuBrWh_BASE].dentry;
32241+ au_wh_clean(h_dir, h_path, /*isdir*/0);
32242+ h_path->dentry = base[AuBrWh_PLINK].dentry;
32243+ au_wh_clean(h_dir, h_path, /*isdir*/1);
32244+ h_path->dentry = base[AuBrWh_ORPH].dentry;
32245+ au_wh_clean(h_dir, h_path, /*isdir*/1);
32246+}
32247+
32248+/*
32249+ * returns tri-state,
c1595e42 32250+ * minus: error, caller should print the message
1facf9fc 32251+ * zero: succuess
c1595e42 32252+ * plus: error, caller should NOT print the message
1facf9fc 32253+ */
32254+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
32255+ int do_plink, struct au_wh_base base[],
32256+ struct path *h_path)
32257+{
32258+ int err;
32259+ struct inode *h_dir;
32260+
5527c038 32261+ h_dir = d_inode(h_root);
1facf9fc 32262+ h_path->dentry = base[AuBrWh_BASE].dentry;
32263+ au_wh_clean(h_dir, h_path, /*isdir*/0);
32264+ h_path->dentry = base[AuBrWh_PLINK].dentry;
32265+ if (do_plink) {
32266+ err = test_linkable(h_root);
32267+ if (unlikely(err)) {
32268+ err = 1;
32269+ goto out;
32270+ }
32271+
32272+ err = au_whdir(h_dir, h_path);
32273+ if (unlikely(err))
32274+ goto out;
32275+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
32276+ } else
32277+ au_wh_clean(h_dir, h_path, /*isdir*/1);
32278+ h_path->dentry = base[AuBrWh_ORPH].dentry;
32279+ err = au_whdir(h_dir, h_path);
32280+ if (unlikely(err))
32281+ goto out;
32282+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
32283+
4f0767ce 32284+out:
1facf9fc 32285+ return err;
32286+}
32287+
32288+/*
32289+ * for the moment, aufs supports the branch filesystem which does not support
32290+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
32291+ * copyup failed. finally, such filesystem will not be used as the writable
32292+ * branch.
32293+ *
32294+ * returns tri-state, see above.
32295+ */
32296+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
32297+ int do_plink, struct au_wh_base base[],
32298+ struct path *h_path)
32299+{
32300+ int err;
32301+ struct inode *h_dir;
32302+
1308ab2a 32303+ WbrWhMustWriteLock(wbr);
32304+
1facf9fc 32305+ err = test_linkable(h_root);
32306+ if (unlikely(err)) {
32307+ err = 1;
32308+ goto out;
32309+ }
32310+
32311+ /*
32312+ * todo: should this create be done in /sbin/mount.aufs helper?
32313+ */
32314+ err = -EEXIST;
5527c038
JR
32315+ h_dir = d_inode(h_root);
32316+ if (d_is_negative(base[AuBrWh_BASE].dentry)) {
86dc4139
AM
32317+ h_path->dentry = base[AuBrWh_BASE].dentry;
32318+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
7e9cd9fe 32319+ } else if (d_is_reg(base[AuBrWh_BASE].dentry))
1facf9fc 32320+ err = 0;
32321+ else
523b37e3 32322+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 32323+ if (unlikely(err))
32324+ goto out;
32325+
32326+ h_path->dentry = base[AuBrWh_PLINK].dentry;
32327+ if (do_plink) {
32328+ err = au_whdir(h_dir, h_path);
32329+ if (unlikely(err))
32330+ goto out;
32331+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
32332+ } else
32333+ au_wh_clean(h_dir, h_path, /*isdir*/1);
32334+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
32335+
32336+ h_path->dentry = base[AuBrWh_ORPH].dentry;
32337+ err = au_whdir(h_dir, h_path);
32338+ if (unlikely(err))
32339+ goto out;
32340+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
32341+
4f0767ce 32342+out:
1facf9fc 32343+ return err;
32344+}
32345+
32346+/*
32347+ * initialize the whiteout base file/dir for @br.
32348+ */
86dc4139 32349+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 32350+{
32351+ int err, i;
32352+ const unsigned char do_plink
32353+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 32354+ struct inode *h_dir;
86dc4139
AM
32355+ struct path path = br->br_path;
32356+ struct dentry *h_root = path.dentry;
1facf9fc 32357+ struct au_wbr *wbr = br->br_wbr;
32358+ static const struct qstr base_name[] = {
0c3ec466
AM
32359+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
32360+ sizeof(AUFS_BASE_NAME) - 1),
32361+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
32362+ sizeof(AUFS_PLINKDIR_NAME) - 1),
32363+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
32364+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 32365+ };
32366+ struct au_wh_base base[] = {
32367+ [AuBrWh_BASE] = {
32368+ .name = base_name + AuBrWh_BASE,
32369+ .dentry = NULL
32370+ },
32371+ [AuBrWh_PLINK] = {
32372+ .name = base_name + AuBrWh_PLINK,
32373+ .dentry = NULL
32374+ },
32375+ [AuBrWh_ORPH] = {
32376+ .name = base_name + AuBrWh_ORPH,
32377+ .dentry = NULL
32378+ }
32379+ };
32380+
1308ab2a 32381+ if (wbr)
32382+ WbrWhMustWriteLock(wbr);
1facf9fc 32383+
1facf9fc 32384+ for (i = 0; i < AuBrWh_Last; i++) {
32385+ /* doubly whiteouted */
32386+ struct dentry *d;
32387+
32388+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
32389+ err = PTR_ERR(d);
32390+ if (IS_ERR(d))
32391+ goto out;
32392+
32393+ base[i].dentry = d;
32394+ AuDebugOn(wbr
32395+ && wbr->wbr_wh[i]
32396+ && wbr->wbr_wh[i] != base[i].dentry);
32397+ }
32398+
32399+ if (wbr)
32400+ for (i = 0; i < AuBrWh_Last; i++) {
32401+ dput(wbr->wbr_wh[i]);
32402+ wbr->wbr_wh[i] = NULL;
32403+ }
32404+
32405+ err = 0;
1e00d052 32406+ if (!au_br_writable(br->br_perm)) {
5527c038 32407+ h_dir = d_inode(h_root);
1facf9fc 32408+ au_wh_init_ro(h_dir, base, &path);
1e00d052 32409+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 32410+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
32411+ if (err > 0)
32412+ goto out;
32413+ else if (err)
32414+ goto out_err;
1e00d052 32415+ } else {
1facf9fc 32416+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
32417+ if (err > 0)
32418+ goto out;
32419+ else if (err)
32420+ goto out_err;
1facf9fc 32421+ }
32422+ goto out; /* success */
32423+
4f0767ce 32424+out_err:
523b37e3
AM
32425+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
32426+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 32427+out:
1facf9fc 32428+ for (i = 0; i < AuBrWh_Last; i++)
32429+ dput(base[i].dentry);
32430+ return err;
32431+}
32432+
32433+/* ---------------------------------------------------------------------- */
32434+/*
32435+ * whiteouts are all hard-linked usually.
32436+ * when its link count reaches a ceiling, we create a new whiteout base
32437+ * asynchronously.
32438+ */
32439+
32440+struct reinit_br_wh {
32441+ struct super_block *sb;
32442+ struct au_branch *br;
32443+};
32444+
32445+static void reinit_br_wh(void *arg)
32446+{
32447+ int err;
32448+ aufs_bindex_t bindex;
32449+ struct path h_path;
32450+ struct reinit_br_wh *a = arg;
32451+ struct au_wbr *wbr;
523b37e3 32452+ struct inode *dir, *delegated;
1facf9fc 32453+ struct dentry *h_root;
32454+ struct au_hinode *hdir;
32455+
32456+ err = 0;
32457+ wbr = a->br->br_wbr;
32458+ /* big aufs lock */
32459+ si_noflush_write_lock(a->sb);
32460+ if (!au_br_writable(a->br->br_perm))
32461+ goto out;
32462+ bindex = au_br_index(a->sb, a->br->br_id);
32463+ if (unlikely(bindex < 0))
32464+ goto out;
32465+
1308ab2a 32466+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
5527c038 32467+ dir = d_inode(a->sb->s_root);
1facf9fc 32468+ hdir = au_hi(dir, bindex);
32469+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 32470+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 32471+
4a4d8108 32472+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 32473+ wbr_wh_write_lock(wbr);
32474+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
32475+ h_root, a->br);
32476+ if (!err) {
86dc4139
AM
32477+ h_path.dentry = wbr->wbr_whbase;
32478+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
32479+ delegated = NULL;
32480+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
32481+ /*force*/0);
32482+ if (unlikely(err == -EWOULDBLOCK)) {
32483+ pr_warn("cannot retry for NFSv4 delegation"
32484+ " for an internal unlink\n");
32485+ iput(delegated);
32486+ }
1facf9fc 32487+ } else {
523b37e3 32488+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 32489+ err = 0;
32490+ }
32491+ dput(wbr->wbr_whbase);
32492+ wbr->wbr_whbase = NULL;
32493+ if (!err)
86dc4139 32494+ err = au_wh_init(a->br, a->sb);
1facf9fc 32495+ wbr_wh_write_unlock(wbr);
4a4d8108 32496+ au_hn_imtx_unlock(hdir);
1308ab2a 32497+ di_read_unlock(a->sb->s_root, AuLock_IR);
076b876e
AM
32498+ if (!err)
32499+ au_fhsm_wrote(a->sb, bindex, /*force*/0);
1facf9fc 32500+
4f0767ce 32501+out:
1facf9fc 32502+ if (wbr)
32503+ atomic_dec(&wbr->wbr_wh_running);
32504+ atomic_dec(&a->br->br_count);
1facf9fc 32505+ si_write_unlock(a->sb);
027c5e7a 32506+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1facf9fc 32507+ kfree(arg);
32508+ if (unlikely(err))
32509+ AuIOErr("err %d\n", err);
32510+}
32511+
32512+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
32513+{
32514+ int do_dec, wkq_err;
32515+ struct reinit_br_wh *arg;
32516+
32517+ do_dec = 1;
32518+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
32519+ goto out;
32520+
32521+ /* ignore ENOMEM */
32522+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
32523+ if (arg) {
32524+ /*
32525+ * dec(wh_running), kfree(arg) and dec(br_count)
32526+ * in reinit function
32527+ */
32528+ arg->sb = sb;
32529+ arg->br = br;
32530+ atomic_inc(&br->br_count);
53392da6 32531+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 32532+ if (unlikely(wkq_err)) {
32533+ atomic_dec(&br->br_wbr->wbr_wh_running);
32534+ atomic_dec(&br->br_count);
32535+ kfree(arg);
32536+ }
32537+ do_dec = 0;
32538+ }
32539+
4f0767ce 32540+out:
1facf9fc 32541+ if (do_dec)
32542+ atomic_dec(&br->br_wbr->wbr_wh_running);
32543+}
32544+
32545+/* ---------------------------------------------------------------------- */
32546+
32547+/*
32548+ * create the whiteout @wh.
32549+ */
32550+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
32551+ struct dentry *wh)
32552+{
32553+ int err;
32554+ struct path h_path = {
32555+ .dentry = wh
32556+ };
32557+ struct au_branch *br;
32558+ struct au_wbr *wbr;
32559+ struct dentry *h_parent;
523b37e3 32560+ struct inode *h_dir, *delegated;
1facf9fc 32561+
32562+ h_parent = wh->d_parent; /* dir inode is locked */
5527c038 32563+ h_dir = d_inode(h_parent);
1facf9fc 32564+ IMustLock(h_dir);
32565+
32566+ br = au_sbr(sb, bindex);
86dc4139 32567+ h_path.mnt = au_br_mnt(br);
1facf9fc 32568+ wbr = br->br_wbr;
32569+ wbr_wh_read_lock(wbr);
32570+ if (wbr->wbr_whbase) {
523b37e3
AM
32571+ delegated = NULL;
32572+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
32573+ if (unlikely(err == -EWOULDBLOCK)) {
32574+ pr_warn("cannot retry for NFSv4 delegation"
32575+ " for an internal link\n");
32576+ iput(delegated);
32577+ }
1facf9fc 32578+ if (!err || err != -EMLINK)
32579+ goto out;
32580+
32581+ /* link count full. re-initialize br_whbase. */
32582+ kick_reinit_br_wh(sb, br);
32583+ }
32584+
32585+ /* return this error in this context */
b4510431 32586+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
076b876e
AM
32587+ if (!err)
32588+ au_fhsm_wrote(sb, bindex, /*force*/0);
1facf9fc 32589+
4f0767ce 32590+out:
1facf9fc 32591+ wbr_wh_read_unlock(wbr);
32592+ return err;
32593+}
32594+
32595+/* ---------------------------------------------------------------------- */
32596+
32597+/*
32598+ * create or remove the diropq.
32599+ */
32600+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
32601+ unsigned int flags)
32602+{
32603+ struct dentry *opq_dentry, *h_dentry;
32604+ struct super_block *sb;
32605+ struct au_branch *br;
32606+ int err;
32607+
32608+ sb = dentry->d_sb;
32609+ br = au_sbr(sb, bindex);
32610+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 32611+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 32612+ if (IS_ERR(opq_dentry))
32613+ goto out;
32614+
32615+ if (au_ftest_diropq(flags, CREATE)) {
32616+ err = link_or_create_wh(sb, bindex, opq_dentry);
32617+ if (!err) {
32618+ au_set_dbdiropq(dentry, bindex);
32619+ goto out; /* success */
32620+ }
32621+ } else {
32622+ struct path tmp = {
32623+ .dentry = opq_dentry,
86dc4139 32624+ .mnt = au_br_mnt(br)
1facf9fc 32625+ };
5527c038 32626+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp);
1facf9fc 32627+ if (!err)
32628+ au_set_dbdiropq(dentry, -1);
32629+ }
32630+ dput(opq_dentry);
32631+ opq_dentry = ERR_PTR(err);
32632+
4f0767ce 32633+out:
1facf9fc 32634+ return opq_dentry;
32635+}
32636+
32637+struct do_diropq_args {
32638+ struct dentry **errp;
32639+ struct dentry *dentry;
32640+ aufs_bindex_t bindex;
32641+ unsigned int flags;
32642+};
32643+
32644+static void call_do_diropq(void *args)
32645+{
32646+ struct do_diropq_args *a = args;
32647+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
32648+}
32649+
32650+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
32651+ unsigned int flags)
32652+{
32653+ struct dentry *diropq, *h_dentry;
32654+
32655+ h_dentry = au_h_dptr(dentry, bindex);
5527c038 32656+ if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE))
1facf9fc 32657+ diropq = do_diropq(dentry, bindex, flags);
32658+ else {
32659+ int wkq_err;
32660+ struct do_diropq_args args = {
32661+ .errp = &diropq,
32662+ .dentry = dentry,
32663+ .bindex = bindex,
32664+ .flags = flags
32665+ };
32666+
32667+ wkq_err = au_wkq_wait(call_do_diropq, &args);
32668+ if (unlikely(wkq_err))
32669+ diropq = ERR_PTR(wkq_err);
32670+ }
32671+
32672+ return diropq;
32673+}
32674+
32675+/* ---------------------------------------------------------------------- */
32676+
32677+/*
32678+ * lookup whiteout dentry.
32679+ * @h_parent: lower parent dentry which must exist and be locked
32680+ * @base_name: name of dentry which will be whiteouted
32681+ * returns dentry for whiteout.
32682+ */
32683+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
32684+ struct au_branch *br)
32685+{
32686+ int err;
32687+ struct qstr wh_name;
32688+ struct dentry *wh_dentry;
32689+
32690+ err = au_wh_name_alloc(&wh_name, base_name);
32691+ wh_dentry = ERR_PTR(err);
32692+ if (!err) {
b4510431 32693+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1facf9fc 32694+ kfree(wh_name.name);
32695+ }
32696+ return wh_dentry;
32697+}
32698+
32699+/*
32700+ * link/create a whiteout for @dentry on @bindex.
32701+ */
32702+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
32703+ struct dentry *h_parent)
32704+{
32705+ struct dentry *wh_dentry;
32706+ struct super_block *sb;
32707+ int err;
32708+
32709+ sb = dentry->d_sb;
32710+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
5527c038 32711+ if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) {
1facf9fc 32712+ err = link_or_create_wh(sb, bindex, wh_dentry);
076b876e 32713+ if (!err) {
1facf9fc 32714+ au_set_dbwh(dentry, bindex);
076b876e
AM
32715+ au_fhsm_wrote(sb, bindex, /*force*/0);
32716+ } else {
1facf9fc 32717+ dput(wh_dentry);
32718+ wh_dentry = ERR_PTR(err);
32719+ }
32720+ }
32721+
32722+ return wh_dentry;
32723+}
32724+
32725+/* ---------------------------------------------------------------------- */
32726+
32727+/* Delete all whiteouts in this directory on branch bindex. */
32728+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
32729+ aufs_bindex_t bindex, struct au_branch *br)
32730+{
32731+ int err;
32732+ unsigned long ul, n;
32733+ struct qstr wh_name;
32734+ char *p;
32735+ struct hlist_head *head;
c06a8ce3 32736+ struct au_vdir_wh *pos;
1facf9fc 32737+ struct au_vdir_destr *str;
32738+
32739+ err = -ENOMEM;
537831f9 32740+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 32741+ wh_name.name = p;
32742+ if (unlikely(!wh_name.name))
32743+ goto out;
32744+
32745+ err = 0;
32746+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
32747+ p += AUFS_WH_PFX_LEN;
32748+ n = whlist->nh_num;
32749+ head = whlist->nh_head;
32750+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
32751+ hlist_for_each_entry(pos, head, wh_hash) {
32752+ if (pos->wh_bindex != bindex)
1facf9fc 32753+ continue;
32754+
c06a8ce3 32755+ str = &pos->wh_str;
1facf9fc 32756+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
32757+ memcpy(p, str->name, str->len);
32758+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
32759+ err = unlink_wh_name(h_dentry, &wh_name, br);
32760+ if (!err)
32761+ continue;
32762+ break;
32763+ }
32764+ AuIOErr("whiteout name too long %.*s\n",
32765+ str->len, str->name);
32766+ err = -EIO;
32767+ break;
32768+ }
32769+ }
537831f9 32770+ free_page((unsigned long)wh_name.name);
1facf9fc 32771+
4f0767ce 32772+out:
1facf9fc 32773+ return err;
32774+}
32775+
32776+struct del_wh_children_args {
32777+ int *errp;
32778+ struct dentry *h_dentry;
1308ab2a 32779+ struct au_nhash *whlist;
1facf9fc 32780+ aufs_bindex_t bindex;
32781+ struct au_branch *br;
32782+};
32783+
32784+static void call_del_wh_children(void *args)
32785+{
32786+ struct del_wh_children_args *a = args;
1308ab2a 32787+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 32788+}
32789+
32790+/* ---------------------------------------------------------------------- */
32791+
32792+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
32793+{
32794+ struct au_whtmp_rmdir *whtmp;
dece6358 32795+ int err;
1308ab2a 32796+ unsigned int rdhash;
dece6358
AM
32797+
32798+ SiMustAnyLock(sb);
1facf9fc 32799+
32800+ whtmp = kmalloc(sizeof(*whtmp), gfp);
dece6358
AM
32801+ if (unlikely(!whtmp)) {
32802+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 32803+ goto out;
dece6358 32804+ }
1facf9fc 32805+
32806+ whtmp->dir = NULL;
027c5e7a 32807+ whtmp->br = NULL;
1facf9fc 32808+ whtmp->wh_dentry = NULL;
1308ab2a 32809+ /* no estimation for dir size */
32810+ rdhash = au_sbi(sb)->si_rdhash;
32811+ if (!rdhash)
32812+ rdhash = AUFS_RDHASH_DEF;
32813+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
32814+ if (unlikely(err)) {
32815+ kfree(whtmp);
32816+ whtmp = ERR_PTR(err);
32817+ }
dece6358 32818+
4f0767ce 32819+out:
dece6358 32820+ return whtmp;
1facf9fc 32821+}
32822+
32823+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
32824+{
027c5e7a
AM
32825+ if (whtmp->br)
32826+ atomic_dec(&whtmp->br->br_count);
1facf9fc 32827+ dput(whtmp->wh_dentry);
32828+ iput(whtmp->dir);
dece6358 32829+ au_nhash_wh_free(&whtmp->whlist);
1facf9fc 32830+ kfree(whtmp);
32831+}
32832+
32833+/*
32834+ * rmdir the whiteouted temporary named dir @h_dentry.
32835+ * @whlist: whiteouted children.
32836+ */
32837+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
32838+ struct dentry *wh_dentry, struct au_nhash *whlist)
32839+{
32840+ int err;
2000de60 32841+ unsigned int h_nlink;
1facf9fc 32842+ struct path h_tmp;
32843+ struct inode *wh_inode, *h_dir;
32844+ struct au_branch *br;
32845+
5527c038 32846+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */
1facf9fc 32847+ IMustLock(h_dir);
32848+
32849+ br = au_sbr(dir->i_sb, bindex);
5527c038 32850+ wh_inode = d_inode(wh_dentry);
1facf9fc 32851+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
32852+
32853+ /*
32854+ * someone else might change some whiteouts while we were sleeping.
32855+ * it means this whlist may have an obsoleted entry.
32856+ */
32857+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
32858+ err = del_wh_children(wh_dentry, whlist, bindex, br);
32859+ else {
32860+ int wkq_err;
32861+ struct del_wh_children_args args = {
32862+ .errp = &err,
32863+ .h_dentry = wh_dentry,
1308ab2a 32864+ .whlist = whlist,
1facf9fc 32865+ .bindex = bindex,
32866+ .br = br
32867+ };
32868+
32869+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
32870+ if (unlikely(wkq_err))
32871+ err = wkq_err;
32872+ }
32873+ mutex_unlock(&wh_inode->i_mutex);
32874+
32875+ if (!err) {
32876+ h_tmp.dentry = wh_dentry;
86dc4139 32877+ h_tmp.mnt = au_br_mnt(br);
2000de60 32878+ h_nlink = h_dir->i_nlink;
1facf9fc 32879+ err = vfsub_rmdir(h_dir, &h_tmp);
2000de60
JR
32880+ /* some fs doesn't change the parent nlink in some cases */
32881+ h_nlink -= h_dir->i_nlink;
1facf9fc 32882+ }
32883+
32884+ if (!err) {
32885+ if (au_ibstart(dir) == bindex) {
7f207e10 32886+ /* todo: dir->i_mutex is necessary */
1facf9fc 32887+ au_cpup_attr_timesizes(dir);
2000de60
JR
32888+ if (h_nlink)
32889+ vfsub_drop_nlink(dir);
1facf9fc 32890+ }
32891+ return 0; /* success */
32892+ }
32893+
523b37e3 32894+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 32895+ return err;
32896+}
32897+
32898+static void call_rmdir_whtmp(void *args)
32899+{
32900+ int err;
e49829fe 32901+ aufs_bindex_t bindex;
1facf9fc 32902+ struct au_whtmp_rmdir *a = args;
32903+ struct super_block *sb;
32904+ struct dentry *h_parent;
32905+ struct inode *h_dir;
1facf9fc 32906+ struct au_hinode *hdir;
32907+
32908+ /* rmdir by nfsd may cause deadlock with this i_mutex */
32909+ /* mutex_lock(&a->dir->i_mutex); */
e49829fe 32910+ err = -EROFS;
1facf9fc 32911+ sb = a->dir->i_sb;
e49829fe
JR
32912+ si_read_lock(sb, !AuLock_FLUSH);
32913+ if (!au_br_writable(a->br->br_perm))
32914+ goto out;
32915+ bindex = au_br_index(sb, a->br->br_id);
32916+ if (unlikely(bindex < 0))
1facf9fc 32917+ goto out;
32918+
32919+ err = -EIO;
1facf9fc 32920+ ii_write_lock_parent(a->dir);
32921+ h_parent = dget_parent(a->wh_dentry);
5527c038 32922+ h_dir = d_inode(h_parent);
e49829fe 32923+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
32924+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
32925+ if (unlikely(err))
32926+ goto out_mnt;
4a4d8108 32927+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
32928+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
32929+ a->br);
86dc4139
AM
32930+ if (!err)
32931+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
4a4d8108 32932+ au_hn_imtx_unlock(hdir);
86dc4139
AM
32933+ vfsub_mnt_drop_write(au_br_mnt(a->br));
32934+
32935+out_mnt:
1facf9fc 32936+ dput(h_parent);
32937+ ii_write_unlock(a->dir);
4f0767ce 32938+out:
1facf9fc 32939+ /* mutex_unlock(&a->dir->i_mutex); */
1facf9fc 32940+ au_whtmp_rmdir_free(a);
027c5e7a
AM
32941+ si_read_unlock(sb);
32942+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 32943+ if (unlikely(err))
32944+ AuIOErr("err %d\n", err);
32945+}
32946+
32947+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
32948+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
32949+{
32950+ int wkq_err;
e49829fe 32951+ struct super_block *sb;
1facf9fc 32952+
32953+ IMustLock(dir);
32954+
32955+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 32956+ sb = dir->i_sb;
1facf9fc 32957+ args->dir = au_igrab(dir);
e49829fe
JR
32958+ args->br = au_sbr(sb, bindex);
32959+ atomic_inc(&args->br->br_count);
1facf9fc 32960+ args->wh_dentry = dget(wh_dentry);
53392da6 32961+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 32962+ if (unlikely(wkq_err)) {
523b37e3 32963+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 32964+ au_whtmp_rmdir_free(args);
32965+ }
32966+}
7f207e10
AM
32967diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
32968--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 32969+++ linux/fs/aufs/whout.h 2015-09-24 10:47:58.258053165 +0200
076b876e 32970@@ -0,0 +1,85 @@
1facf9fc 32971+/*
2000de60 32972+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 32973+ *
32974+ * This program, aufs is free software; you can redistribute it and/or modify
32975+ * it under the terms of the GNU General Public License as published by
32976+ * the Free Software Foundation; either version 2 of the License, or
32977+ * (at your option) any later version.
dece6358
AM
32978+ *
32979+ * This program is distributed in the hope that it will be useful,
32980+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32981+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32982+ * GNU General Public License for more details.
32983+ *
32984+ * You should have received a copy of the GNU General Public License
523b37e3 32985+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32986+ */
32987+
32988+/*
32989+ * whiteout for logical deletion and opaque directory
32990+ */
32991+
32992+#ifndef __AUFS_WHOUT_H__
32993+#define __AUFS_WHOUT_H__
32994+
32995+#ifdef __KERNEL__
32996+
1facf9fc 32997+#include "dir.h"
32998+
32999+/* whout.c */
33000+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
076b876e
AM
33001+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
33002+int au_diropq_test(struct dentry *h_dentry);
7e9cd9fe 33003+struct au_branch;
1facf9fc 33004+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
33005+ struct qstr *prefix);
33006+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
33007+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
33008+ struct dentry *dentry);
86dc4139 33009+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 33010+
33011+/* diropq flags */
33012+#define AuDiropq_CREATE 1
33013+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
33014+#define au_fset_diropq(flags, name) \
33015+ do { (flags) |= AuDiropq_##name; } while (0)
33016+#define au_fclr_diropq(flags, name) \
33017+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 33018+
33019+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
33020+ unsigned int flags);
33021+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
33022+ struct au_branch *br);
33023+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
33024+ struct dentry *h_parent);
33025+
33026+/* real rmdir for the whiteout-ed dir */
33027+struct au_whtmp_rmdir {
33028+ struct inode *dir;
e49829fe 33029+ struct au_branch *br;
1facf9fc 33030+ struct dentry *wh_dentry;
dece6358 33031+ struct au_nhash whlist;
1facf9fc 33032+};
33033+
33034+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
33035+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
33036+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
33037+ struct dentry *wh_dentry, struct au_nhash *whlist);
33038+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
33039+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
33040+
33041+/* ---------------------------------------------------------------------- */
33042+
33043+static inline struct dentry *au_diropq_create(struct dentry *dentry,
33044+ aufs_bindex_t bindex)
33045+{
33046+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
33047+}
33048+
33049+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
33050+{
33051+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
33052+}
33053+
33054+#endif /* __KERNEL__ */
33055+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
33056diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
33057--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 33058+++ linux/fs/aufs/wkq.c 2015-09-24 10:47:58.258053165 +0200
38d290e6 33059@@ -0,0 +1,213 @@
1facf9fc 33060+/*
2000de60 33061+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 33062+ *
33063+ * This program, aufs is free software; you can redistribute it and/or modify
33064+ * it under the terms of the GNU General Public License as published by
33065+ * the Free Software Foundation; either version 2 of the License, or
33066+ * (at your option) any later version.
dece6358
AM
33067+ *
33068+ * This program is distributed in the hope that it will be useful,
33069+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33070+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33071+ * GNU General Public License for more details.
33072+ *
33073+ * You should have received a copy of the GNU General Public License
523b37e3 33074+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33075+ */
33076+
33077+/*
33078+ * workqueue for asynchronous/super-io operations
33079+ * todo: try new dredential scheme
33080+ */
33081+
dece6358 33082+#include <linux/module.h>
1facf9fc 33083+#include "aufs.h"
33084+
9dbd164d 33085+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 33086+
9dbd164d 33087+static struct workqueue_struct *au_wkq;
1facf9fc 33088+
33089+struct au_wkinfo {
33090+ struct work_struct wk;
7f207e10 33091+ struct kobject *kobj;
1facf9fc 33092+
33093+ unsigned int flags; /* see wkq.h */
33094+
33095+ au_wkq_func_t func;
33096+ void *args;
33097+
1facf9fc 33098+ struct completion *comp;
33099+};
33100+
33101+/* ---------------------------------------------------------------------- */
33102+
1facf9fc 33103+static void wkq_func(struct work_struct *wk)
33104+{
33105+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
33106+
2dfbb274 33107+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
33108+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
33109+
1facf9fc 33110+ wkinfo->func(wkinfo->args);
1facf9fc 33111+ if (au_ftest_wkq(wkinfo->flags, WAIT))
33112+ complete(wkinfo->comp);
33113+ else {
7f207e10 33114+ kobject_put(wkinfo->kobj);
9dbd164d 33115+ module_put(THIS_MODULE); /* todo: ?? */
1facf9fc 33116+ kfree(wkinfo);
33117+ }
33118+}
33119+
33120+/*
33121+ * Since struct completion is large, try allocating it dynamically.
33122+ */
c2b27bf2 33123+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 33124+#define AuWkqCompDeclare(name) struct completion *comp = NULL
33125+
33126+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
33127+{
33128+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
33129+ if (*comp) {
33130+ init_completion(*comp);
33131+ wkinfo->comp = *comp;
33132+ return 0;
33133+ }
33134+ return -ENOMEM;
33135+}
33136+
33137+static void au_wkq_comp_free(struct completion *comp)
33138+{
33139+ kfree(comp);
33140+}
33141+
33142+#else
33143+
33144+/* no braces */
33145+#define AuWkqCompDeclare(name) \
33146+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
33147+ struct completion *comp = &_ ## name
33148+
33149+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
33150+{
33151+ wkinfo->comp = *comp;
33152+ return 0;
33153+}
33154+
33155+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
33156+{
33157+ /* empty */
33158+}
33159+#endif /* 4KSTACKS */
33160+
53392da6 33161+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 33162+{
53392da6
AM
33163+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
33164+ if (au_wkq_test()) {
38d290e6
JR
33165+ AuWarn1("wkq from wkq, unless silly-rename on NFS,"
33166+ " due to a dead dir by UDBA?\n");
53392da6
AM
33167+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
33168+ }
33169+ } else
33170+ au_dbg_verify_kthread();
33171+
33172+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 33173+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 33174+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
33175+ } else {
33176+ INIT_WORK(&wkinfo->wk, wkq_func);
33177+ schedule_work(&wkinfo->wk);
33178+ }
1facf9fc 33179+}
33180+
7f207e10
AM
33181+/*
33182+ * Be careful. It is easy to make deadlock happen.
33183+ * processA: lock, wkq and wait
33184+ * processB: wkq and wait, lock in wkq
33185+ * --> deadlock
33186+ */
b752ccd1 33187+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 33188+{
33189+ int err;
33190+ AuWkqCompDeclare(comp);
33191+ struct au_wkinfo wkinfo = {
b752ccd1 33192+ .flags = flags,
1facf9fc 33193+ .func = func,
33194+ .args = args
33195+ };
33196+
33197+ err = au_wkq_comp_alloc(&wkinfo, &comp);
33198+ if (!err) {
53392da6 33199+ au_wkq_run(&wkinfo);
1facf9fc 33200+ /* no timeout, no interrupt */
33201+ wait_for_completion(wkinfo.comp);
33202+ au_wkq_comp_free(comp);
4a4d8108 33203+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 33204+ }
33205+
33206+ return err;
33207+
33208+}
33209+
027c5e7a
AM
33210+/*
33211+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
33212+ * problem in a concurrent umounting.
33213+ */
53392da6
AM
33214+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
33215+ unsigned int flags)
1facf9fc 33216+{
33217+ int err;
33218+ struct au_wkinfo *wkinfo;
33219+
33220+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
33221+
33222+ /*
33223+ * wkq_func() must free this wkinfo.
33224+ * it highly depends upon the implementation of workqueue.
33225+ */
33226+ err = 0;
33227+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
33228+ if (wkinfo) {
7f207e10 33229+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 33230+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 33231+ wkinfo->func = func;
33232+ wkinfo->args = args;
33233+ wkinfo->comp = NULL;
7f207e10 33234+ kobject_get(wkinfo->kobj);
9dbd164d 33235+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 33236+
53392da6 33237+ au_wkq_run(wkinfo);
1facf9fc 33238+ } else {
33239+ err = -ENOMEM;
e49829fe 33240+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 33241+ }
33242+
33243+ return err;
33244+}
33245+
33246+/* ---------------------------------------------------------------------- */
33247+
33248+void au_nwt_init(struct au_nowait_tasks *nwt)
33249+{
33250+ atomic_set(&nwt->nw_len, 0);
4a4d8108 33251+ /* smp_mb(); */ /* atomic_set */
1facf9fc 33252+ init_waitqueue_head(&nwt->nw_wq);
33253+}
33254+
33255+void au_wkq_fin(void)
33256+{
9dbd164d 33257+ destroy_workqueue(au_wkq);
1facf9fc 33258+}
33259+
33260+int __init au_wkq_init(void)
33261+{
9dbd164d 33262+ int err;
b752ccd1
AM
33263+
33264+ err = 0;
86dc4139 33265+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
33266+ if (IS_ERR(au_wkq))
33267+ err = PTR_ERR(au_wkq);
33268+ else if (!au_wkq)
33269+ err = -ENOMEM;
b752ccd1
AM
33270+
33271+ return err;
1facf9fc 33272+}
7f207e10
AM
33273diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
33274--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 33275+++ linux/fs/aufs/wkq.h 2015-09-24 10:47:58.258053165 +0200
523b37e3 33276@@ -0,0 +1,91 @@
1facf9fc 33277+/*
2000de60 33278+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 33279+ *
33280+ * This program, aufs is free software; you can redistribute it and/or modify
33281+ * it under the terms of the GNU General Public License as published by
33282+ * the Free Software Foundation; either version 2 of the License, or
33283+ * (at your option) any later version.
dece6358
AM
33284+ *
33285+ * This program is distributed in the hope that it will be useful,
33286+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33287+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33288+ * GNU General Public License for more details.
33289+ *
33290+ * You should have received a copy of the GNU General Public License
523b37e3 33291+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33292+ */
33293+
33294+/*
33295+ * workqueue for asynchronous/super-io operations
33296+ * todo: try new credentials management scheme
33297+ */
33298+
33299+#ifndef __AUFS_WKQ_H__
33300+#define __AUFS_WKQ_H__
33301+
33302+#ifdef __KERNEL__
33303+
dece6358
AM
33304+struct super_block;
33305+
1facf9fc 33306+/* ---------------------------------------------------------------------- */
33307+
33308+/*
33309+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
33310+ */
33311+struct au_nowait_tasks {
33312+ atomic_t nw_len;
33313+ wait_queue_head_t nw_wq;
33314+};
33315+
33316+/* ---------------------------------------------------------------------- */
33317+
33318+typedef void (*au_wkq_func_t)(void *args);
33319+
33320+/* wkq flags */
33321+#define AuWkq_WAIT 1
9dbd164d 33322+#define AuWkq_NEST (1 << 1)
1facf9fc 33323+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
33324+#define au_fset_wkq(flags, name) \
33325+ do { (flags) |= AuWkq_##name; } while (0)
33326+#define au_fclr_wkq(flags, name) \
33327+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 33328+
9dbd164d
AM
33329+#ifndef CONFIG_AUFS_HNOTIFY
33330+#undef AuWkq_NEST
33331+#define AuWkq_NEST 0
33332+#endif
33333+
1facf9fc 33334+/* wkq.c */
b752ccd1 33335+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
33336+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
33337+ unsigned int flags);
1facf9fc 33338+void au_nwt_init(struct au_nowait_tasks *nwt);
33339+int __init au_wkq_init(void);
33340+void au_wkq_fin(void);
33341+
33342+/* ---------------------------------------------------------------------- */
33343+
53392da6
AM
33344+static inline int au_wkq_test(void)
33345+{
33346+ return current->flags & PF_WQ_WORKER;
33347+}
33348+
b752ccd1 33349+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 33350+{
b752ccd1 33351+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 33352+}
33353+
33354+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
33355+{
e49829fe 33356+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 33357+ wake_up_all(&nwt->nw_wq);
33358+}
33359+
33360+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
33361+{
33362+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
33363+ return 0;
33364+}
33365+
33366+#endif /* __KERNEL__ */
33367+#endif /* __AUFS_WKQ_H__ */
c1595e42
JR
33368diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
33369--- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100
c2c0f25c 33370+++ linux/fs/aufs/xattr.c 2015-09-24 10:47:58.258053165 +0200
b912730e 33371@@ -0,0 +1,344 @@
c1595e42 33372+/*
2000de60 33373+ * Copyright (C) 2014-2015 Junjiro R. Okajima
c1595e42
JR
33374+ *
33375+ * This program, aufs is free software; you can redistribute it and/or modify
33376+ * it under the terms of the GNU General Public License as published by
33377+ * the Free Software Foundation; either version 2 of the License, or
33378+ * (at your option) any later version.
33379+ *
33380+ * This program is distributed in the hope that it will be useful,
33381+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33382+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33383+ * GNU General Public License for more details.
33384+ *
33385+ * You should have received a copy of the GNU General Public License
33386+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
33387+ */
33388+
33389+/*
33390+ * handling xattr functions
33391+ */
33392+
33393+#include <linux/xattr.h>
33394+#include "aufs.h"
33395+
33396+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
33397+{
33398+ if (!ignore_flags)
33399+ goto out;
33400+ switch (err) {
33401+ case -ENOMEM:
33402+ case -EDQUOT:
33403+ goto out;
33404+ }
33405+
33406+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
33407+ err = 0;
33408+ goto out;
33409+ }
33410+
33411+#define cmp(brattr, prefix) do { \
33412+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \
33413+ XATTR_##prefix##_PREFIX_LEN)) { \
33414+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \
33415+ err = 0; \
33416+ goto out; \
33417+ } \
33418+ } while (0)
33419+
33420+ cmp(SEC, SECURITY);
33421+ cmp(SYS, SYSTEM);
33422+ cmp(TR, TRUSTED);
33423+ cmp(USR, USER);
33424+#undef cmp
33425+
33426+ if (ignore_flags & AuBrAttr_ICEX_OTH)
33427+ err = 0;
33428+
33429+out:
33430+ return err;
33431+}
33432+
33433+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
33434+
33435+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe
AM
33436+ char *name, char **buf, unsigned int ignore_flags,
33437+ unsigned int verbose)
c1595e42
JR
33438+{
33439+ int err;
33440+ ssize_t ssz;
33441+ struct inode *h_idst;
33442+
33443+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
33444+ err = ssz;
33445+ if (unlikely(err <= 0)) {
c1595e42
JR
33446+ if (err == -ENODATA
33447+ || (err == -EOPNOTSUPP
b912730e 33448+ && ((ignore_flags & au_xattr_out_of_list)
5527c038 33449+ || (au_test_nfs_noacl(d_inode(h_src))
b912730e
AM
33450+ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)
33451+ || !strcmp(name,
33452+ XATTR_NAME_POSIX_ACL_DEFAULT))))
33453+ ))
c1595e42 33454+ err = 0;
b912730e
AM
33455+ if (err && (verbose || au_debug_test()))
33456+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
33457+ goto out;
33458+ }
33459+
33460+ /* unlock it temporary */
5527c038 33461+ h_idst = d_inode(h_dst);
c1595e42
JR
33462+ mutex_unlock(&h_idst->i_mutex);
33463+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
33464+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
33465+ if (unlikely(err)) {
7e9cd9fe
AM
33466+ if (verbose || au_debug_test())
33467+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
33468+ err = au_xattr_ignore(err, name, ignore_flags);
33469+ }
33470+
33471+out:
33472+ return err;
33473+}
33474+
7e9cd9fe
AM
33475+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
33476+ unsigned int verbose)
c1595e42
JR
33477+{
33478+ int err, unlocked, acl_access, acl_default;
33479+ ssize_t ssz;
33480+ struct inode *h_isrc, *h_idst;
33481+ char *value, *p, *o, *e;
33482+
33483+ /* try stopping to update the source inode while we are referencing */
7e9cd9fe 33484+ /* there should not be the parent-child relationship between them */
5527c038
JR
33485+ h_isrc = d_inode(h_src);
33486+ h_idst = d_inode(h_dst);
c1595e42
JR
33487+ mutex_unlock(&h_idst->i_mutex);
33488+ mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD);
33489+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
33490+ unlocked = 0;
33491+
33492+ /* some filesystems don't list POSIX ACL, for example tmpfs */
33493+ ssz = vfs_listxattr(h_src, NULL, 0);
33494+ err = ssz;
33495+ if (unlikely(err < 0)) {
33496+ AuTraceErr(err);
33497+ if (err == -ENODATA
33498+ || err == -EOPNOTSUPP)
33499+ err = 0; /* ignore */
33500+ goto out;
33501+ }
33502+
33503+ err = 0;
33504+ p = NULL;
33505+ o = NULL;
33506+ if (ssz) {
33507+ err = -ENOMEM;
33508+ p = kmalloc(ssz, GFP_NOFS);
33509+ o = p;
33510+ if (unlikely(!p))
33511+ goto out;
33512+ err = vfs_listxattr(h_src, p, ssz);
33513+ }
33514+ mutex_unlock(&h_isrc->i_mutex);
33515+ unlocked = 1;
33516+ AuDbg("err %d, ssz %zd\n", err, ssz);
33517+ if (unlikely(err < 0))
33518+ goto out_free;
33519+
33520+ err = 0;
33521+ e = p + ssz;
33522+ value = NULL;
33523+ acl_access = 0;
33524+ acl_default = 0;
33525+ while (!err && p < e) {
33526+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
33527+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
33528+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
33529+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
33530+ - 1);
7e9cd9fe
AM
33531+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags,
33532+ verbose);
c1595e42
JR
33533+ p += strlen(p) + 1;
33534+ }
33535+ AuTraceErr(err);
33536+ ignore_flags |= au_xattr_out_of_list;
33537+ if (!err && !acl_access) {
33538+ err = au_do_cpup_xattr(h_dst, h_src,
33539+ XATTR_NAME_POSIX_ACL_ACCESS, &value,
7e9cd9fe 33540+ ignore_flags, verbose);
c1595e42
JR
33541+ AuTraceErr(err);
33542+ }
33543+ if (!err && !acl_default) {
33544+ err = au_do_cpup_xattr(h_dst, h_src,
33545+ XATTR_NAME_POSIX_ACL_DEFAULT, &value,
7e9cd9fe 33546+ ignore_flags, verbose);
c1595e42
JR
33547+ AuTraceErr(err);
33548+ }
33549+
33550+ kfree(value);
33551+
33552+out_free:
33553+ kfree(o);
33554+out:
33555+ if (!unlocked)
33556+ mutex_unlock(&h_isrc->i_mutex);
33557+ AuTraceErr(err);
33558+ return err;
33559+}
33560+
33561+/* ---------------------------------------------------------------------- */
33562+
33563+enum {
33564+ AU_XATTR_LIST,
33565+ AU_XATTR_GET
33566+};
33567+
33568+struct au_lgxattr {
33569+ int type;
33570+ union {
33571+ struct {
33572+ char *list;
33573+ size_t size;
33574+ } list;
33575+ struct {
33576+ const char *name;
33577+ void *value;
33578+ size_t size;
33579+ } get;
33580+ } u;
33581+};
33582+
33583+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
33584+{
33585+ ssize_t err;
33586+ struct path h_path;
33587+ struct super_block *sb;
33588+
33589+ sb = dentry->d_sb;
33590+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
33591+ if (unlikely(err))
33592+ goto out;
33593+ err = au_h_path_getattr(dentry, /*force*/1, &h_path);
33594+ if (unlikely(err))
33595+ goto out_si;
33596+ if (unlikely(!h_path.dentry))
33597+ /* illegally overlapped or something */
33598+ goto out_di; /* pretending success */
33599+
33600+ /* always topmost entry only */
33601+ switch (arg->type) {
33602+ case AU_XATTR_LIST:
33603+ err = vfs_listxattr(h_path.dentry,
33604+ arg->u.list.list, arg->u.list.size);
33605+ break;
33606+ case AU_XATTR_GET:
33607+ err = vfs_getxattr(h_path.dentry,
33608+ arg->u.get.name, arg->u.get.value,
33609+ arg->u.get.size);
33610+ break;
33611+ }
33612+
33613+out_di:
33614+ di_read_unlock(dentry, AuLock_IR);
33615+out_si:
33616+ si_read_unlock(sb);
33617+out:
33618+ AuTraceErr(err);
33619+ return err;
33620+}
33621+
33622+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
33623+{
33624+ struct au_lgxattr arg = {
33625+ .type = AU_XATTR_LIST,
33626+ .u.list = {
33627+ .list = list,
33628+ .size = size
33629+ },
33630+ };
33631+
33632+ return au_lgxattr(dentry, &arg);
33633+}
33634+
33635+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
33636+ size_t size)
33637+{
33638+ struct au_lgxattr arg = {
33639+ .type = AU_XATTR_GET,
33640+ .u.get = {
33641+ .name = name,
33642+ .value = value,
33643+ .size = size
33644+ },
33645+ };
33646+
33647+ return au_lgxattr(dentry, &arg);
33648+}
33649+
33650+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
33651+ size_t size, int flags)
33652+{
33653+ struct au_srxattr arg = {
33654+ .type = AU_XATTR_SET,
33655+ .u.set = {
33656+ .name = name,
33657+ .value = value,
33658+ .size = size,
33659+ .flags = flags
33660+ },
33661+ };
33662+
33663+ return au_srxattr(dentry, &arg);
33664+}
33665+
33666+int aufs_removexattr(struct dentry *dentry, const char *name)
33667+{
33668+ struct au_srxattr arg = {
33669+ .type = AU_XATTR_REMOVE,
33670+ .u.remove = {
33671+ .name = name
33672+ },
33673+ };
33674+
33675+ return au_srxattr(dentry, &arg);
33676+}
33677+
33678+/* ---------------------------------------------------------------------- */
33679+
33680+#if 0
33681+static size_t au_xattr_list(struct dentry *dentry, char *list, size_t list_size,
33682+ const char *name, size_t name_len, int type)
33683+{
33684+ return aufs_listxattr(dentry, list, list_size);
33685+}
33686+
33687+static int au_xattr_get(struct dentry *dentry, const char *name, void *buffer,
33688+ size_t size, int type)
33689+{
33690+ return aufs_getxattr(dentry, name, buffer, size);
33691+}
33692+
33693+static int au_xattr_set(struct dentry *dentry, const char *name,
33694+ const void *value, size_t size, int flags, int type)
33695+{
33696+ return aufs_setxattr(dentry, name, value, size, flags);
33697+}
33698+
33699+static const struct xattr_handler au_xattr_handler = {
33700+ /* no prefix, no flags */
33701+ .list = au_xattr_list,
33702+ .get = au_xattr_get,
33703+ .set = au_xattr_set
33704+ /* why no remove? */
33705+};
33706+
33707+static const struct xattr_handler *au_xattr_handlers[] = {
33708+ &au_xattr_handler
33709+};
33710+
33711+void au_xattr_init(struct super_block *sb)
33712+{
33713+ /* sb->s_xattr = au_xattr_handlers; */
33714+}
33715+#endif
7f207e10
AM
33716diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
33717--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
79b8bda9
AM
33718+++ linux/fs/aufs/xino.c 2015-11-11 17:21:46.922197217 +0100
33719@@ -0,0 +1,1296 @@
1facf9fc 33720+/*
2000de60 33721+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 33722+ *
33723+ * This program, aufs is free software; you can redistribute it and/or modify
33724+ * it under the terms of the GNU General Public License as published by
33725+ * the Free Software Foundation; either version 2 of the License, or
33726+ * (at your option) any later version.
dece6358
AM
33727+ *
33728+ * This program is distributed in the hope that it will be useful,
33729+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33730+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33731+ * GNU General Public License for more details.
33732+ *
33733+ * You should have received a copy of the GNU General Public License
523b37e3 33734+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33735+ */
33736+
33737+/*
33738+ * external inode number translation table and bitmap
33739+ */
33740+
33741+#include <linux/seq_file.h>
392086de 33742+#include <linux/statfs.h>
1facf9fc 33743+#include "aufs.h"
33744+
9dbd164d 33745+/* todo: unnecessary to support mmap_sem since kernel-space? */
5527c038 33746+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 33747+ loff_t *pos)
33748+{
33749+ ssize_t err;
33750+ mm_segment_t oldfs;
b752ccd1
AM
33751+ union {
33752+ void *k;
33753+ char __user *u;
33754+ } buf;
1facf9fc 33755+
b752ccd1 33756+ buf.k = kbuf;
1facf9fc 33757+ oldfs = get_fs();
33758+ set_fs(KERNEL_DS);
33759+ do {
33760+ /* todo: signal_pending? */
b752ccd1 33761+ err = func(file, buf.u, size, pos);
1facf9fc 33762+ } while (err == -EAGAIN || err == -EINTR);
33763+ set_fs(oldfs);
33764+
33765+#if 0 /* reserved for future use */
33766+ if (err > 0)
2000de60 33767+ fsnotify_access(file->f_path.dentry);
1facf9fc 33768+#endif
33769+
33770+ return err;
33771+}
33772+
33773+/* ---------------------------------------------------------------------- */
33774+
5527c038 33775+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf,
1facf9fc 33776+ size_t size, loff_t *pos)
33777+{
33778+ ssize_t err;
33779+ mm_segment_t oldfs;
b752ccd1
AM
33780+ union {
33781+ void *k;
33782+ const char __user *u;
33783+ } buf;
1facf9fc 33784+
b752ccd1 33785+ buf.k = kbuf;
1facf9fc 33786+ oldfs = get_fs();
33787+ set_fs(KERNEL_DS);
1facf9fc 33788+ do {
33789+ /* todo: signal_pending? */
b752ccd1 33790+ err = func(file, buf.u, size, pos);
1facf9fc 33791+ } while (err == -EAGAIN || err == -EINTR);
1facf9fc 33792+ set_fs(oldfs);
33793+
33794+#if 0 /* reserved for future use */
33795+ if (err > 0)
2000de60 33796+ fsnotify_modify(file->f_path.dentry);
1facf9fc 33797+#endif
33798+
33799+ return err;
33800+}
33801+
33802+struct do_xino_fwrite_args {
33803+ ssize_t *errp;
5527c038 33804+ vfs_writef_t func;
1facf9fc 33805+ struct file *file;
33806+ void *buf;
33807+ size_t size;
33808+ loff_t *pos;
33809+};
33810+
33811+static void call_do_xino_fwrite(void *args)
33812+{
33813+ struct do_xino_fwrite_args *a = args;
33814+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
33815+}
33816+
5527c038
JR
33817+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf,
33818+ size_t size, loff_t *pos)
1facf9fc 33819+{
33820+ ssize_t err;
33821+
33822+ /* todo: signal block and no wkq? */
b752ccd1
AM
33823+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
33824+ lockdep_off();
33825+ err = do_xino_fwrite(func, file, buf, size, pos);
33826+ lockdep_on();
33827+ } else {
33828+ /*
33829+ * it breaks RLIMIT_FSIZE and normal user's limit,
33830+ * users should care about quota and real 'filesystem full.'
33831+ */
1facf9fc 33832+ int wkq_err;
33833+ struct do_xino_fwrite_args args = {
33834+ .errp = &err,
33835+ .func = func,
33836+ .file = file,
33837+ .buf = buf,
33838+ .size = size,
33839+ .pos = pos
33840+ };
33841+
33842+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
33843+ if (unlikely(wkq_err))
33844+ err = wkq_err;
b752ccd1 33845+ }
1facf9fc 33846+
33847+ return err;
33848+}
33849+
33850+/* ---------------------------------------------------------------------- */
33851+
33852+/*
33853+ * create a new xinofile at the same place/path as @base_file.
33854+ */
33855+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
33856+{
33857+ struct file *file;
4a4d8108 33858+ struct dentry *base, *parent;
523b37e3 33859+ struct inode *dir, *delegated;
1facf9fc 33860+ struct qstr *name;
1308ab2a 33861+ struct path path;
4a4d8108 33862+ int err;
1facf9fc 33863+
2000de60 33864+ base = base_file->f_path.dentry;
1facf9fc 33865+ parent = base->d_parent; /* dir inode is locked */
5527c038 33866+ dir = d_inode(parent);
1facf9fc 33867+ IMustLock(dir);
33868+
33869+ file = ERR_PTR(-EINVAL);
33870+ name = &base->d_name;
4a4d8108
AM
33871+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
33872+ if (IS_ERR(path.dentry)) {
33873+ file = (void *)path.dentry;
523b37e3
AM
33874+ pr_err("%pd lookup err %ld\n",
33875+ base, PTR_ERR(path.dentry));
1facf9fc 33876+ goto out;
33877+ }
33878+
33879+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 33880+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 33881+ if (unlikely(err)) {
33882+ file = ERR_PTR(err);
523b37e3 33883+ pr_err("%pd create err %d\n", base, err);
1facf9fc 33884+ goto out_dput;
33885+ }
33886+
c06a8ce3 33887+ path.mnt = base_file->f_path.mnt;
4a4d8108 33888+ file = vfsub_dentry_open(&path,
7f207e10 33889+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 33890+ /* | __FMODE_NONOTIFY */);
1facf9fc 33891+ if (IS_ERR(file)) {
523b37e3 33892+ pr_err("%pd open err %ld\n", base, PTR_ERR(file));
1facf9fc 33893+ goto out_dput;
33894+ }
33895+
523b37e3
AM
33896+ delegated = NULL;
33897+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
33898+ if (unlikely(err == -EWOULDBLOCK)) {
33899+ pr_warn("cannot retry for NFSv4 delegation"
33900+ " for an internal unlink\n");
33901+ iput(delegated);
33902+ }
1facf9fc 33903+ if (unlikely(err)) {
523b37e3 33904+ pr_err("%pd unlink err %d\n", base, err);
1facf9fc 33905+ goto out_fput;
33906+ }
33907+
33908+ if (copy_src) {
33909+ /* no one can touch copy_src xino */
c06a8ce3 33910+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 33911+ if (unlikely(err)) {
523b37e3 33912+ pr_err("%pd copy err %d\n", base, err);
1facf9fc 33913+ goto out_fput;
33914+ }
33915+ }
33916+ goto out_dput; /* success */
33917+
4f0767ce 33918+out_fput:
1facf9fc 33919+ fput(file);
33920+ file = ERR_PTR(err);
4f0767ce 33921+out_dput:
4a4d8108 33922+ dput(path.dentry);
4f0767ce 33923+out:
1facf9fc 33924+ return file;
33925+}
33926+
33927+struct au_xino_lock_dir {
33928+ struct au_hinode *hdir;
33929+ struct dentry *parent;
33930+ struct mutex *mtx;
33931+};
33932+
33933+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
33934+ struct au_xino_lock_dir *ldir)
33935+{
33936+ aufs_bindex_t brid, bindex;
33937+
33938+ ldir->hdir = NULL;
33939+ bindex = -1;
33940+ brid = au_xino_brid(sb);
33941+ if (brid >= 0)
33942+ bindex = au_br_index(sb, brid);
33943+ if (bindex >= 0) {
5527c038 33944+ ldir->hdir = au_hi(d_inode(sb->s_root), bindex);
4a4d8108 33945+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 33946+ } else {
2000de60 33947+ ldir->parent = dget_parent(xino->f_path.dentry);
5527c038 33948+ ldir->mtx = &d_inode(ldir->parent)->i_mutex;
1facf9fc 33949+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
33950+ }
33951+}
33952+
33953+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
33954+{
33955+ if (ldir->hdir)
4a4d8108 33956+ au_hn_imtx_unlock(ldir->hdir);
1facf9fc 33957+ else {
33958+ mutex_unlock(ldir->mtx);
33959+ dput(ldir->parent);
33960+ }
33961+}
33962+
33963+/* ---------------------------------------------------------------------- */
33964+
33965+/* trucate xino files asynchronously */
33966+
33967+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
33968+{
33969+ int err;
392086de
AM
33970+ unsigned long jiffy;
33971+ blkcnt_t blocks;
1facf9fc 33972+ aufs_bindex_t bi, bend;
392086de 33973+ struct kstatfs *st;
1facf9fc 33974+ struct au_branch *br;
33975+ struct file *new_xino, *file;
33976+ struct super_block *h_sb;
33977+ struct au_xino_lock_dir ldir;
33978+
392086de
AM
33979+ err = -ENOMEM;
33980+ st = kzalloc(sizeof(*st), GFP_NOFS);
33981+ if (unlikely(!st))
33982+ goto out;
33983+
1facf9fc 33984+ err = -EINVAL;
33985+ bend = au_sbend(sb);
33986+ if (unlikely(bindex < 0 || bend < bindex))
392086de 33987+ goto out_st;
1facf9fc 33988+ br = au_sbr(sb, bindex);
33989+ file = br->br_xino.xi_file;
33990+ if (!file)
392086de
AM
33991+ goto out_st;
33992+
33993+ err = vfs_statfs(&file->f_path, st);
33994+ if (unlikely(err))
33995+ AuErr1("statfs err %d, ignored\n", err);
33996+ jiffy = jiffies;
33997+ blocks = file_inode(file)->i_blocks;
33998+ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
33999+ bindex, (u64)blocks, st->f_bfree, st->f_blocks);
1facf9fc 34000+
34001+ au_xino_lock_dir(sb, file, &ldir);
34002+ /* mnt_want_write() is unnecessary here */
34003+ new_xino = au_xino_create2(file, file);
34004+ au_xino_unlock_dir(&ldir);
34005+ err = PTR_ERR(new_xino);
392086de
AM
34006+ if (IS_ERR(new_xino)) {
34007+ pr_err("err %d, ignored\n", err);
34008+ goto out_st;
34009+ }
1facf9fc 34010+ err = 0;
34011+ fput(file);
34012+ br->br_xino.xi_file = new_xino;
34013+
86dc4139 34014+ h_sb = au_br_sb(br);
1facf9fc 34015+ for (bi = 0; bi <= bend; bi++) {
34016+ if (unlikely(bi == bindex))
34017+ continue;
34018+ br = au_sbr(sb, bi);
86dc4139 34019+ if (au_br_sb(br) != h_sb)
1facf9fc 34020+ continue;
34021+
34022+ fput(br->br_xino.xi_file);
34023+ br->br_xino.xi_file = new_xino;
34024+ get_file(new_xino);
34025+ }
34026+
392086de
AM
34027+ err = vfs_statfs(&new_xino->f_path, st);
34028+ if (!err) {
34029+ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
34030+ bindex, (u64)file_inode(new_xino)->i_blocks,
34031+ st->f_bfree, st->f_blocks);
34032+ if (file_inode(new_xino)->i_blocks < blocks)
34033+ au_sbi(sb)->si_xino_jiffy = jiffy;
34034+ } else
34035+ AuErr1("statfs err %d, ignored\n", err);
34036+
34037+out_st:
34038+ kfree(st);
4f0767ce 34039+out:
1facf9fc 34040+ return err;
34041+}
34042+
34043+struct xino_do_trunc_args {
34044+ struct super_block *sb;
34045+ struct au_branch *br;
34046+};
34047+
34048+static void xino_do_trunc(void *_args)
34049+{
34050+ struct xino_do_trunc_args *args = _args;
34051+ struct super_block *sb;
34052+ struct au_branch *br;
34053+ struct inode *dir;
34054+ int err;
34055+ aufs_bindex_t bindex;
34056+
34057+ err = 0;
34058+ sb = args->sb;
5527c038 34059+ dir = d_inode(sb->s_root);
1facf9fc 34060+ br = args->br;
34061+
34062+ si_noflush_write_lock(sb);
34063+ ii_read_lock_parent(dir);
34064+ bindex = au_br_index(sb, br->br_id);
34065+ err = au_xino_trunc(sb, bindex);
1facf9fc 34066+ ii_read_unlock(dir);
34067+ if (unlikely(err))
392086de 34068+ pr_warn("err b%d, (%d)\n", bindex, err);
1facf9fc 34069+ atomic_dec(&br->br_xino_running);
34070+ atomic_dec(&br->br_count);
1facf9fc 34071+ si_write_unlock(sb);
027c5e7a 34072+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 34073+ kfree(args);
34074+}
34075+
392086de
AM
34076+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
34077+{
34078+ int err;
34079+ struct kstatfs st;
34080+ struct au_sbinfo *sbinfo;
34081+
34082+ /* todo: si_xino_expire and the ratio should be customizable */
34083+ sbinfo = au_sbi(sb);
34084+ if (time_before(jiffies,
34085+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
34086+ return 0;
34087+
34088+ /* truncation border */
34089+ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
34090+ if (unlikely(err)) {
34091+ AuErr1("statfs err %d, ignored\n", err);
34092+ return 0;
34093+ }
34094+ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
34095+ return 0;
34096+
34097+ return 1;
34098+}
34099+
1facf9fc 34100+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
34101+{
34102+ struct xino_do_trunc_args *args;
34103+ int wkq_err;
34104+
392086de 34105+ if (!xino_trunc_test(sb, br))
1facf9fc 34106+ return;
34107+
34108+ if (atomic_inc_return(&br->br_xino_running) > 1)
34109+ goto out;
34110+
34111+ /* lock and kfree() will be called in trunc_xino() */
34112+ args = kmalloc(sizeof(*args), GFP_NOFS);
34113+ if (unlikely(!args)) {
34114+ AuErr1("no memory\n");
34115+ goto out_args;
34116+ }
34117+
e49829fe 34118+ atomic_inc(&br->br_count);
1facf9fc 34119+ args->sb = sb;
34120+ args->br = br;
53392da6 34121+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 34122+ if (!wkq_err)
34123+ return; /* success */
34124+
4a4d8108 34125+ pr_err("wkq %d\n", wkq_err);
e49829fe 34126+ atomic_dec(&br->br_count);
1facf9fc 34127+
4f0767ce 34128+out_args:
1facf9fc 34129+ kfree(args);
4f0767ce 34130+out:
e49829fe 34131+ atomic_dec(&br->br_xino_running);
1facf9fc 34132+}
34133+
34134+/* ---------------------------------------------------------------------- */
34135+
5527c038 34136+static int au_xino_do_write(vfs_writef_t write, struct file *file,
1facf9fc 34137+ ino_t h_ino, ino_t ino)
34138+{
34139+ loff_t pos;
34140+ ssize_t sz;
34141+
34142+ pos = h_ino;
34143+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
34144+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
34145+ return -EFBIG;
34146+ }
34147+ pos *= sizeof(ino);
34148+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
34149+ if (sz == sizeof(ino))
34150+ return 0; /* success */
34151+
34152+ AuIOErr("write failed (%zd)\n", sz);
34153+ return -EIO;
34154+}
34155+
34156+/*
34157+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
34158+ * at the position of @h_ino.
34159+ * even if @ino is zero, it is written to the xinofile and means no entry.
34160+ * if the size of the xino file on a specific filesystem exceeds the watermark,
34161+ * try truncating it.
34162+ */
34163+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
34164+ ino_t ino)
34165+{
34166+ int err;
34167+ unsigned int mnt_flags;
34168+ struct au_branch *br;
34169+
34170+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
34171+ || ((loff_t)-1) > 0);
dece6358 34172+ SiMustAnyLock(sb);
1facf9fc 34173+
34174+ mnt_flags = au_mntflags(sb);
34175+ if (!au_opt_test(mnt_flags, XINO))
34176+ return 0;
34177+
34178+ br = au_sbr(sb, bindex);
34179+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
34180+ h_ino, ino);
34181+ if (!err) {
34182+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 34183+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 34184+ xino_try_trunc(sb, br);
34185+ return 0; /* success */
34186+ }
34187+
34188+ AuIOErr("write failed (%d)\n", err);
34189+ return -EIO;
34190+}
34191+
34192+/* ---------------------------------------------------------------------- */
34193+
34194+/* aufs inode number bitmap */
34195+
34196+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
34197+static ino_t xib_calc_ino(unsigned long pindex, int bit)
34198+{
34199+ ino_t ino;
34200+
34201+ AuDebugOn(bit < 0 || page_bits <= bit);
34202+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
34203+ return ino;
34204+}
34205+
34206+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
34207+{
34208+ AuDebugOn(ino < AUFS_FIRST_INO);
34209+ ino -= AUFS_FIRST_INO;
34210+ *pindex = ino / page_bits;
34211+ *bit = ino % page_bits;
34212+}
34213+
34214+static int xib_pindex(struct super_block *sb, unsigned long pindex)
34215+{
34216+ int err;
34217+ loff_t pos;
34218+ ssize_t sz;
34219+ struct au_sbinfo *sbinfo;
34220+ struct file *xib;
34221+ unsigned long *p;
34222+
34223+ sbinfo = au_sbi(sb);
34224+ MtxMustLock(&sbinfo->si_xib_mtx);
34225+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
34226+ || !au_opt_test(sbinfo->si_mntflags, XINO));
34227+
34228+ if (pindex == sbinfo->si_xib_last_pindex)
34229+ return 0;
34230+
34231+ xib = sbinfo->si_xib;
34232+ p = sbinfo->si_xib_buf;
34233+ pos = sbinfo->si_xib_last_pindex;
34234+ pos *= PAGE_SIZE;
34235+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
34236+ if (unlikely(sz != PAGE_SIZE))
34237+ goto out;
34238+
34239+ pos = pindex;
34240+ pos *= PAGE_SIZE;
c06a8ce3 34241+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 34242+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
34243+ else {
34244+ memset(p, 0, PAGE_SIZE);
34245+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
34246+ }
34247+ if (sz == PAGE_SIZE) {
34248+ sbinfo->si_xib_last_pindex = pindex;
34249+ return 0; /* success */
34250+ }
34251+
4f0767ce 34252+out:
b752ccd1
AM
34253+ AuIOErr1("write failed (%zd)\n", sz);
34254+ err = sz;
34255+ if (sz >= 0)
34256+ err = -EIO;
34257+ return err;
34258+}
34259+
34260+/* ---------------------------------------------------------------------- */
34261+
34262+static void au_xib_clear_bit(struct inode *inode)
34263+{
34264+ int err, bit;
34265+ unsigned long pindex;
34266+ struct super_block *sb;
34267+ struct au_sbinfo *sbinfo;
34268+
34269+ AuDebugOn(inode->i_nlink);
34270+
34271+ sb = inode->i_sb;
34272+ xib_calc_bit(inode->i_ino, &pindex, &bit);
34273+ AuDebugOn(page_bits <= bit);
34274+ sbinfo = au_sbi(sb);
34275+ mutex_lock(&sbinfo->si_xib_mtx);
34276+ err = xib_pindex(sb, pindex);
34277+ if (!err) {
34278+ clear_bit(bit, sbinfo->si_xib_buf);
34279+ sbinfo->si_xib_next_bit = bit;
34280+ }
34281+ mutex_unlock(&sbinfo->si_xib_mtx);
34282+}
34283+
34284+/* for s_op->delete_inode() */
34285+void au_xino_delete_inode(struct inode *inode, const int unlinked)
34286+{
34287+ int err;
34288+ unsigned int mnt_flags;
34289+ aufs_bindex_t bindex, bend, bi;
34290+ unsigned char try_trunc;
34291+ struct au_iinfo *iinfo;
34292+ struct super_block *sb;
34293+ struct au_hinode *hi;
34294+ struct inode *h_inode;
34295+ struct au_branch *br;
5527c038 34296+ vfs_writef_t xwrite;
b752ccd1
AM
34297+
34298+ sb = inode->i_sb;
34299+ mnt_flags = au_mntflags(sb);
34300+ if (!au_opt_test(mnt_flags, XINO)
34301+ || inode->i_ino == AUFS_ROOT_INO)
34302+ return;
34303+
34304+ if (unlinked) {
34305+ au_xigen_inc(inode);
34306+ au_xib_clear_bit(inode);
34307+ }
34308+
34309+ iinfo = au_ii(inode);
34310+ if (!iinfo)
34311+ return;
1facf9fc 34312+
b752ccd1
AM
34313+ bindex = iinfo->ii_bstart;
34314+ if (bindex < 0)
34315+ return;
1facf9fc 34316+
b752ccd1
AM
34317+ xwrite = au_sbi(sb)->si_xwrite;
34318+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
34319+ hi = iinfo->ii_hinode + bindex;
34320+ bend = iinfo->ii_bend;
34321+ for (; bindex <= bend; bindex++, hi++) {
34322+ h_inode = hi->hi_inode;
34323+ if (!h_inode
34324+ || (!unlinked && h_inode->i_nlink))
34325+ continue;
1facf9fc 34326+
b752ccd1
AM
34327+ /* inode may not be revalidated */
34328+ bi = au_br_index(sb, hi->hi_id);
34329+ if (bi < 0)
34330+ continue;
1facf9fc 34331+
b752ccd1
AM
34332+ br = au_sbr(sb, bi);
34333+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
34334+ h_inode->i_ino, /*ino*/0);
34335+ if (!err && try_trunc
86dc4139 34336+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 34337+ xino_try_trunc(sb, br);
1facf9fc 34338+ }
1facf9fc 34339+}
34340+
34341+/* get an unused inode number from bitmap */
34342+ino_t au_xino_new_ino(struct super_block *sb)
34343+{
34344+ ino_t ino;
34345+ unsigned long *p, pindex, ul, pend;
34346+ struct au_sbinfo *sbinfo;
34347+ struct file *file;
34348+ int free_bit, err;
34349+
34350+ if (!au_opt_test(au_mntflags(sb), XINO))
34351+ return iunique(sb, AUFS_FIRST_INO);
34352+
34353+ sbinfo = au_sbi(sb);
34354+ mutex_lock(&sbinfo->si_xib_mtx);
34355+ p = sbinfo->si_xib_buf;
34356+ free_bit = sbinfo->si_xib_next_bit;
34357+ if (free_bit < page_bits && !test_bit(free_bit, p))
34358+ goto out; /* success */
34359+ free_bit = find_first_zero_bit(p, page_bits);
34360+ if (free_bit < page_bits)
34361+ goto out; /* success */
34362+
34363+ pindex = sbinfo->si_xib_last_pindex;
34364+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
34365+ err = xib_pindex(sb, ul);
34366+ if (unlikely(err))
34367+ goto out_err;
34368+ free_bit = find_first_zero_bit(p, page_bits);
34369+ if (free_bit < page_bits)
34370+ goto out; /* success */
34371+ }
34372+
34373+ file = sbinfo->si_xib;
c06a8ce3 34374+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 34375+ for (ul = pindex + 1; ul <= pend; ul++) {
34376+ err = xib_pindex(sb, ul);
34377+ if (unlikely(err))
34378+ goto out_err;
34379+ free_bit = find_first_zero_bit(p, page_bits);
34380+ if (free_bit < page_bits)
34381+ goto out; /* success */
34382+ }
34383+ BUG();
34384+
4f0767ce 34385+out:
1facf9fc 34386+ set_bit(free_bit, p);
7f207e10 34387+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 34388+ pindex = sbinfo->si_xib_last_pindex;
34389+ mutex_unlock(&sbinfo->si_xib_mtx);
34390+ ino = xib_calc_ino(pindex, free_bit);
34391+ AuDbg("i%lu\n", (unsigned long)ino);
34392+ return ino;
4f0767ce 34393+out_err:
1facf9fc 34394+ mutex_unlock(&sbinfo->si_xib_mtx);
34395+ AuDbg("i0\n");
34396+ return 0;
34397+}
34398+
34399+/*
34400+ * read @ino from xinofile for the specified branch{@sb, @bindex}
34401+ * at the position of @h_ino.
34402+ * if @ino does not exist and @do_new is true, get new one.
34403+ */
34404+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
34405+ ino_t *ino)
34406+{
34407+ int err;
34408+ ssize_t sz;
34409+ loff_t pos;
34410+ struct file *file;
34411+ struct au_sbinfo *sbinfo;
34412+
34413+ *ino = 0;
34414+ if (!au_opt_test(au_mntflags(sb), XINO))
34415+ return 0; /* no xino */
34416+
34417+ err = 0;
34418+ sbinfo = au_sbi(sb);
34419+ pos = h_ino;
34420+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
34421+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
34422+ return -EFBIG;
34423+ }
34424+ pos *= sizeof(*ino);
34425+
34426+ file = au_sbr(sb, bindex)->br_xino.xi_file;
c06a8ce3 34427+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 34428+ return 0; /* no ino */
34429+
34430+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
34431+ if (sz == sizeof(*ino))
34432+ return 0; /* success */
34433+
34434+ err = sz;
34435+ if (unlikely(sz >= 0)) {
34436+ err = -EIO;
34437+ AuIOErr("xino read error (%zd)\n", sz);
34438+ }
34439+
34440+ return err;
34441+}
34442+
34443+/* ---------------------------------------------------------------------- */
34444+
34445+/* create and set a new xino file */
34446+
34447+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
34448+{
34449+ struct file *file;
34450+ struct dentry *h_parent, *d;
b912730e 34451+ struct inode *h_dir, *inode;
1facf9fc 34452+ int err;
34453+
34454+ /*
34455+ * at mount-time, and the xino file is the default path,
4a4d8108 34456+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 34457+ * when a user specified the xino, we cannot get au_hdir to be ignored.
34458+ */
7f207e10 34459+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 34460+ /* | __FMODE_NONOTIFY */,
1facf9fc 34461+ S_IRUGO | S_IWUGO);
34462+ if (IS_ERR(file)) {
34463+ if (!silent)
4a4d8108 34464+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 34465+ return file;
34466+ }
34467+
34468+ /* keep file count */
b912730e
AM
34469+ err = 0;
34470+ inode = file_inode(file);
2000de60 34471+ h_parent = dget_parent(file->f_path.dentry);
5527c038 34472+ h_dir = d_inode(h_parent);
1facf9fc 34473+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
34474+ /* mnt_want_write() is unnecessary here */
523b37e3 34475+ /* no delegation since it is just created */
b912730e
AM
34476+ if (inode->i_nlink)
34477+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL,
34478+ /*force*/0);
1facf9fc 34479+ mutex_unlock(&h_dir->i_mutex);
34480+ dput(h_parent);
34481+ if (unlikely(err)) {
34482+ if (!silent)
4a4d8108 34483+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 34484+ goto out;
34485+ }
34486+
34487+ err = -EINVAL;
2000de60 34488+ d = file->f_path.dentry;
1facf9fc 34489+ if (unlikely(sb == d->d_sb)) {
34490+ if (!silent)
4a4d8108 34491+ pr_err("%s must be outside\n", fname);
1facf9fc 34492+ goto out;
34493+ }
34494+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
34495+ if (!silent)
4a4d8108
AM
34496+ pr_err("xino doesn't support %s(%s)\n",
34497+ fname, au_sbtype(d->d_sb));
1facf9fc 34498+ goto out;
34499+ }
34500+ return file; /* success */
34501+
4f0767ce 34502+out:
1facf9fc 34503+ fput(file);
34504+ file = ERR_PTR(err);
34505+ return file;
34506+}
34507+
34508+/*
34509+ * find another branch who is on the same filesystem of the specified
34510+ * branch{@btgt}. search until @bend.
34511+ */
34512+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
34513+ aufs_bindex_t bend)
34514+{
34515+ aufs_bindex_t bindex;
34516+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
34517+
34518+ for (bindex = 0; bindex < btgt; bindex++)
34519+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
34520+ return bindex;
34521+ for (bindex++; bindex <= bend; bindex++)
34522+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
34523+ return bindex;
34524+ return -1;
34525+}
34526+
34527+/* ---------------------------------------------------------------------- */
34528+
34529+/*
34530+ * initialize the xinofile for the specified branch @br
34531+ * at the place/path where @base_file indicates.
34532+ * test whether another branch is on the same filesystem or not,
34533+ * if @do_test is true.
34534+ */
34535+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
34536+ struct file *base_file, int do_test)
34537+{
34538+ int err;
34539+ ino_t ino;
34540+ aufs_bindex_t bend, bindex;
34541+ struct au_branch *shared_br, *b;
34542+ struct file *file;
34543+ struct super_block *tgt_sb;
34544+
34545+ shared_br = NULL;
34546+ bend = au_sbend(sb);
34547+ if (do_test) {
86dc4139 34548+ tgt_sb = au_br_sb(br);
1facf9fc 34549+ for (bindex = 0; bindex <= bend; bindex++) {
34550+ b = au_sbr(sb, bindex);
86dc4139 34551+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 34552+ shared_br = b;
34553+ break;
34554+ }
34555+ }
34556+ }
34557+
34558+ if (!shared_br || !shared_br->br_xino.xi_file) {
34559+ struct au_xino_lock_dir ldir;
34560+
34561+ au_xino_lock_dir(sb, base_file, &ldir);
34562+ /* mnt_want_write() is unnecessary here */
34563+ file = au_xino_create2(base_file, NULL);
34564+ au_xino_unlock_dir(&ldir);
34565+ err = PTR_ERR(file);
34566+ if (IS_ERR(file))
34567+ goto out;
34568+ br->br_xino.xi_file = file;
34569+ } else {
34570+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
34571+ get_file(br->br_xino.xi_file);
34572+ }
34573+
34574+ ino = AUFS_ROOT_INO;
34575+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
34576+ h_ino, ino);
b752ccd1
AM
34577+ if (unlikely(err)) {
34578+ fput(br->br_xino.xi_file);
34579+ br->br_xino.xi_file = NULL;
34580+ }
1facf9fc 34581+
4f0767ce 34582+out:
1facf9fc 34583+ return err;
34584+}
34585+
34586+/* ---------------------------------------------------------------------- */
34587+
34588+/* trucate a xino bitmap file */
34589+
34590+/* todo: slow */
34591+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
34592+{
34593+ int err, bit;
34594+ ssize_t sz;
34595+ unsigned long pindex;
34596+ loff_t pos, pend;
34597+ struct au_sbinfo *sbinfo;
5527c038 34598+ vfs_readf_t func;
1facf9fc 34599+ ino_t *ino;
34600+ unsigned long *p;
34601+
34602+ err = 0;
34603+ sbinfo = au_sbi(sb);
dece6358 34604+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 34605+ p = sbinfo->si_xib_buf;
34606+ func = sbinfo->si_xread;
c06a8ce3 34607+ pend = vfsub_f_size_read(file);
1facf9fc 34608+ pos = 0;
34609+ while (pos < pend) {
34610+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
34611+ err = sz;
34612+ if (unlikely(sz <= 0))
34613+ goto out;
34614+
34615+ err = 0;
34616+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
34617+ if (unlikely(*ino < AUFS_FIRST_INO))
34618+ continue;
34619+
34620+ xib_calc_bit(*ino, &pindex, &bit);
34621+ AuDebugOn(page_bits <= bit);
34622+ err = xib_pindex(sb, pindex);
34623+ if (!err)
34624+ set_bit(bit, p);
34625+ else
34626+ goto out;
34627+ }
34628+ }
34629+
4f0767ce 34630+out:
1facf9fc 34631+ return err;
34632+}
34633+
34634+static int xib_restore(struct super_block *sb)
34635+{
34636+ int err;
34637+ aufs_bindex_t bindex, bend;
34638+ void *page;
34639+
34640+ err = -ENOMEM;
34641+ page = (void *)__get_free_page(GFP_NOFS);
34642+ if (unlikely(!page))
34643+ goto out;
34644+
34645+ err = 0;
34646+ bend = au_sbend(sb);
34647+ for (bindex = 0; !err && bindex <= bend; bindex++)
34648+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
34649+ err = do_xib_restore
34650+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
34651+ else
34652+ AuDbg("b%d\n", bindex);
34653+ free_page((unsigned long)page);
34654+
4f0767ce 34655+out:
1facf9fc 34656+ return err;
34657+}
34658+
34659+int au_xib_trunc(struct super_block *sb)
34660+{
34661+ int err;
34662+ ssize_t sz;
34663+ loff_t pos;
34664+ struct au_xino_lock_dir ldir;
34665+ struct au_sbinfo *sbinfo;
34666+ unsigned long *p;
34667+ struct file *file;
34668+
dece6358
AM
34669+ SiMustWriteLock(sb);
34670+
1facf9fc 34671+ err = 0;
34672+ sbinfo = au_sbi(sb);
34673+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
34674+ goto out;
34675+
34676+ file = sbinfo->si_xib;
c06a8ce3 34677+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 34678+ goto out;
34679+
34680+ au_xino_lock_dir(sb, file, &ldir);
34681+ /* mnt_want_write() is unnecessary here */
34682+ file = au_xino_create2(sbinfo->si_xib, NULL);
34683+ au_xino_unlock_dir(&ldir);
34684+ err = PTR_ERR(file);
34685+ if (IS_ERR(file))
34686+ goto out;
34687+ fput(sbinfo->si_xib);
34688+ sbinfo->si_xib = file;
34689+
34690+ p = sbinfo->si_xib_buf;
34691+ memset(p, 0, PAGE_SIZE);
34692+ pos = 0;
34693+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
34694+ if (unlikely(sz != PAGE_SIZE)) {
34695+ err = sz;
34696+ AuIOErr("err %d\n", err);
34697+ if (sz >= 0)
34698+ err = -EIO;
34699+ goto out;
34700+ }
34701+
34702+ mutex_lock(&sbinfo->si_xib_mtx);
34703+ /* mnt_want_write() is unnecessary here */
34704+ err = xib_restore(sb);
34705+ mutex_unlock(&sbinfo->si_xib_mtx);
34706+
34707+out:
34708+ return err;
34709+}
34710+
34711+/* ---------------------------------------------------------------------- */
34712+
34713+/*
34714+ * xino mount option handlers
34715+ */
1facf9fc 34716+
34717+/* xino bitmap */
34718+static void xino_clear_xib(struct super_block *sb)
34719+{
34720+ struct au_sbinfo *sbinfo;
34721+
dece6358
AM
34722+ SiMustWriteLock(sb);
34723+
1facf9fc 34724+ sbinfo = au_sbi(sb);
34725+ sbinfo->si_xread = NULL;
34726+ sbinfo->si_xwrite = NULL;
34727+ if (sbinfo->si_xib)
34728+ fput(sbinfo->si_xib);
34729+ sbinfo->si_xib = NULL;
34730+ free_page((unsigned long)sbinfo->si_xib_buf);
34731+ sbinfo->si_xib_buf = NULL;
34732+}
34733+
34734+static int au_xino_set_xib(struct super_block *sb, struct file *base)
34735+{
34736+ int err;
34737+ loff_t pos;
34738+ struct au_sbinfo *sbinfo;
34739+ struct file *file;
34740+
dece6358
AM
34741+ SiMustWriteLock(sb);
34742+
1facf9fc 34743+ sbinfo = au_sbi(sb);
34744+ file = au_xino_create2(base, sbinfo->si_xib);
34745+ err = PTR_ERR(file);
34746+ if (IS_ERR(file))
34747+ goto out;
34748+ if (sbinfo->si_xib)
34749+ fput(sbinfo->si_xib);
34750+ sbinfo->si_xib = file;
5527c038
JR
34751+ sbinfo->si_xread = vfs_readf(file);
34752+ sbinfo->si_xwrite = vfs_writef(file);
1facf9fc 34753+
34754+ err = -ENOMEM;
34755+ if (!sbinfo->si_xib_buf)
34756+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
34757+ if (unlikely(!sbinfo->si_xib_buf))
34758+ goto out_unset;
34759+
34760+ sbinfo->si_xib_last_pindex = 0;
34761+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 34762+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 34763+ pos = 0;
34764+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
34765+ PAGE_SIZE, &pos);
34766+ if (unlikely(err != PAGE_SIZE))
34767+ goto out_free;
34768+ }
34769+ err = 0;
34770+ goto out; /* success */
34771+
4f0767ce 34772+out_free:
1facf9fc 34773+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
34774+ sbinfo->si_xib_buf = NULL;
34775+ if (err >= 0)
34776+ err = -EIO;
4f0767ce 34777+out_unset:
b752ccd1
AM
34778+ fput(sbinfo->si_xib);
34779+ sbinfo->si_xib = NULL;
34780+ sbinfo->si_xread = NULL;
34781+ sbinfo->si_xwrite = NULL;
4f0767ce 34782+out:
b752ccd1 34783+ return err;
1facf9fc 34784+}
34785+
b752ccd1
AM
34786+/* xino for each branch */
34787+static void xino_clear_br(struct super_block *sb)
34788+{
34789+ aufs_bindex_t bindex, bend;
34790+ struct au_branch *br;
1facf9fc 34791+
b752ccd1
AM
34792+ bend = au_sbend(sb);
34793+ for (bindex = 0; bindex <= bend; bindex++) {
34794+ br = au_sbr(sb, bindex);
34795+ if (!br || !br->br_xino.xi_file)
34796+ continue;
34797+
34798+ fput(br->br_xino.xi_file);
34799+ br->br_xino.xi_file = NULL;
34800+ }
34801+}
34802+
34803+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 34804+{
34805+ int err;
b752ccd1
AM
34806+ ino_t ino;
34807+ aufs_bindex_t bindex, bend, bshared;
34808+ struct {
34809+ struct file *old, *new;
34810+ } *fpair, *p;
34811+ struct au_branch *br;
34812+ struct inode *inode;
5527c038 34813+ vfs_writef_t writef;
1facf9fc 34814+
b752ccd1
AM
34815+ SiMustWriteLock(sb);
34816+
34817+ err = -ENOMEM;
34818+ bend = au_sbend(sb);
34819+ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
34820+ if (unlikely(!fpair))
1facf9fc 34821+ goto out;
34822+
5527c038 34823+ inode = d_inode(sb->s_root);
b752ccd1
AM
34824+ ino = AUFS_ROOT_INO;
34825+ writef = au_sbi(sb)->si_xwrite;
34826+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
34827+ br = au_sbr(sb, bindex);
34828+ bshared = is_sb_shared(sb, bindex, bindex - 1);
34829+ if (bshared >= 0) {
34830+ /* shared xino */
34831+ *p = fpair[bshared];
34832+ get_file(p->new);
34833+ }
34834+
34835+ if (!p->new) {
34836+ /* new xino */
34837+ p->old = br->br_xino.xi_file;
34838+ p->new = au_xino_create2(base, br->br_xino.xi_file);
34839+ err = PTR_ERR(p->new);
34840+ if (IS_ERR(p->new)) {
34841+ p->new = NULL;
34842+ goto out_pair;
34843+ }
34844+ }
34845+
34846+ err = au_xino_do_write(writef, p->new,
34847+ au_h_iptr(inode, bindex)->i_ino, ino);
34848+ if (unlikely(err))
34849+ goto out_pair;
34850+ }
34851+
34852+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
34853+ br = au_sbr(sb, bindex);
34854+ if (br->br_xino.xi_file)
34855+ fput(br->br_xino.xi_file);
34856+ get_file(p->new);
34857+ br->br_xino.xi_file = p->new;
34858+ }
1facf9fc 34859+
4f0767ce 34860+out_pair:
b752ccd1
AM
34861+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
34862+ if (p->new)
34863+ fput(p->new);
34864+ else
34865+ break;
34866+ kfree(fpair);
4f0767ce 34867+out:
1facf9fc 34868+ return err;
34869+}
b752ccd1
AM
34870+
34871+void au_xino_clr(struct super_block *sb)
34872+{
34873+ struct au_sbinfo *sbinfo;
34874+
34875+ au_xigen_clr(sb);
34876+ xino_clear_xib(sb);
34877+ xino_clear_br(sb);
34878+ sbinfo = au_sbi(sb);
34879+ /* lvalue, do not call au_mntflags() */
34880+ au_opt_clr(sbinfo->si_mntflags, XINO);
34881+}
34882+
34883+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
34884+{
34885+ int err, skip;
34886+ struct dentry *parent, *cur_parent;
34887+ struct qstr *dname, *cur_name;
34888+ struct file *cur_xino;
34889+ struct inode *dir;
34890+ struct au_sbinfo *sbinfo;
34891+
34892+ SiMustWriteLock(sb);
34893+
34894+ err = 0;
34895+ sbinfo = au_sbi(sb);
2000de60 34896+ parent = dget_parent(xino->file->f_path.dentry);
b752ccd1
AM
34897+ if (remount) {
34898+ skip = 0;
2000de60 34899+ dname = &xino->file->f_path.dentry->d_name;
b752ccd1
AM
34900+ cur_xino = sbinfo->si_xib;
34901+ if (cur_xino) {
2000de60
JR
34902+ cur_parent = dget_parent(cur_xino->f_path.dentry);
34903+ cur_name = &cur_xino->f_path.dentry->d_name;
b752ccd1 34904+ skip = (cur_parent == parent
38d290e6 34905+ && au_qstreq(dname, cur_name));
b752ccd1
AM
34906+ dput(cur_parent);
34907+ }
34908+ if (skip)
34909+ goto out;
34910+ }
34911+
34912+ au_opt_set(sbinfo->si_mntflags, XINO);
5527c038 34913+ dir = d_inode(parent);
b752ccd1
AM
34914+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
34915+ /* mnt_want_write() is unnecessary here */
34916+ err = au_xino_set_xib(sb, xino->file);
34917+ if (!err)
34918+ err = au_xigen_set(sb, xino->file);
34919+ if (!err)
34920+ err = au_xino_set_br(sb, xino->file);
34921+ mutex_unlock(&dir->i_mutex);
34922+ if (!err)
34923+ goto out; /* success */
34924+
34925+ /* reset all */
34926+ AuIOErr("failed creating xino(%d).\n", err);
c1595e42
JR
34927+ au_xigen_clr(sb);
34928+ xino_clear_xib(sb);
b752ccd1 34929+
4f0767ce 34930+out:
b752ccd1
AM
34931+ dput(parent);
34932+ return err;
34933+}
34934+
34935+/* ---------------------------------------------------------------------- */
34936+
34937+/*
34938+ * create a xinofile at the default place/path.
34939+ */
34940+struct file *au_xino_def(struct super_block *sb)
34941+{
34942+ struct file *file;
34943+ char *page, *p;
34944+ struct au_branch *br;
34945+ struct super_block *h_sb;
34946+ struct path path;
34947+ aufs_bindex_t bend, bindex, bwr;
34948+
34949+ br = NULL;
34950+ bend = au_sbend(sb);
34951+ bwr = -1;
34952+ for (bindex = 0; bindex <= bend; bindex++) {
34953+ br = au_sbr(sb, bindex);
34954+ if (au_br_writable(br->br_perm)
86dc4139 34955+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
34956+ bwr = bindex;
34957+ break;
34958+ }
34959+ }
34960+
7f207e10
AM
34961+ if (bwr >= 0) {
34962+ file = ERR_PTR(-ENOMEM);
537831f9 34963+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
34964+ if (unlikely(!page))
34965+ goto out;
86dc4139 34966+ path.mnt = au_br_mnt(br);
7f207e10
AM
34967+ path.dentry = au_h_dptr(sb->s_root, bwr);
34968+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
34969+ file = (void *)p;
34970+ if (!IS_ERR(p)) {
34971+ strcat(p, "/" AUFS_XINO_FNAME);
34972+ AuDbg("%s\n", p);
34973+ file = au_xino_create(sb, p, /*silent*/0);
34974+ if (!IS_ERR(file))
34975+ au_xino_brid_set(sb, br->br_id);
34976+ }
537831f9 34977+ free_page((unsigned long)page);
7f207e10
AM
34978+ } else {
34979+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
34980+ if (IS_ERR(file))
34981+ goto out;
2000de60 34982+ h_sb = file->f_path.dentry->d_sb;
7f207e10
AM
34983+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
34984+ pr_err("xino doesn't support %s(%s)\n",
34985+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
34986+ fput(file);
34987+ file = ERR_PTR(-EINVAL);
34988+ }
34989+ if (!IS_ERR(file))
34990+ au_xino_brid_set(sb, -1);
34991+ }
0c5527e5 34992+
7f207e10
AM
34993+out:
34994+ return file;
34995+}
34996+
34997+/* ---------------------------------------------------------------------- */
34998+
34999+int au_xino_path(struct seq_file *seq, struct file *file)
35000+{
35001+ int err;
35002+
35003+ err = au_seq_path(seq, &file->f_path);
79b8bda9 35004+ if (unlikely(err))
7f207e10
AM
35005+ goto out;
35006+
7f207e10
AM
35007+#define Deleted "\\040(deleted)"
35008+ seq->count -= sizeof(Deleted) - 1;
35009+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
35010+ sizeof(Deleted) - 1));
35011+#undef Deleted
35012+
35013+out:
35014+ return err;
35015+}
537831f9
AM
35016diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
35017--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
79b8bda9 35018+++ linux/include/uapi/linux/aufs_type.h 2015-11-11 17:22:06.926020273 +0100
c1595e42 35019@@ -0,0 +1,419 @@
7f207e10 35020+/*
2000de60 35021+ * Copyright (C) 2005-2015 Junjiro R. Okajima
7f207e10
AM
35022+ *
35023+ * This program, aufs is free software; you can redistribute it and/or modify
35024+ * it under the terms of the GNU General Public License as published by
35025+ * the Free Software Foundation; either version 2 of the License, or
35026+ * (at your option) any later version.
35027+ *
35028+ * This program is distributed in the hope that it will be useful,
35029+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35030+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35031+ * GNU General Public License for more details.
35032+ *
35033+ * You should have received a copy of the GNU General Public License
523b37e3 35034+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
35035+ */
35036+
35037+#ifndef __AUFS_TYPE_H__
35038+#define __AUFS_TYPE_H__
35039+
f6c5ef8b
AM
35040+#define AUFS_NAME "aufs"
35041+
9dbd164d 35042+#ifdef __KERNEL__
f6c5ef8b
AM
35043+/*
35044+ * define it before including all other headers.
35045+ * sched.h may use pr_* macros before defining "current", so define the
35046+ * no-current version first, and re-define later.
35047+ */
35048+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
35049+#include <linux/sched.h>
35050+#undef pr_fmt
a2a7ad62
AM
35051+#define pr_fmt(fmt) \
35052+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
35053+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
35054+#else
35055+#include <stdint.h>
35056+#include <sys/types.h>
f6c5ef8b 35057+#endif /* __KERNEL__ */
7f207e10 35058+
f6c5ef8b
AM
35059+#include <linux/limits.h>
35060+
79b8bda9 35061+#define AUFS_VERSION "4.3-20151109"
7f207e10
AM
35062+
35063+/* todo? move this to linux-2.6.19/include/magic.h */
35064+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
35065+
35066+/* ---------------------------------------------------------------------- */
35067+
35068+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 35069+typedef int8_t aufs_bindex_t;
7f207e10
AM
35070+#define AUFS_BRANCH_MAX 127
35071+#else
9dbd164d 35072+typedef int16_t aufs_bindex_t;
7f207e10
AM
35073+#ifdef CONFIG_AUFS_BRANCH_MAX_511
35074+#define AUFS_BRANCH_MAX 511
35075+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
35076+#define AUFS_BRANCH_MAX 1023
35077+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
35078+#define AUFS_BRANCH_MAX 32767
35079+#endif
35080+#endif
35081+
35082+#ifdef __KERNEL__
35083+#ifndef AUFS_BRANCH_MAX
35084+#error unknown CONFIG_AUFS_BRANCH_MAX value
35085+#endif
35086+#endif /* __KERNEL__ */
35087+
35088+/* ---------------------------------------------------------------------- */
35089+
7f207e10
AM
35090+#define AUFS_FSTYPE AUFS_NAME
35091+
35092+#define AUFS_ROOT_INO 2
35093+#define AUFS_FIRST_INO 11
35094+
35095+#define AUFS_WH_PFX ".wh."
35096+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
35097+#define AUFS_WH_TMP_LEN 4
86dc4139 35098+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
35099+#define AUFS_MAX_NAMELEN (NAME_MAX \
35100+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
35101+ - 1 /* dot */\
35102+ - AUFS_WH_TMP_LEN) /* hex */
35103+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
35104+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
35105+#define AUFS_XINO_DEF_SEC 30 /* seconds */
35106+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
35107+#define AUFS_DIRWH_DEF 3
35108+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 35109+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
35110+#define AUFS_RDBLK_DEF 512 /* bytes */
35111+#define AUFS_RDHASH_DEF 32
35112+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
35113+#define AUFS_MFS_DEF_SEC 30 /* seconds */
35114+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
076b876e 35115+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
86dc4139 35116+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
35117+
35118+/* pseudo-link maintenace under /proc */
35119+#define AUFS_PLINK_MAINT_NAME "plink_maint"
35120+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
35121+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
35122+
35123+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
35124+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
35125+
35126+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
35127+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
35128+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
35129+
35130+/* doubly whiteouted */
35131+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
35132+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
35133+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
35134+
1e00d052 35135+/* branch permissions and attributes */
7f207e10
AM
35136+#define AUFS_BRPERM_RW "rw"
35137+#define AUFS_BRPERM_RO "ro"
35138+#define AUFS_BRPERM_RR "rr"
076b876e
AM
35139+#define AUFS_BRATTR_COO_REG "coo_reg"
35140+#define AUFS_BRATTR_COO_ALL "coo_all"
35141+#define AUFS_BRATTR_FHSM "fhsm"
35142+#define AUFS_BRATTR_UNPIN "unpin"
c1595e42
JR
35143+#define AUFS_BRATTR_ICEX "icex"
35144+#define AUFS_BRATTR_ICEX_SEC "icexsec"
35145+#define AUFS_BRATTR_ICEX_SYS "icexsys"
35146+#define AUFS_BRATTR_ICEX_TR "icextr"
35147+#define AUFS_BRATTR_ICEX_USR "icexusr"
35148+#define AUFS_BRATTR_ICEX_OTH "icexoth"
1e00d052
AM
35149+#define AUFS_BRRATTR_WH "wh"
35150+#define AUFS_BRWATTR_NLWH "nolwh"
076b876e
AM
35151+#define AUFS_BRWATTR_MOO "moo"
35152+
35153+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
35154+#define AuBrPerm_RO (1 << 1) /* readonly */
35155+#define AuBrPerm_RR (1 << 2) /* natively readonly */
35156+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
35157+
35158+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
35159+#define AuBrAttr_COO_ALL (1 << 4)
35160+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
35161+
35162+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
35163+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
c1595e42
JR
35164+ branch. meaningless since
35165+ linux-3.18-rc1 */
35166+
35167+/* ignore error in copying XATTR */
35168+#define AuBrAttr_ICEX_SEC (1 << 7)
35169+#define AuBrAttr_ICEX_SYS (1 << 8)
35170+#define AuBrAttr_ICEX_TR (1 << 9)
35171+#define AuBrAttr_ICEX_USR (1 << 10)
35172+#define AuBrAttr_ICEX_OTH (1 << 11)
35173+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \
35174+ | AuBrAttr_ICEX_SYS \
35175+ | AuBrAttr_ICEX_TR \
35176+ | AuBrAttr_ICEX_USR \
35177+ | AuBrAttr_ICEX_OTH)
35178+
35179+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */
076b876e
AM
35180+#define AuBrRAttr_Mask AuBrRAttr_WH
35181+
c1595e42
JR
35182+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */
35183+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */
076b876e
AM
35184+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
35185+
35186+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
35187+
c1595e42 35188+/* #warning test userspace */
076b876e
AM
35189+#ifdef __KERNEL__
35190+#ifndef CONFIG_AUFS_FHSM
35191+#undef AuBrAttr_FHSM
35192+#define AuBrAttr_FHSM 0
35193+#endif
c1595e42
JR
35194+#ifndef CONFIG_AUFS_XATTR
35195+#undef AuBrAttr_ICEX
35196+#define AuBrAttr_ICEX 0
35197+#undef AuBrAttr_ICEX_SEC
35198+#define AuBrAttr_ICEX_SEC 0
35199+#undef AuBrAttr_ICEX_SYS
35200+#define AuBrAttr_ICEX_SYS 0
35201+#undef AuBrAttr_ICEX_TR
35202+#define AuBrAttr_ICEX_TR 0
35203+#undef AuBrAttr_ICEX_USR
35204+#define AuBrAttr_ICEX_USR 0
35205+#undef AuBrAttr_ICEX_OTH
35206+#define AuBrAttr_ICEX_OTH 0
35207+#endif
076b876e
AM
35208+#endif
35209+
35210+/* the longest combination */
c1595e42
JR
35211+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
35212+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
35213+ "+" AUFS_BRATTR_COO_REG \
35214+ "+" AUFS_BRATTR_FHSM \
35215+ "+" AUFS_BRATTR_UNPIN \
7e9cd9fe
AM
35216+ "+" AUFS_BRATTR_ICEX_SEC \
35217+ "+" AUFS_BRATTR_ICEX_SYS \
35218+ "+" AUFS_BRATTR_ICEX_USR \
35219+ "+" AUFS_BRATTR_ICEX_OTH \
076b876e
AM
35220+ "+" AUFS_BRWATTR_NLWH)
35221+
35222+typedef struct {
35223+ char a[AuBrPermStrSz];
35224+} au_br_perm_str_t;
35225+
35226+static inline int au_br_writable(int brperm)
35227+{
35228+ return brperm & AuBrPerm_RW;
35229+}
35230+
35231+static inline int au_br_whable(int brperm)
35232+{
35233+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
35234+}
35235+
35236+static inline int au_br_wh_linkable(int brperm)
35237+{
35238+ return !(brperm & AuBrWAttr_NoLinkWH);
35239+}
35240+
35241+static inline int au_br_cmoo(int brperm)
35242+{
35243+ return brperm & AuBrAttr_CMOO_Mask;
35244+}
35245+
35246+static inline int au_br_fhsm(int brperm)
35247+{
35248+ return brperm & AuBrAttr_FHSM;
35249+}
7f207e10
AM
35250+
35251+/* ---------------------------------------------------------------------- */
35252+
35253+/* ioctl */
35254+enum {
35255+ /* readdir in userspace */
35256+ AuCtl_RDU,
35257+ AuCtl_RDU_INO,
35258+
076b876e
AM
35259+ AuCtl_WBR_FD, /* pathconf wrapper */
35260+ AuCtl_IBUSY, /* busy inode */
35261+ AuCtl_MVDOWN, /* move-down */
35262+ AuCtl_BR, /* info about branches */
35263+ AuCtl_FHSM_FD /* connection for fhsm */
7f207e10
AM
35264+};
35265+
35266+/* borrowed from linux/include/linux/kernel.h */
35267+#ifndef ALIGN
35268+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
35269+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
35270+#endif
35271+
35272+/* borrowed from linux/include/linux/compiler-gcc3.h */
35273+#ifndef __aligned
35274+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
35275+#endif
35276+
35277+#ifdef __KERNEL__
35278+#ifndef __packed
7f207e10
AM
35279+#define __packed __attribute__((packed))
35280+#endif
53392da6 35281+#endif
7f207e10
AM
35282+
35283+struct au_rdu_cookie {
9dbd164d
AM
35284+ uint64_t h_pos;
35285+ int16_t bindex;
35286+ uint8_t flags;
35287+ uint8_t pad;
35288+ uint32_t generation;
7f207e10
AM
35289+} __aligned(8);
35290+
35291+struct au_rdu_ent {
9dbd164d
AM
35292+ uint64_t ino;
35293+ int16_t bindex;
35294+ uint8_t type;
35295+ uint8_t nlen;
35296+ uint8_t wh;
7f207e10
AM
35297+ char name[0];
35298+} __aligned(8);
35299+
35300+static inline int au_rdu_len(int nlen)
35301+{
35302+ /* include the terminating NULL */
35303+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 35304+ sizeof(uint64_t));
7f207e10
AM
35305+}
35306+
35307+union au_rdu_ent_ul {
35308+ struct au_rdu_ent __user *e;
9dbd164d 35309+ uint64_t ul;
7f207e10
AM
35310+};
35311+
35312+enum {
35313+ AufsCtlRduV_SZ,
35314+ AufsCtlRduV_End
35315+};
35316+
35317+struct aufs_rdu {
35318+ /* input */
35319+ union {
9dbd164d
AM
35320+ uint64_t sz; /* AuCtl_RDU */
35321+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
35322+ };
35323+ union au_rdu_ent_ul ent;
9dbd164d 35324+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
35325+
35326+ /* input/output */
9dbd164d 35327+ uint32_t blk;
7f207e10
AM
35328+
35329+ /* output */
35330+ union au_rdu_ent_ul tail;
35331+ /* number of entries which were added in a single call */
9dbd164d
AM
35332+ uint64_t rent;
35333+ uint8_t full;
35334+ uint8_t shwh;
7f207e10
AM
35335+
35336+ struct au_rdu_cookie cookie;
35337+} __aligned(8);
35338+
1e00d052
AM
35339+/* ---------------------------------------------------------------------- */
35340+
35341+struct aufs_wbr_fd {
9dbd164d
AM
35342+ uint32_t oflags;
35343+ int16_t brid;
1e00d052
AM
35344+} __aligned(8);
35345+
35346+/* ---------------------------------------------------------------------- */
35347+
027c5e7a 35348+struct aufs_ibusy {
9dbd164d
AM
35349+ uint64_t ino, h_ino;
35350+ int16_t bindex;
027c5e7a
AM
35351+} __aligned(8);
35352+
1e00d052
AM
35353+/* ---------------------------------------------------------------------- */
35354+
392086de
AM
35355+/* error code for move-down */
35356+/* the actual message strings are implemented in aufs-util.git */
35357+enum {
35358+ EAU_MVDOWN_OPAQUE = 1,
35359+ EAU_MVDOWN_WHITEOUT,
35360+ EAU_MVDOWN_UPPER,
35361+ EAU_MVDOWN_BOTTOM,
35362+ EAU_MVDOWN_NOUPPER,
35363+ EAU_MVDOWN_NOLOWERBR,
35364+ EAU_Last
35365+};
35366+
c2b27bf2 35367+/* flags for move-down */
392086de
AM
35368+#define AUFS_MVDOWN_DMSG 1
35369+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
35370+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
35371+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
35372+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
35373+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
35374+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
35375+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
35376+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
076b876e
AM
35377+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
35378+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
35379+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
35380+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
c2b27bf2 35381+
076b876e 35382+/* index for move-down */
392086de
AM
35383+enum {
35384+ AUFS_MVDOWN_UPPER,
35385+ AUFS_MVDOWN_LOWER,
35386+ AUFS_MVDOWN_NARRAY
35387+};
35388+
076b876e
AM
35389+/*
35390+ * additional info of move-down
35391+ * number of free blocks and inodes.
35392+ * subset of struct kstatfs, but smaller and always 64bit.
35393+ */
35394+struct aufs_stfs {
35395+ uint64_t f_blocks;
35396+ uint64_t f_bavail;
35397+ uint64_t f_files;
35398+ uint64_t f_ffree;
35399+};
35400+
35401+struct aufs_stbr {
35402+ int16_t brid; /* optional input */
35403+ int16_t bindex; /* output */
35404+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
35405+} __aligned(8);
35406+
c2b27bf2 35407+struct aufs_mvdown {
076b876e
AM
35408+ uint32_t flags; /* input/output */
35409+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
35410+ int8_t au_errno; /* output */
35411+} __aligned(8);
35412+
35413+/* ---------------------------------------------------------------------- */
35414+
35415+union aufs_brinfo {
35416+ /* PATH_MAX may differ between kernel-space and user-space */
35417+ char _spacer[4096];
392086de 35418+ struct {
076b876e
AM
35419+ int16_t id;
35420+ int perm;
35421+ char path[0];
35422+ };
c2b27bf2
AM
35423+} __aligned(8);
35424+
35425+/* ---------------------------------------------------------------------- */
35426+
7f207e10
AM
35427+#define AuCtlType 'A'
35428+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
35429+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
35430+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
35431+ struct aufs_wbr_fd)
027c5e7a 35432+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
35433+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
35434+ struct aufs_mvdown)
076b876e
AM
35435+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
35436+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
7f207e10
AM
35437+
35438+#endif /* __AUFS_TYPE_H__ */
79b8bda9 35439aufs4.3 loopback patch
5527c038
JR
35440
35441diff --git a/drivers/block/loop.c b/drivers/block/loop.c
79b8bda9 35442index 291ec9e..1b8190d 100644
5527c038
JR
35443--- a/drivers/block/loop.c
35444+++ b/drivers/block/loop.c
c2c0f25c 35445@@ -417,7 +417,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
5527c038
JR
35446 }
35447
35448 struct switch_request {
35449- struct file *file;
35450+ struct file *file, *virt_file;
35451 struct completion wait;
35452 };
35453
c2c0f25c 35454@@ -437,6 +437,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
5527c038
JR
35455 mapping = file->f_mapping;
35456 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
35457 lo->lo_backing_file = file;
35458+ lo->lo_backing_virt_file = p->virt_file;
35459 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
35460 mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
35461 lo->old_gfp_mask = mapping_gfp_mask(mapping);
c2c0f25c 35462@@ -448,11 +449,13 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
5527c038
JR
35463 * First it needs to flush existing IO, it does this by sending a magic
35464 * BIO down the pipe. The completion of this BIO does the actual switch.
35465 */
35466-static int loop_switch(struct loop_device *lo, struct file *file)
35467+static int loop_switch(struct loop_device *lo, struct file *file,
35468+ struct file *virt_file)
35469 {
35470 struct switch_request w;
35471
35472 w.file = file;
35473+ w.virt_file = virt_file;
35474
35475 /* freeze queue and wait for completion of scheduled requests */
35476 blk_mq_freeze_queue(lo->lo_queue);
c2c0f25c 35477@@ -471,7 +474,16 @@ static int loop_switch(struct loop_device *lo, struct file *file)
5527c038
JR
35478 */
35479 static int loop_flush(struct loop_device *lo)
35480 {
35481- return loop_switch(lo, NULL);
35482+ return loop_switch(lo, NULL, NULL);
35483+}
35484+
35485+static struct file *loop_real_file(struct file *file)
35486+{
35487+ struct file *f = NULL;
35488+
35489+ if (file->f_path.dentry->d_sb->s_op->real_loop)
35490+ f = file->f_path.dentry->d_sb->s_op->real_loop(file);
35491+ return f;
35492 }
35493
c2c0f25c
AM
35494 static void loop_reread_partitions(struct loop_device *lo,
35495@@ -508,6 +520,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
35496 unsigned int arg)
35497 {
35498 struct file *file, *old_file;
35499+ struct file *f, *virt_file = NULL, *old_virt_file;
35500 struct inode *inode;
35501 int error;
35502
c2c0f25c 35503@@ -524,9 +537,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
35504 file = fget(arg);
35505 if (!file)
35506 goto out;
35507+ f = loop_real_file(file);
35508+ if (f) {
35509+ virt_file = file;
35510+ file = f;
35511+ get_file(file);
35512+ }
35513
35514 inode = file->f_mapping->host;
35515 old_file = lo->lo_backing_file;
35516+ old_virt_file = lo->lo_backing_virt_file;
35517
35518 error = -EINVAL;
35519
c2c0f25c 35520@@ -538,17 +558,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
5527c038
JR
35521 goto out_putf;
35522
35523 /* and ... switch */
35524- error = loop_switch(lo, file);
35525+ error = loop_switch(lo, file, virt_file);
35526 if (error)
35527 goto out_putf;
35528
35529 fput(old_file);
35530+ if (old_virt_file)
35531+ fput(old_virt_file);
35532 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
c2c0f25c 35533 loop_reread_partitions(lo, bdev);
5527c038
JR
35534 return 0;
35535
35536 out_putf:
35537 fput(file);
35538+ if (virt_file)
35539+ fput(virt_file);
35540 out:
35541 return error;
35542 }
c2c0f25c 35543@@ -709,7 +733,7 @@ static void loop_config_discard(struct loop_device *lo)
5527c038
JR
35544 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
35545 struct block_device *bdev, unsigned int arg)
35546 {
35547- struct file *file, *f;
35548+ struct file *file, *f, *virt_file = NULL;
35549 struct inode *inode;
35550 struct address_space *mapping;
35551 unsigned lo_blocksize;
c2c0f25c 35552@@ -724,6 +748,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
35553 file = fget(arg);
35554 if (!file)
35555 goto out;
35556+ f = loop_real_file(file);
35557+ if (f) {
35558+ virt_file = file;
35559+ file = f;
35560+ get_file(file);
35561+ }
35562
35563 error = -EBUSY;
35564 if (lo->lo_state != Lo_unbound)
c2c0f25c 35565@@ -778,6 +808,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
35566 lo->lo_device = bdev;
35567 lo->lo_flags = lo_flags;
35568 lo->lo_backing_file = file;
35569+ lo->lo_backing_virt_file = virt_file;
35570 lo->transfer = NULL;
35571 lo->ioctl = NULL;
35572 lo->lo_sizelimit = 0;
c2c0f25c 35573@@ -809,6 +840,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
5527c038
JR
35574
35575 out_putf:
35576 fput(file);
35577+ if (virt_file)
35578+ fput(virt_file);
35579 out:
35580 /* This is safe: open() is still holding a reference. */
35581 module_put(THIS_MODULE);
c2c0f25c 35582@@ -855,6 +888,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
5527c038
JR
35583 static int loop_clr_fd(struct loop_device *lo)
35584 {
35585 struct file *filp = lo->lo_backing_file;
35586+ struct file *virt_filp = lo->lo_backing_virt_file;
35587 gfp_t gfp = lo->old_gfp_mask;
35588 struct block_device *bdev = lo->lo_device;
35589
c2c0f25c 35590@@ -886,6 +920,7 @@ static int loop_clr_fd(struct loop_device *lo)
5527c038
JR
35591 spin_lock_irq(&lo->lo_lock);
35592 lo->lo_state = Lo_rundown;
35593 lo->lo_backing_file = NULL;
35594+ lo->lo_backing_virt_file = NULL;
35595 spin_unlock_irq(&lo->lo_lock);
35596
35597 loop_release_xfer(lo);
c2c0f25c 35598@@ -931,6 +966,8 @@ static int loop_clr_fd(struct loop_device *lo)
5527c038
JR
35599 * bd_mutex which is usually taken before lo_ctl_mutex.
35600 */
35601 fput(filp);
35602+ if (virt_filp)
35603+ fput(virt_filp);
35604 return 0;
35605 }
35606
35607diff --git a/drivers/block/loop.h b/drivers/block/loop.h
c2c0f25c 35608index 25e8997..93b6fce 100644
5527c038
JR
35609--- a/drivers/block/loop.h
35610+++ b/drivers/block/loop.h
35611@@ -46,7 +46,7 @@ struct loop_device {
35612 int (*ioctl)(struct loop_device *, int cmd,
35613 unsigned long arg);
35614
35615- struct file * lo_backing_file;
35616+ struct file * lo_backing_file, *lo_backing_virt_file;
35617 struct block_device *lo_device;
35618 unsigned lo_blocksize;
35619 void *key_data;
35620diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
35621index 91c2ce7..d4ee5a7 100644
35622--- a/fs/aufs/f_op.c
35623+++ b/fs/aufs/f_op.c
35624@@ -389,7 +389,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
35625 if (IS_ERR(h_file))
35626 goto out;
35627
35628- if (au_test_loopback_kthread()) {
35629+ if (0 && au_test_loopback_kthread()) {
35630 au_warn_loopback(h_file->f_path.dentry->d_sb);
35631 if (file->f_mapping != h_file->f_mapping) {
35632 file->f_mapping = h_file->f_mapping;
35633diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
79b8bda9 35634index f324758..4555e7b 100644
5527c038
JR
35635--- a/fs/aufs/loop.c
35636+++ b/fs/aufs/loop.c
79b8bda9
AM
35637@@ -131,3 +131,19 @@ void au_loopback_fin(void)
35638 symbol_put(loop_backing_file);
5527c038
JR
35639 kfree(au_warn_loopback_array);
35640 }
35641+
35642+/* ---------------------------------------------------------------------- */
35643+
35644+/* support the loopback block device insude aufs */
35645+
35646+struct file *aufs_real_loop(struct file *file)
35647+{
35648+ struct file *f;
35649+
35650+ BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
35651+ fi_read_lock(file);
35652+ f = au_hf_top(file);
35653+ fi_read_unlock(file);
35654+ AuDebugOn(!f);
35655+ return f;
35656+}
35657diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
35658index 6d9864d..3322557 100644
35659--- a/fs/aufs/loop.h
35660+++ b/fs/aufs/loop.h
35661@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
35662
35663 int au_loopback_init(void);
35664 void au_loopback_fin(void);
35665+
35666+struct file *aufs_real_loop(struct file *file);
35667 #else
35668+AuStub(struct file *, loop_backing_file, return NULL)
35669+
35670 AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
35671 struct dentry *h_adding)
35672 AuStubInt0(au_test_loopback_kthread, void)
35673@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
35674
35675 AuStubInt0(au_loopback_init, void)
35676 AuStubVoid(au_loopback_fin, void)
35677+
35678+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
35679 #endif /* BLK_DEV_LOOP */
35680
35681 #endif /* __KERNEL__ */
35682diff --git a/fs/aufs/super.c b/fs/aufs/super.c
79b8bda9 35683index 1b25343..3b0c6c5 100644
5527c038
JR
35684--- a/fs/aufs/super.c
35685+++ b/fs/aufs/super.c
79b8bda9 35686@@ -831,7 +831,10 @@ static const struct super_operations aufs_sop = {
5527c038
JR
35687 .statfs = aufs_statfs,
35688 .put_super = aufs_put_super,
35689 .sync_fs = aufs_sync_fs,
35690- .remount_fs = aufs_remount_fs
35691+ .remount_fs = aufs_remount_fs,
35692+#ifdef CONFIG_AUFS_BDEV_LOOP
35693+ .real_loop = aufs_real_loop
35694+#endif
35695 };
35696
35697 /* ---------------------------------------------------------------------- */
35698diff --git a/include/linux/fs.h b/include/linux/fs.h
79b8bda9 35699index fabd9d7a..90174cf 100644
5527c038
JR
35700--- a/include/linux/fs.h
35701+++ b/include/linux/fs.h
79b8bda9 35702@@ -1734,6 +1734,10 @@ struct super_operations {
5527c038
JR
35703 struct shrink_control *);
35704 long (*free_cached_objects)(struct super_block *,
35705 struct shrink_control *);
35706+#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
35707+ /* and aufs */
35708+ struct file *(*real_loop)(struct file *);
35709+#endif
35710 };
35711
35712 /*
This page took 5.578191 seconds and 4 git commands to generate.